port 2V2-d.1: ActorInstance/InstanceBase closure creates the main character

Port the ActorInstance*/InstanceBase* siblings plus GameUtil, FlyTarget,
PhysicsObject, GameEventManager, WeaponTrace, MapUtil and lineintersect_utils
verbatim and drop their pending stand-ins; CGameEventManager and CPythonSystem
join PythonBoot in CPythonApplication member order.

Root cause of the intermittent Loading-phase header 7: TPlayerSkill::tNextRead
is time_t, 32-bit in 40250 (_USE_32BIT_TIME_T) but 64-bit on LP64, so
SKILL_LEVEL (76) was read as 2551 bytes instead of 1531. Packet.h now uses
LONG with a static_assert, and the fake server sends SKILL_LEVEL in Loading.

The fake server's CHARACTER_ADD now uses CHAR_TYPE_PC; port.login_flow
asserts the main instance exists with race 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-23 19:02:21 +09:00
co-authored by Claude Opus 5.5
parent 996d793f0c
commit 5266b00c6e
71 changed files with 13832 additions and 1405 deletions
@@ -12,6 +12,7 @@
#include "UserInterface/PythonPlayer.h"
#include "GameLib/FlyingObjectManager.h"
#include "GameLib/RaceManager.h"
#include "GameLib/GameEventManager.h"
#include "EffectLib/EffectManager.h"
#include "GameLib/ItemManager.h"
#include "UserInterface/PythonCharacterManager.h"
@@ -28,6 +29,7 @@
#include "UserInterface/PythonMessenger.h"
#include "UserInterface/PythonSafeBox.h"
#include "UserInterface/PythonGuild.h"
#include "UserInterface/PythonSystem.h"
#include "UserInterface/AbstractApplication.h"
#include "UserInterface/PythonApplication.h"
#include "EterBase/Timer.h"
@@ -59,6 +61,7 @@ std::unique_ptr<CAccountConnector> g_account_connector;
std::unique_ptr<CPythonPlayer> g_player;
std::unique_ptr<CFlyingManager> g_flying_manager;
std::unique_ptr<CRaceManager> g_race_manager;
std::unique_ptr<CGameEventManager> g_game_event_manager;
std::unique_ptr<CEffectManager> g_effect_manager;
// PORT: CPythonApplication is not constructed by the Godot host yet. GamePhase calls the
// 40250 IAbstractApplication singleton, so expose the host's current timer and camera surface.
@@ -113,6 +116,7 @@ struct GameSingletons
CPythonMessenger pyManager;
CPythonSafeBox pySafeBox;
CPythonGuild pyGuild;
CPythonSystem pySystem; // last CPythonApplication member (m_pySystem)
};
std::unique_ptr<GameSingletons> g_game_singletons;
@@ -301,6 +305,7 @@ bool Start(const char* stdlib_path, std::string* error)
g_player = std::make_unique<CPythonPlayer>();
g_flying_manager = std::make_unique<CFlyingManager>();
g_race_manager = std::make_unique<CRaceManager>();
g_game_event_manager = std::make_unique<CGameEventManager>();
g_effect_manager = std::make_unique<CEffectManager>();
g_game_application = std::make_unique<GameApplicationAdapter>();
g_game_singletons = std::make_unique<GameSingletons>();
@@ -496,6 +501,7 @@ void Stop()
g_game_singletons.reset();
g_game_application.reset();
g_effect_manager.reset();
g_game_event_manager.reset();
g_race_manager.reset();
g_flying_manager.reset();
g_player.reset();
@@ -164,12 +164,8 @@ void CPythonApplication::SetForceSightRange(int) { MT_PLATFORM_STUB(); }
void CMovieMan::PlayLogo(const char*) { MT_PLATFORM_STUB(); }
float GetDegreeDifference(float, float) { MT_PLATFORM_STUB(); return 0; }
int GetRotatingDirection(float, float) { MT_PLATFORM_STUB(); return 0; }
BOOL PERF_CHECKER_RENDER_GAME = FALSE;
BOOL SKILL_EFFECT_UPGRADE_ENABLE = FALSE;
BOOL USE_WEAPON_SPECULAR = FALSE;
D3DXCOLOR g_fSpecularColor;
double g_specularSpd = 0;
@@ -1,559 +0,0 @@
// Stand-in for the 40250 logic unit GameLib/ActorInstance.cpp, not ported yet: the members the ported units
// reference, as platform_stub.py stubs. Delete this file in the commit that ports the unit into port/
// (docs/PORT-PLAN.md).
#include "GameLib/StdAfx.h"
#include "GameLib/ActorInstance.h"
#include "../../PlatformStub.h"
auto CActorInstance::IEventHandler::GetEmptyPtr() -> IEventHandler *
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<IEventHandler *>();
}
auto CActorInstance::IsDirLine() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::SetMaterialColor(DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::SetEventHandler(IEventHandler *) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::CanAct() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::CanMove() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::CanAttack() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::CanUseSkill() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::AttachWeapon(DWORD, DWORD, DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::RefreshActorInstance() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::UpdateAttachingInstances() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::SetMotionMode(int) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::GetMotionMode() -> int
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<int>();
}
auto CActorInstance::SetLoopMotion(DWORD, float, float) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::InterceptOnceMotion(DWORD, float, UINT, float) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::InterceptLoopMotion(DWORD, float) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::IsPushing() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::IsUsingSkill() -> BOOL
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
}
auto CActorInstance::CanCancelSkill() -> BOOL
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
}
auto CActorInstance::UpdatePointInstance() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::TestCollisionWithDynamicSphere(const CDynamicSphereInstance &) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::UpdateAdvancingPointInstance() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::AvoidObject(const CGraphicObjectInstance &) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::IsBlockObject(const CGraphicObjectInstance &) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::BlockMovement() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::TestPhysicsBlendingCollision(CActorInstance &) -> BOOL
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
}
auto CActorInstance::isAttacking() -> BOOL
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
}
auto CActorInstance::IsUsingMovingSkill() -> BOOL
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
}
auto CActorInstance::IsActEmotion() -> BOOL
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
}
auto CActorInstance::SetBlendingPosition(const TPixelPosition &, float) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::SetBattleHitEffect(DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::GetMovementVectorRef() -> const D3DXVECTOR3 &
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<const D3DXVECTOR3 &>();
}
auto CActorInstance::SetCurPixelPosition(const TPixelPosition &) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::NEW_SetSrcPixelPosition(const TPixelPosition &) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::NEW_SetDstPixelPosition(const TPixelPosition &) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::NEW_SetDstPixelPositionZ(float) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::NEW_GetCurPixelPositionRef() -> const TPixelPosition &
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<const TPixelPosition &>();
}
auto CActorInstance::NEW_GetSrcPixelPositionRef() -> const TPixelPosition &
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<const TPixelPosition &>();
}
auto CActorInstance::NEW_GetDstPixelPositionRef() -> const TPixelPosition &
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<const TPixelPosition &>();
}
auto CActorInstance::NEW_GetLastPixelPositionRef() -> const TPixelPosition &
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<const TPixelPosition &>();
}
auto CActorInstance::GetPixelPosition(TPixelPosition *) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::GetRotation() -> float
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<float>();
}
auto CActorInstance::GetTargetRotation() -> float
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<float>();
}
auto CActorInstance::GetAdvancingRotation() -> float
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<float>();
}
auto CActorInstance::SetRotation(float) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::SetAdvancingRotation(float) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::RestoreRenderMode() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::SetBlendRenderMode() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::SetAlphaValue(float) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::GetAlphaValue() -> float
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<float>();
}
auto CActorInstance::BlendAlphaValue(float, float) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::SetAddRenderMode() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::SetAddColor(const D3DXCOLOR &) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::SetModulateRenderMode() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::SetRenderMode(int) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::RenderTrace() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::RenderCollisionData() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::RenderToShadowMap() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::CanFishing() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::IsFishing() -> BOOL
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
}
auto CActorInstance::OnGetFlyTargetPosition() -> D3DXVECTOR3
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<D3DXVECTOR3>();
}
auto CActorInstance::OnShootDamage() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::AddFlyTarget(const CFlyTarget &) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::SetFlyTarget(const CFlyTarget &) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::CanChangeTarget() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::HORSE_MotionProcess(BOOL) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::MotionProcess(BOOL) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::RotationProcess() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::ComboProcess() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::ShakeProcess() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::TraceProcess() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::OnRender() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::__ClearAttachingEffect() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::__ClearCombo() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::__ClearMotion() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::__IsWaitMotion() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::__IsMoveMotion() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::__IsDamageMotion() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::__IsKnockDownMotion() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::__IsDieMotion() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::__GetCurrentMotionIndex() -> WORD
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<WORD>();
}
auto CActorInstance::__DestroyWeaponTrace() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::__InitializePositionData() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::__OnSyncing() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::__OnWaiting() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::__OnMoving() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::EnableSkipCollision() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::DisableSkipCollision() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::__InitializeCollisionData() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::__BlendAlpha_Initialize() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::__BlendAlpha_Update() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::__IsSyncing() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::__OnStop() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::TEMP_Push(int, int) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::ShowDirectionLine(bool) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::AttachEffectByName(DWORD, const char *, const char *) -> DWORD
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<DWORD>();
}
auto CActorInstance::PushOnceMotion(DWORD, float, float) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::PushLoopMotion(DWORD, float, float) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CActorInstance::SetXYRotation(float, float) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::SetWeaponTraceTexture(const char *) -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::UseTextureWeaponTrace() -> void
{
MT_PLATFORM_STUB();
}
auto CActorInstance::UseAlphaWeaponTrace() -> void
{
MT_PLATFORM_STUB();
}
@@ -1,32 +0,0 @@
// Stand-in for the 40250 logic unit GameLib/FlyTarget.cpp, not ported yet: the members the ported units
// reference, as platform_stub.py stubs. Delete this file in the commit that ports the unit into port/
// (docs/PORT-PLAN.md).
#include "GameLib/StdAfx.h"
#include "GameLib/FlyTarget.h"
#include "../../PlatformStub.h"
CFlyTarget::CFlyTarget(IFlyTargetableObject *)
{
MT_PLATFORM_STUB();
}
CFlyTarget::CFlyTarget(const D3DXVECTOR3 &)
{
MT_PLATFORM_STUB();
}
CFlyTarget::~CFlyTarget()
{
MT_PLATFORM_STUB();
}
CFlyTarget::CFlyTarget()
{
MT_PLATFORM_STUB();
}
auto CFlyTarget::NotifyTargetClear() -> void
{
MT_PLATFORM_STUB();
}
@@ -59,3 +59,39 @@ auto CItemData::GetSpecularPowerf() const -> float
MT_PLATFORM_STUB();
return mt_platform_stub_return<float>();
}
auto CItemData::GetModelThing() -> CGraphicThing *
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<CGraphicThing *>();
}
auto CItemData::GetSubModelThing() -> CGraphicThing *
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<CGraphicThing *>();
}
auto CItemData::GetLODModelThingCount() -> DWORD
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<DWORD>();
}
auto CItemData::GetLODModelThingPointer(DWORD, CGraphicThing **) -> BOOL
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
}
auto CItemData::GetAttachingDataCount() -> DWORD
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<DWORD>();
}
auto CItemData::GetAttachingDataPointer(DWORD, const NRaceData::TAttachingData **) -> BOOL
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
}
@@ -1,7 +0,0 @@
// Pending MapUtil.cpp dependency of the physics object. The interpolation unit remains 2V3 work.
#include "GameLib/StdAfx.h"
#include "GameLib/MapUtil.h"
#include "../../PlatformStub.h"
CEaseOutInterpolation::CEaseOutInterpolation() { MT_PLATFORM_STUB(); }
CEaseOutInterpolation::~CEaseOutInterpolation() { MT_PLATFORM_STUB(); }
@@ -1,43 +0,0 @@
// Stand-in for the 40250 logic unit GameLib/PhysicsObject.cpp, not ported yet: the members the ported units
// reference, as platform_stub.py stubs. Delete this file in the commit that ports the unit into port/
// (docs/PORT-PLAN.md).
#include "GameLib/StdAfx.h"
#include "GameLib/PhysicsObject.h"
#include "../../PlatformStub.h"
decltype(IObjectManager::ms_ObjManager) IObjectManager::ms_ObjManager{};
decltype(IPhysicsWorld::ms_pWorld) IPhysicsWorld::ms_pWorld{};
CPhysicsObject::CPhysicsObject()
{
MT_PLATFORM_STUB();
}
CPhysicsObject::~CPhysicsObject()
{
MT_PLATFORM_STUB();
}
auto CPhysicsObject::Initialize() -> void
{
MT_PLATFORM_STUB();
}
auto CPhysicsObject::Update(float) -> void
{
MT_PLATFORM_STUB();
}
auto CPhysicsObject::GetXMovement() -> float
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<float>();
}
auto CPhysicsObject::GetYMovement() -> float
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<float>();
}
@@ -1,467 +0,0 @@
// Stand-in for the 40250 logic unit UserInterface/InstanceBase.cpp, not ported yet: the members the ported units
// reference, as platform_stub.py stubs. Delete this file in the commit that ports the unit into port/
// (docs/PORT-PLAN.md).
#include "UserInterface/StdAfx.h"
#include "UserInterface/InstanceBase.h"
#include "../../PlatformStub.h"
auto CInstanceBase::RegisterEffect(UINT, const char *, const char *, bool) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CInstanceBase::__AttachEffect(UINT) -> DWORD
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<DWORD>();
}
auto CInstanceBase::__DetachEffect(DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::CreateSpecialEffect(DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::AttachSpecialEffect(DWORD) -> void
{
MT_PLATFORM_STUB();
}
decltype(CInstanceBase::ms_adwCRCAffectEffect) CInstanceBase::ms_adwCRCAffectEffect{};
decltype(CInstanceBase::ms_fDustGap) CInstanceBase::ms_fDustGap{};
decltype(CInstanceBase::ms_fHorseDustGap) CInstanceBase::ms_fHorseDustGap{};
auto CInstanceBase::DeleteBlendOut() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::AttachTextTail() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::DetachTextTail() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::UpdateTextTailLevel(DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::RefreshTextTail() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::RefreshTextTailTitle() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::UpdateDeleting() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CInstanceBase::ActDualEmotion(CInstanceBase &, WORD, WORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::ActEmotion(DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::LevelUp() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::SkillUp() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::Stun() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::Die() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::IsPVPInstance(CInstanceBase &) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CInstanceBase::IsAffect(UINT) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CInstanceBase::SetEventHandler(CActorInstance::IEventHandler *) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::NEW_UseSkill(UINT, UINT, UINT, bool) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CInstanceBase::NEW_GetDistanceFromDestPixelPosition(const TPixelPosition &) -> float
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<float>();
}
auto CInstanceBase::NEW_GetDistanceFromDestInstance(CInstanceBase &) -> float
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<float>();
}
auto CInstanceBase::NEW_SetPixelPosition(const TPixelPosition &) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::RunNormalAttack(float) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::RunComboAttack(float, DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::CheckAdvancing() -> BOOL
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
}
auto CInstanceBase::StartFishing(float) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::StopFishing() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::ReactFishing() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::CatchSuccess() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::CatchFail() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::SCRIPT_SetPixelPosition(float, float) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::NEW_GetPixelPosition(TPixelPosition *) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::NEW_LookAtDestInstance(CInstanceBase &) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::GetRotation() -> float
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<float>();
}
auto CInstanceBase::GetAdvancingRotation() -> float
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<float>();
}
auto CInstanceBase::SetRotation(float) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::BlendRotation(float, float) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::SetMotionMode(int) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::PushOnceMotion(WORD, float, float) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__ClearAffects() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::SetAffectFlagContainer(const CAffectFlagContainer &) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::SetEmoticon(UINT) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::SetFishEmoticon() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__EnableChangingTCPState() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__ComboProcess() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::AttackProcess() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__AttachSelectEffect() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__DetachSelectEffect() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__AttachTargetEffect() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__DetachTargetEffect() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__AttachEmpireEffect(DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__EffectContainer_Initialize() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__EffectContainer_Destroy() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__StoneSmoke_Inialize() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__StoneSmoke_Destroy() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::ProcessDamage() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::AddDamageEffect(DWORD, BYTE, BOOL, BOOL) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::ClearPVPKeySystem() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::InsertPVPKey(DWORD, DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::RemovePVPKey(DWORD, DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::InsertGVGKey(DWORD, DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::RemoveGVGKey(DWORD, DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::InsertDUELKey(DWORD, DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::__FindDUELKey(DWORD, DWORD) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CInstanceBase::GetEventHandlerRef() -> CActorInstance::IEventHandler &
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<CActorInstance::IEventHandler &>();
}
auto CInstanceBase::IsUsingSkill() -> BOOL
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
}
auto CInstanceBase::isLock() -> BOOL
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
}
auto CInstanceBase::__EffectContainer_AttachEffect(DWORD) -> DWORD
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<DWORD>();
}
auto CInstanceBase::__EffectContainer_DetachEffect(DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::RegisterTitleName(int, const char *) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::RegisterNameColor(UINT, UINT, UINT, UINT) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CInstanceBase::RegisterTitleColor(UINT, UINT, UINT, UINT) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CInstanceBase::SetDustGap(float) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::SetHorseDustGap(float) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::SetEmpireNameMode(bool) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::SCRIPT_SetAffect(UINT, bool) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::SetAlpha(float) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::Revive() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::Hide() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::Show() -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::SetDirection(int) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::SetLoopMotion(WORD, float, float) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::PushLoopMotion(WORD, float, float) -> void
{
MT_PLATFORM_STUB();
}
auto CInstanceBase::IsPossibleEmoticon() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
@@ -0,0 +1,23 @@
// Stand-in for the 40250 logic unit UserInterface/PythonSystem.cpp, not ported yet: the members the ported units
// reference, as platform_stub.py stubs. Delete this file in the commit that ports the unit into port/
// (docs/PORT-PLAN.md).
#include "UserInterface/StdAfx.h"
#include "UserInterface/PythonSystem.h"
#include "../../PlatformStub.h"
CPythonSystem::CPythonSystem()
{
MT_PLATFORM_STUB();
}
CPythonSystem::~CPythonSystem()
{
MT_PLATFORM_STUB();
}
auto CPythonSystem::IsShowDamage() -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
@@ -20,3 +20,33 @@ auto CPythonTextTail::RegisterChatTail(DWORD, const char *) -> void
{
MT_PLATFORM_STUB();
}
auto CPythonTextTail::RegisterCharacterTextTail(DWORD, DWORD, const D3DXCOLOR &, float) -> void
{
MT_PLATFORM_STUB();
}
auto CPythonTextTail::SetCharacterTextTailColor(DWORD, const D3DXCOLOR &) -> void
{
MT_PLATFORM_STUB();
}
auto CPythonTextTail::DeleteCharacterTextTail(DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CPythonTextTail::AttachTitle(DWORD, const char *, const D3DXCOLOR &) -> void
{
MT_PLATFORM_STUB();
}
auto CPythonTextTail::DetachTitle(DWORD) -> void
{
MT_PLATFORM_STUB();
}
auto CPythonTextTail::AttachLevel(DWORD, const char *, const D3DXCOLOR &) -> void
{
MT_PLATFORM_STUB();
}
@@ -0,0 +1,849 @@
/**************************************************************************************
| File: lineintersect_utils.cpp
| Purpose: Implementation of line segment intersection utility functions
| Book Title: Game Programming Gems II
| Chapter Title: Fast, Robust Intersection of 3D Line Segments
| Author: Graham Rhodes
| Revisions: 05-Apr-2001 - GSR. Original.
**************************************************************************************/
#include "StdAfx.h"
#include <math.h>
#include "lineintersect_utils.h"
#include <assert.h>
// uncomment the following line to have the code check intermediate results
//#define CHECK_ANSWERS
// uncomment the following line to use Cramer's rule instead of Gaussian elimination
//#define USE_CRAMERS_RULE
#define FMAX(a,b) ((a) > (b) ? (a) : (b))
#define FMIN(a,b) ((a) > (b) ? (b) : (a))
#define FABS(a) ((a) < 0.0f ? -(a) : (a))
#define OUT_OF_RANGE(a) ((a) < 0.0f || (a) > 1.f)
#define MY_EPSILON 0.1f
__forceinline void FindNearestPointOnLineSegment(const D3DXVECTOR3 & A1,
const D3DXVECTOR3 & L,
const D3DXVECTOR3 & B,
D3DXVECTOR3 & Nearest,
float &parameter)
{
// Line/Segment is degenerate --- special case #1
float D = D3DXVec3LengthSq(&L);
if (D < MY_EPSILON*MY_EPSILON)
{
Nearest = A1;
return;
}
D3DXVECTOR3 AB = B-A1;
// parameter is computed from Equation (20).
parameter = (D3DXVec3Dot(&AB,&L)) / D;
//if (false == infinite_line)
parameter = FMAX(0.0f, FMIN(1.0f, parameter));
Nearest = A1 + parameter * L;
return;
}
/**************************************************************************
|
| Method: FindNearestPointOfParallelLineSegments
|
| Purpose: Given two lines (segments) that are known to be parallel, find
| a representative point on each that is nearest to the other. If
| the lines are considered to be finite then it is possible that there
| is one true point on each line that is nearest to the other. This
| code properly handles this case.
|
| This is the most difficult line intersection case to handle, since
| there is potentially a family, or locus of points on each line/segment
| that are nearest to the other.
| Parameters: Input:
| ------
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
| A2x, A2y, A2z - Coordinates of second defining point of line/segment A
| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
| B2x, B2y, B2z - Coordinates of second defining point of line/segment B
| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
| infinite_lines - set to true if lines are to be treated as infinite
| epsilon_squared - tolerance value to be used to check for degenerate
| and parallel lines, and to check for true intersection.
|
| Output:
| -------
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
| PointOnSegAy, to segment B. This corresponds to point C in the text.
| PointOnSegAz
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
| PointOnSegBy, to segment A. This corresponds to point D in the text.
| PointOnSegBz
**************************************************************************/
__forceinline void FindNearestPointOfParallelLineSegments(const D3DXVECTOR3 & A1,
const D3DXVECTOR3 & A2,
const D3DXVECTOR3 & La,
const D3DXVECTOR3 & B1,
const D3DXVECTOR3 & B2,
const D3DXVECTOR3 & Lb,
//bool infinite_lines, float epsilon_squared,
D3DXVECTOR3 & OutA,
D3DXVECTOR3 & OutB)
{
float s[2], temp;
FindNearestPointOnLineSegment(A1, La, B1, OutA, s[0]);
/*if (true == infinite_lines)
{
PointOnSegBx = B1x;
PointOnSegBy = B1y;
PointOnSegBz = B1z;
}
else*/
{
//float tp[3];
D3DXVECTOR3 tp;
FindNearestPointOnLineSegment(A1, La, B2,
tp, s[1]);
if (s[0] < 0.f && s[1] < 0.f)
{
OutA = A1;
if (s[0] < s[1])
{
OutB =B2;
}
else
{
OutB = B1;
}
}
else if (s[0] > 1.f && s[1] > 1.f)
{
OutA = A2;
if (s[0] < s[1])
{
OutB = B1;
}
else
{
OutB = B2;
}
}
else
{
temp = 0.5f*(FMAX(0.0f, FMIN(1.0f, s[0])) + FMAX(0.0f, FMIN(1.0f, s[1])));
OutA = A1 + temp * La;
FindNearestPointOnLineSegment(B1, Lb,
OutA, OutB, temp);
}
}
}
/**************************************************************************
|
| Method: AdjustNearestPoints
|
| Purpose: Given nearest point information for two infinite lines, adjust
| to model finite line segments.
|
| Parameters: Input:
| ------
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
| epsilon_squared - tolerance value to be used to check for degenerate
| and parallel lines, and to check for true intersection.
| s - parameter representing nearest point on infinite line A
| t - parameter representing nearest point on infinite line B
|
| Output:
| -------
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
| PointOnSegAy, to segment B. This corresponds to point C in the text.
| PointOnSegAz
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
| PointOnSegBy, to segment A. This corresponds to point D in the text.
| PointOnSegBz
**************************************************************************/
__forceinline void AdjustNearestPoints(const D3DXVECTOR3 & A1,
const D3DXVECTOR3 & La,
const D3DXVECTOR3 & B1,
const D3DXVECTOR3 & Lb,
float s, float t,
D3DXVECTOR3 & OutA,
D3DXVECTOR3 & OutB)
{
// handle the case where both parameter s and t are out of range
if (OUT_OF_RANGE(s) && OUT_OF_RANGE(t))
{
s = FMAX(0.0f, FMIN(1.0f, s));
OutA = A1 + s*La;
FindNearestPointOnLineSegment(B1, Lb,
OutA,
OutB, t);
if (OUT_OF_RANGE(t))
{
t = FMAX(0.0f, FMIN(1.0f, t));
OutB = B1 + t*Lb;
FindNearestPointOnLineSegment(A1, La, OutB,
OutA, s);
FindNearestPointOnLineSegment(B1, Lb, OutA,
OutB, t);
}
}
// otherwise, handle the case where the parameter for only one segment is
// out of range
else if (OUT_OF_RANGE(s))
{
s = FMAX(0.0f, FMIN(1.0f, s));
OutA = A1 + s*La;
FindNearestPointOnLineSegment(B1, Lb,
OutA,
OutB, t);
}
else if (OUT_OF_RANGE(t))
{
t = FMAX(0.0f, FMIN(1.0f, t));
OutB = B1 + t*Lb;
FindNearestPointOnLineSegment(A1, La, OutB,
OutA, s);
}
else
{
assert(0);
}
}
void IntersectLineSegments(const D3DXVECTOR3 & A1,
const D3DXVECTOR3 & A2,
const D3DXVECTOR3 & B1,
const D3DXVECTOR3 & B2,
//bool infinite_lines, /*float epsilon,*/
D3DXVECTOR3 & OutA,
D3DXVECTOR3 & OutB)
{
float temp = 0.f;
const float epsilon = MY_EPSILON;
const float epsilon_squared = MY_EPSILON*MY_EPSILON;
// Compute parameters from Equations (1) and (2) in the text
D3DXVECTOR3 La = A2-A1;
D3DXVECTOR3 Lb = B2-B1;
// From Equation (15)
float L11 = D3DXVec3LengthSq(&La);
float L22 = D3DXVec3LengthSq(&Lb);
// Line/Segment A is degenerate ---- Special Case #1
if (L11 < epsilon_squared)
{
OutA = A1;
FindNearestPointOnLineSegment(B1, Lb, A1,
OutB, temp);
}
// Line/Segment B is degenerate ---- Special Case #1
else if (L22 < epsilon_squared)
{
OutB = B1;
FindNearestPointOnLineSegment(A1, La, B1,
OutA, temp);
}
// Neither line/segment is degenerate
else
{
// Compute more parameters from Equation (3) in the text.
D3DXVECTOR3 AB = B1 - A1;
// and from Equation (15).
float L12 = -D3DXVec3Dot(&La, &Lb);
float DetL = L11 * L22 - L12 * L12;
// Lines/Segments A and B are parallel ---- special case #2.
if (FABS(DetL) < epsilon)
{
FindNearestPointOfParallelLineSegments(A1, A2,
La,
B1, B2,
Lb,
OutA, OutB);
}
// The general case
else
{
// from Equation (15)
float ra = D3DXVec3Dot(&La, &AB);//Lax * ABx + Lay * ABy + Laz * ABz;
float rb = D3DXVec3Dot(&Lb, &AB);//-Lbx * ABx - Lby * ABy - Lbz * ABz;
float t = (L11 * rb - ra * L12)/DetL; // Equation (12)
#ifdef USE_CRAMERS_RULE
float s = (L22 * ra - rb * L12)/DetL;
#else
float s = (ra-L12*t)/L11; // Equation (13)
#endif // USE_CRAMERS_RULE
#ifdef CHECK_ANSWERS
float check_ra = s*L11 + t*L12;
float check_rb = s*L12 + t*L22;
assert(FABS(check_ra-ra) < epsilon);
assert(FABS(check_rb-rb) < epsilon);
#endif // CHECK_ANSWERS
// if we are dealing with infinite lines or if parameters s and t both
// lie in the range [0,1] then just compute the points using Equations
// (1) and (2) from the text.
OutA = (A1 + s * La);
OutB = (B1 + t * Lb);
// otherwise, at least one of s and t is outside of [0,1] and we have to
// handle this case.
if ((OUT_OF_RANGE(s) || OUT_OF_RANGE(t)))
{
AdjustNearestPoints(A1,La,B1,Lb,
s, t,
OutA,
OutB);
}
}
}
}
void IntersectLineSegments(const float A1x, const float A1y, const float A1z,
const float A2x, const float A2y, const float A2z,
const float B1x, const float B1y, const float B1z,
const float B2x, const float B2y, const float B2z,
bool infinite_lines, float epsilon, float &PointOnSegAx,
float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx,
float &PointOnSegBy, float &PointOnSegBz)
{
float temp = 0.f;
float epsilon_squared = epsilon * epsilon;
// Compute parameters from Equations (1) and (2) in the text
float Lax = A2x - A1x;
float Lay = A2y - A1y;
float Laz = A2z - A1z;
float Lbx = B2x - B1x;
float Lby = B2y - B1y;
float Lbz = B2z - B1z;
// From Equation (15)
float L11 = (Lax * Lax) + (Lay * Lay) + (Laz * Laz);
float L22 = (Lbx * Lbx) + (Lby * Lby) + (Lbz * Lbz);
// Line/Segment A is degenerate ---- Special Case #1
if (L11 < epsilon_squared)
{
PointOnSegAx = A1x;
PointOnSegAy = A1y;
PointOnSegAz = A1z;
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, A1x, A1y, A1z,
infinite_lines, epsilon, PointOnSegBx, PointOnSegBy,
PointOnSegBz, temp);
}
// Line/Segment B is degenerate ---- Special Case #1
else if (L22 < epsilon_squared)
{
PointOnSegBx = B1x;
PointOnSegBy = B1y;
PointOnSegBz = B1z;
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z,
infinite_lines, epsilon, PointOnSegAx, PointOnSegAy,
PointOnSegAz, temp);
}
// Neither line/segment is degenerate
else
{
// Compute more parameters from Equation (3) in the text.
float ABx = B1x - A1x;
float ABy = B1y - A1y;
float ABz = B1z - A1z;
// and from Equation (15).
float L12 = -(Lax * Lbx) - (Lay * Lby) - (Laz * Lbz);
float DetL = L11 * L22 - L12 * L12;
// Lines/Segments A and B are parallel ---- special case #2.
if (FABS(DetL) < epsilon)
{
FindNearestPointOfParallelLineSegments(A1x, A1y, A1z, A2x, A2y, A2z,
Lax, Lay, Laz,
B1x, B1y, B1z, B2x, B2y, B2z,
Lbx, Lby, Lbz,
infinite_lines, epsilon,
PointOnSegAx, PointOnSegAy, PointOnSegAz,
PointOnSegBx, PointOnSegBy, PointOnSegBz);
}
// The general case
else
{
// from Equation (15)
float ra = Lax * ABx + Lay * ABy + Laz * ABz;
float rb = -Lbx * ABx - Lby * ABy - Lbz * ABz;
float t = (L11 * rb - ra * L12)/DetL; // Equation (12)
#ifdef USE_CRAMERS_RULE
float s = (L22 * ra - rb * L12)/DetL;
#else
float s = (ra-L12*t)/L11; // Equation (13)
#endif // USE_CRAMERS_RULE
#ifdef CHECK_ANSWERS
float check_ra = s*L11 + t*L12;
float check_rb = s*L12 + t*L22;
assert(FABS(check_ra-ra) < epsilon);
assert(FABS(check_rb-rb) < epsilon);
#endif // CHECK_ANSWERS
// if we are dealing with infinite lines or if parameters s and t both
// lie in the range [0,1] then just compute the points using Equations
// (1) and (2) from the text.
PointOnSegAx = (A1x + s * Lax);
PointOnSegAy = (A1y + s * Lay);
PointOnSegAz = (A1z + s * Laz);
PointOnSegBx = (B1x + t * Lbx);
PointOnSegBy = (B1y + t * Lby);
PointOnSegBz = (B1z + t * Lbz);
// otherwise, at least one of s and t is outside of [0,1] and we have to
// handle this case.
if (false == infinite_lines && (OUT_OF_RANGE(s) || OUT_OF_RANGE(t)))
{
AdjustNearestPoints(A1x, A1y, A1z, Lax, Lay, Laz,
B1x, B1y, B1z, Lbx, Lby, Lbz,
epsilon, s, t,
PointOnSegAx, PointOnSegAy, PointOnSegAz,
PointOnSegBx, PointOnSegBy, PointOnSegBz);
}
}
}
}
// pragma to get rid of math.h inline function removal warnings.
#pragma warning(disable:4514)
/**************************************************************************
|
| Method: IntersectLineSegments
|
| Purpose: Find the nearest point between two finite length line segments
| or two infinite lines in 3-dimensional space. The function calculates
| the point on each line/line segment that is closest to the other
| line/line segment, the midpoint between the nearest points, and
| the vector between these two points. If the two nearest points
| are close within a tolerance, a flag is set indicating the lines
| have a "true" intersection.
|
| Parameters: Input:
| ------
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
| A2x, A2y, A2z - Coordinates of second defining point of line/segment A
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
| B2x, B2y, B2z - Coordinates of second defining point of line/segment B
| infinite_lines - set to true if lines are to be treated as infinite
| epsilon - tolerance value to be used to check for degenerate
| and parallel lines, and to check for true intersection.
|
| Output:
| -------
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
| PointOnSegAy, to segment B. This corresponds to point C in the text.
| PointOnSegAz
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
| PointOnSegBy, to segment A. This corresponds to point D in the text.
| PointOnSegBz
| NearestPointX, - Midpoint between the two nearest points. This can be
| NearestPointY, treated as *the* intersection point if nearest points
| NearestPointZ are sufficiently close. This corresponds to point P
| in the text.
| NearestVectorX, - Vector between the nearest point on A to the nearest
| point on segment B. This vector is normal to both
| lines if the lines are infinite, but is not guaranteed
| to be normal to both lines if both lines are finite
| length.
| true_intersection - true if the nearest points are close within a small
| tolerance.
**************************************************************************/
void IntersectLineSegments(const float A1x, const float A1y, const float A1z,
const float A2x, const float A2y, const float A2z,
const float B1x, const float B1y, const float B1z,
const float B2x, const float B2y, const float B2z,
bool infinite_lines, float epsilon, float &PointOnSegAx,
float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx,
float &PointOnSegBy, float &PointOnSegBz, float &NearestPointX,
float &NearestPointY, float &NearestPointZ, float &NearestVectorX,
float &NearestVectorY, float &NearestVectorZ, bool &true_intersection)
{
float temp = 0.f;
float epsilon_squared = epsilon * epsilon;
// Compute parameters from Equations (1) and (2) in the text
float Lax = A2x - A1x;
float Lay = A2y - A1y;
float Laz = A2z - A1z;
float Lbx = B2x - B1x;
float Lby = B2y - B1y;
float Lbz = B2z - B1z;
// From Equation (15)
float L11 = (Lax * Lax) + (Lay * Lay) + (Laz * Laz);
float L22 = (Lbx * Lbx) + (Lby * Lby) + (Lbz * Lbz);
// Line/Segment A is degenerate ---- Special Case #1
if (L11 < epsilon_squared)
{
PointOnSegAx = A1x;
PointOnSegAy = A1y;
PointOnSegAz = A1z;
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, A1x, A1y, A1z,
infinite_lines, epsilon, PointOnSegBx, PointOnSegBy,
PointOnSegBz, temp);
}
// Line/Segment B is degenerate ---- Special Case #1
else if (L22 < epsilon_squared)
{
PointOnSegBx = B1x;
PointOnSegBy = B1y;
PointOnSegBz = B1z;
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z,
infinite_lines, epsilon, PointOnSegAx, PointOnSegAy,
PointOnSegAz, temp);
}
// Neither line/segment is degenerate
else
{
// Compute more parameters from Equation (3) in the text.
float ABx = B1x - A1x;
float ABy = B1y - A1y;
float ABz = B1z - A1z;
// and from Equation (15).
float L12 = -(Lax * Lbx) - (Lay * Lby) - (Laz * Lbz);
float DetL = L11 * L22 - L12 * L12;
// Lines/Segments A and B are parallel ---- special case #2.
if (FABS(DetL) < epsilon)
{
FindNearestPointOfParallelLineSegments(A1x, A1y, A1z, A2x, A2y, A2z,
Lax, Lay, Laz,
B1x, B1y, B1z, B2x, B2y, B2z,
Lbx, Lby, Lbz,
infinite_lines, epsilon,
PointOnSegAx, PointOnSegAy, PointOnSegAz,
PointOnSegBx, PointOnSegBy, PointOnSegBz);
}
// The general case
else
{
// from Equation (15)
float ra = Lax * ABx + Lay * ABy + Laz * ABz;
float rb = -Lbx * ABx - Lby * ABy - Lbz * ABz;
float t = (L11 * rb - ra * L12)/DetL; // Equation (12)
#ifdef USE_CRAMERS_RULE
float s = (L22 * ra - rb * L12)/DetL;
#else
float s = (ra-L12*t)/L11; // Equation (13)
#endif // USE_CRAMERS_RULE
#ifdef CHECK_ANSWERS
float check_ra = s*L11 + t*L12;
float check_rb = s*L12 + t*L22;
assert(FABS(check_ra-ra) < epsilon);
assert(FABS(check_rb-rb) < epsilon);
#endif // CHECK_ANSWERS
// if we are dealing with infinite lines or if parameters s and t both
// lie in the range [0,1] then just compute the points using Equations
// (1) and (2) from the text.
PointOnSegAx = (A1x + s * Lax);
PointOnSegAy = (A1y + s * Lay);
PointOnSegAz = (A1z + s * Laz);
PointOnSegBx = (B1x + t * Lbx);
PointOnSegBy = (B1y + t * Lby);
PointOnSegBz = (B1z + t * Lbz);
// otherwise, at least one of s and t is outside of [0,1] and we have to
// handle this case.
if (false == infinite_lines && (OUT_OF_RANGE(s) || OUT_OF_RANGE(t)))
{
AdjustNearestPoints(A1x, A1y, A1z, Lax, Lay, Laz,
B1x, B1y, B1z, Lbx, Lby, Lbz,
epsilon, s, t,
PointOnSegAx, PointOnSegAy, PointOnSegAz,
PointOnSegBx, PointOnSegBy, PointOnSegBz);
}
}
}
NearestPointX = 0.5f * (PointOnSegAx + PointOnSegBx);
NearestPointY = 0.5f * (PointOnSegAy + PointOnSegBy);
NearestPointZ = 0.5f * (PointOnSegAz + PointOnSegBz);
NearestVectorX = PointOnSegBx - PointOnSegAx;
NearestVectorY = PointOnSegBy - PointOnSegAy;
NearestVectorZ = PointOnSegBz - PointOnSegAz;
// optional check to indicate if the lines truly intersect
true_intersection = (FABS(NearestVectorX) +
FABS(NearestVectorY) +
FABS(NearestVectorZ)) < epsilon ? true : false;
}
/**************************************************************************
|
| Method: FindNearestPointOnLineSegment
|
| Purpose: Given a line (segment) and a point in 3-dimensional space,
| find the point on the line (segment) that is closest to the
| point.
|
| Parameters: Input:
| ------
| A1x, A1y, A1z - Coordinates of first defining point of the line/segment
| Lx, Ly, Lz - Vector from (A1x, A1y, A1z) to the second defining point
| of the line/segment.
| Bx, By, Bz - Coordinates of the point
| infinite_lines - set to true if lines are to be treated as infinite
| epsilon_squared - tolerance value to be used to check for degenerate
| and parallel lines, and to check for true intersection.
|
| Output:
| -------
| NearestPointX, - Point on line/segment that is closest to (Bx, By, Bz)
| NearestPointY,
| NearestPointZ
| parameter - Parametric coordinate of the nearest point along the
| line/segment. parameter = 0 at (A1x, A1y, A1z) and
| parameter = 1 at the second defining point of the line/
| segmetn
**************************************************************************/
void FindNearestPointOnLineSegment(const float A1x, const float A1y, const float A1z,
const float Lx, const float Ly, const float Lz,
const float Bx, const float By, const float Bz,
bool infinite_line, float epsilon_squared, float &NearestPointX,
float &NearestPointY, float &NearestPointZ,
float &parameter)
{
// Line/Segment is degenerate --- special case #1
float D = Lx * Lx + Ly * Ly + Lz * Lz;
if (D < epsilon_squared)
{
NearestPointX = A1x;
NearestPointY = A1y;
NearestPointZ = A1z;
return;
}
float ABx = Bx - A1x;
float ABy = By - A1y;
float ABz = Bz - A1z;
// parameter is computed from Equation (20).
parameter = (Lx * ABx + Ly * ABy + Lz * ABz) / D;
if (false == infinite_line) parameter = FMAX(0.0f, FMIN(1.0f, parameter));
NearestPointX = A1x + parameter * Lx;
NearestPointY = A1y + parameter * Ly;
NearestPointZ = A1z + parameter * Lz;
return;
}
/**************************************************************************
|
| Method: FindNearestPointOfParallelLineSegments
|
| Purpose: Given two lines (segments) that are known to be parallel, find
| a representative point on each that is nearest to the other. If
| the lines are considered to be finite then it is possible that there
| is one true point on each line that is nearest to the other. This
| code properly handles this case.
|
| This is the most difficult line intersection case to handle, since
| there is potentially a family, or locus of points on each line/segment
| that are nearest to the other.
| Parameters: Input:
| ------
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
| A2x, A2y, A2z - Coordinates of second defining point of line/segment A
| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
| B2x, B2y, B2z - Coordinates of second defining point of line/segment B
| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
| infinite_lines - set to true if lines are to be treated as infinite
| epsilon_squared - tolerance value to be used to check for degenerate
| and parallel lines, and to check for true intersection.
|
| Output:
| -------
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
| PointOnSegAy, to segment B. This corresponds to point C in the text.
| PointOnSegAz
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
| PointOnSegBy, to segment A. This corresponds to point D in the text.
| PointOnSegBz
**************************************************************************/
void FindNearestPointOfParallelLineSegments(float A1x, float A1y, float A1z,
float A2x, float A2y, float A2z,
float Lax, float Lay, float Laz,
float B1x, float B1y, float B1z,
float B2x, float B2y, float B2z,
float Lbx, float Lby, float Lbz,
bool infinite_lines, float epsilon_squared,
float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz,
float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz)
{
float s[2], temp;
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z,
true, epsilon_squared, PointOnSegAx, PointOnSegAy, PointOnSegAz, s[0]);
if (true == infinite_lines)
{
PointOnSegBx = B1x;
PointOnSegBy = B1y;
PointOnSegBz = B1z;
}
else
{
float tp[3];
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B2x, B2y, B2z,
true, epsilon_squared, tp[0], tp[1], tp[2], s[1]);
if (s[0] < 0.f && s[1] < 0.f)
{
PointOnSegAx = A1x;
PointOnSegAy = A1y;
PointOnSegAz = A1z;
if (s[0] < s[1])
{
PointOnSegBx = B2x;
PointOnSegBy = B2y;
PointOnSegBz = B2z;
}
else
{
PointOnSegBx = B1x;
PointOnSegBy = B1y;
PointOnSegBz = B1z;
}
}
else if (s[0] > 1.f && s[1] > 1.f)
{
PointOnSegAx = A2x;
PointOnSegAy = A2y;
PointOnSegAz = A2z;
if (s[0] < s[1])
{
PointOnSegBx = B1x;
PointOnSegBy = B1y;
PointOnSegBz = B1z;
}
else
{
PointOnSegBx = B2x;
PointOnSegBy = B2y;
PointOnSegBz = B2z;
}
}
else
{
temp = 0.5f*(FMAX(0.0f, FMIN(1.0f, s[0])) + FMAX(0.0f, FMIN(1.0f, s[1])));
PointOnSegAx = (A1x + temp * Lax);
PointOnSegAy = (A1y + temp * Lay);
PointOnSegAz = (A1z + temp * Laz);
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz,
PointOnSegAx, PointOnSegAy, PointOnSegAz, true,
epsilon_squared, PointOnSegBx, PointOnSegBy, PointOnSegBz, temp);
}
}
}
/**************************************************************************
|
| Method: AdjustNearestPoints
|
| Purpose: Given nearest point information for two infinite lines, adjust
| to model finite line segments.
|
| Parameters: Input:
| ------
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
| epsilon_squared - tolerance value to be used to check for degenerate
| and parallel lines, and to check for true intersection.
| s - parameter representing nearest point on infinite line A
| t - parameter representing nearest point on infinite line B
|
| Output:
| -------
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
| PointOnSegAy, to segment B. This corresponds to point C in the text.
| PointOnSegAz
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
| PointOnSegBy, to segment A. This corresponds to point D in the text.
| PointOnSegBz
**************************************************************************/
void AdjustNearestPoints(float A1x, float A1y, float A1z,
float Lax, float Lay, float Laz,
float B1x, float B1y, float B1z,
float Lbx, float Lby, float Lbz,
float epsilon_squared, float s, float t,
float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz,
float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz)
{
// handle the case where both parameter s and t are out of range
if (OUT_OF_RANGE(s) && OUT_OF_RANGE(t))
{
s = FMAX(0.0f, FMIN(1.0f, s));
PointOnSegAx = (A1x + s * Lax);
PointOnSegAy = (A1y + s * Lay);
PointOnSegAz = (A1z + s * Laz);
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx,
PointOnSegAy, PointOnSegAz, true, epsilon_squared,
PointOnSegBx, PointOnSegBy, PointOnSegBz, t);
if (OUT_OF_RANGE(t))
{
t = FMAX(0.0f, FMIN(1.0f, t));
PointOnSegBx = (B1x + t * Lbx);
PointOnSegBy = (B1y + t * Lby);
PointOnSegBz = (B1z + t * Lbz);
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, PointOnSegBx,
PointOnSegBy, PointOnSegBz, false, epsilon_squared,
PointOnSegAx, PointOnSegAy, PointOnSegAz, s);
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx,
PointOnSegAy, PointOnSegAz, false, epsilon_squared,
PointOnSegBx, PointOnSegBy, PointOnSegBz, t);
}
}
// otherwise, handle the case where the parameter for only one segment is
// out of range
else if (OUT_OF_RANGE(s))
{
s = FMAX(0.0f, FMIN(1.0f, s));
PointOnSegAx = (A1x + s * Lax);
PointOnSegAy = (A1y + s * Lay);
PointOnSegAz = (A1z + s * Laz);
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx,
PointOnSegAy, PointOnSegAz, false, epsilon_squared,
PointOnSegBx, PointOnSegBy, PointOnSegBz, t);
}
else if (OUT_OF_RANGE(t))
{
t = FMAX(0.0f, FMIN(1.0f, t));
PointOnSegBx = (B1x + t * Lbx);
PointOnSegBy = (B1y + t * Lby);
PointOnSegBz = (B1z + t * Lbz);
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, PointOnSegBx,
PointOnSegBy, PointOnSegBz, false, epsilon_squared,
PointOnSegAx, PointOnSegAy, PointOnSegAz, s);
}
else
{
assert(0);
}
}
@@ -0,0 +1,80 @@
/* Copyright (C) Graham Rhodes, 2001.
* All rights reserved worldwide.
*
* This software is provided "as is" without express or implied
* warranties. You may freely copy and compile this source into
* applications you distribute provided that the copyright text
* below is included in the resulting source code, for example:
* "Portions Copyright (C) Graham Rhodes, 2001"
*/
/**************************************************************************************
|
| File: lineintersect_utils.h
|
| Purpose: Function prototypes for line segment intersection utility functions
|
| Book Title: Game Programming Gems II
|
| Chapter Title: Fast, Robust Intersection of 3D Line Segments
|
| Author: Graham Rhodes
|
| Revisions: 05-Apr-2001 - GSR. Original.
|
**************************************************************************************/
#ifndef _lineintersect_utils_h
#define _lineintersect_utils_h
void IntersectLineSegments(const D3DXVECTOR3 & A1,
const D3DXVECTOR3 & A2,
const D3DXVECTOR3 & B1,
const D3DXVECTOR3 & B2,
//bool infinite_lines, /*float epsilon,*/
D3DXVECTOR3 & OutA,
D3DXVECTOR3 & OutB);
void IntersectLineSegments(const float A1x, const float A1y, const float A1z,
const float A2x, const float A2y, const float A2z,
const float B1x, const float B1y, const float B1z,
const float B2x, const float B2y, const float B2z,
bool infinite_lines, float epsilon, float &PointOnSegAx,
float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx,
float &PointOnSegBy, float &PointOnSegBz, float &NearestPointX,
float &NearestPointY, float &NearestPointZ, float &NearestVectorX,
float &NearestVectorY, float &NearestVectorZ, bool &true_intersection);
void IntersectLineSegments(const float A1x, const float A1y, const float A1z,
const float A2x, const float A2y, const float A2z,
const float B1x, const float B1y, const float B1z,
const float B2x, const float B2y, const float B2z,
bool infinite_lines, float epsilon, float &PointOnSegAx,
float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx,
float &PointOnSegBy, float &PointOnSegBz);
void FindNearestPointOnLineSegment(const float A1x, const float A1y, const float A1z,
const float Lx, const float Ly, const float Lz,
const float Bx, const float By, const float Bz,
bool infinite_line, float epsilon_squared, float &NearestPointX,
float &NearestPointY, float &NearestPointZ,
float &parameter);
void FindNearestPointOfParallelLineSegments(float A1x, float A1y, float A1z,
float A2x, float A2y, float A2z,
float Lax, float Lay, float Laz,
float B1x, float B1y, float B1z,
float B2x, float B2y, float B2z,
float Lbx, float Lby, float Lbz,
bool infinite_lines, float epsilon_squared,
float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz,
float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz);
void AdjustNearestPoints(float A1x, float A1y, float A1z,
float Lax, float Lay, float Laz,
float B1x, float B1y, float B1z,
float Lbx, float Lby, float Lbz,
float epsilon_squared, float s, float t,
float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz,
float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz);
#endif // _lineintersect_utils_h
@@ -0,0 +1,606 @@
#include "StdAfx.h"
#include "../EffectLib/EffectManager.h"
#include "ActorInstance.h"
#include "ItemData.h"
#include "ItemManager.h"
#include "RaceData.h"
#include "WeaponTrace.h"
BOOL USE_WEAPON_SPECULAR = TRUE;
BOOL USE_VIETNAM_CONVERT_WEAPON_VNUM = FALSE;
DWORD Vietnam_ConvertWeaponVnum(DWORD vnum)
{
DWORD base = vnum / 10 * 10;
DWORD rest = vnum % 10;
switch (base)
{
case 10:base = 5000;break;
case 20:base = 5010;break;
case 30:base = 5020;break;
case 40:base = 5030;break;
case 50:base = 5030;break;
case 60:base = 5040;break;
case 70:base = 5040;break;
case 80:base = 5050;break;
case 90:base = 5050;break;
case 100:base = 5060;break;
case 110:base = 5060;break;
case 120:base = 5070;break;
case 130:base = 5070;break;
case 140:base = 5080;break;
case 150:base = 5080;break;
case 160:base = 5090;break;
case 170:base = 5090;break;
case 180:base = 5100;break;
case 190:base = 5100;break;
case 200:base = 5110;break;
case 210:base = 5110;break;
case 220:base = 5120;break;
case 230:base = 5120;break;
case 240:base = 5130;break;
case 250:base = 5130;break;
case 260:base = 5140;break;
case 270:base = 5140;break;
case 280:base = 5150;break;
case 290:base = 5150;break;
case 1000:base = 5000;break;
case 1010:base = 5010;break;
case 1020:base = 5020;break;
case 1030:base = 5030;break;
case 1040:base = 5040;break;
case 1050:base = 5050;break;
case 1060:base = 5060;break;
case 1070:base = 5070;break;
case 1080:base = 5080;break;
case 1090:base = 5090;break;
case 1100:base = 5100;break;
case 1110:base = 5110;break;
case 1120:base = 5120;break;
case 1130:base = 5130;break;
case 1140:base = 5140;break;
case 1150:base = 5150;break;
case 1160:base = 5150;break;
case 1170:base = 5150;break;
case 3000:base = 5000;break;
case 3010:base = 5010;break;
case 3020:base = 5020;break;
case 3030:base = 5030;break;
case 3040:base = 5040;break;
case 3050:base = 5050;break;
case 3060:base = 5060;break;
case 3070:base = 5070;break;
case 3080:base = 5080;break;
case 3090:base = 5090;break;
case 3100:base = 5100;break;
case 3110:base = 5100;break;
case 3120:base = 5110;break;
case 3130:base = 5110;break;
case 3140:base = 5120;break;
case 3150:base = 5120;break;
case 3160:base = 5130;break;
case 3170:base = 5130;break;
case 3180:base = 5140;break;
case 3190:base = 5140;break;
case 3200:base = 5150;break;
case 3210:base = 5150;break;
}
return base + rest;
}
DWORD CActorInstance::AttachSmokeEffect(DWORD eSmoke)
{
if (!m_pkCurRaceData)
return 0;
DWORD dwSmokeEffectID=m_pkCurRaceData->GetSmokeEffectID(eSmoke);
return AttachEffectByID(0, m_pkCurRaceData->GetSmokeBone().c_str(), dwSmokeEffectID);
}
bool CActorInstance::__IsLeftHandWeapon(DWORD type)
{
if (CItemData::WEAPON_DAGGER == type || (CItemData::WEAPON_FAN == type && __IsMountingHorse()))
return true;
else if (CItemData::WEAPON_BOW == type)
return true;
else
return false;
}
bool CActorInstance::__IsRightHandWeapon(DWORD type)
{
if (CItemData::WEAPON_DAGGER == type || (CItemData::WEAPON_FAN == type && __IsMountingHorse()))
return true;
else if (CItemData::WEAPON_BOW == type)
return false;
else
return true;
}
bool CActorInstance::__IsWeaponTrace(DWORD weaponType)
{
switch(weaponType)
{
case CItemData::WEAPON_BELL:
case CItemData::WEAPON_FAN:
case CItemData::WEAPON_BOW:
return false;
default:
return true;
}
}
void CActorInstance::AttachWeapon(DWORD dwItemIndex,DWORD dwParentPartIndex, DWORD dwPartIndex)
{
if (dwPartIndex>=CRaceData::PART_MAX_NUM)
return;
m_adwPartItemID[dwPartIndex]=dwItemIndex;
if (USE_VIETNAM_CONVERT_WEAPON_VNUM)
dwItemIndex = Vietnam_ConvertWeaponVnum(dwItemIndex);
CItemData * pItemData;
if (!CItemManager::Instance().GetItemDataPointer(dwItemIndex, &pItemData))
{
RegisterModelThing(dwPartIndex, NULL);
SetModelInstance(dwPartIndex, dwPartIndex, 0);
RegisterModelThing(CRaceData::PART_WEAPON_LEFT, NULL);
SetModelInstance(CRaceData::PART_WEAPON_LEFT, CRaceData::PART_WEAPON_LEFT, 0);
RefreshActorInstance();
return;
}
__DestroyWeaponTrace();
//양손무기(자객 이도류) 왼손,오른손 모두에 장착.
if (__IsRightHandWeapon(pItemData->GetWeaponType()))
AttachWeapon(dwParentPartIndex, CRaceData::PART_WEAPON, pItemData);
if (__IsLeftHandWeapon(pItemData->GetWeaponType()))
AttachWeapon(dwParentPartIndex, CRaceData::PART_WEAPON_LEFT, pItemData);
}
BOOL CActorInstance::GetAttachingBoneName(DWORD dwPartIndex, const char ** c_pszBoneName)
{
return m_pkCurRaceData->GetAttachingBoneName(dwPartIndex, c_pszBoneName);
}
void CActorInstance::AttachWeapon(DWORD dwParentPartIndex, DWORD dwPartIndex, CItemData * pItemData)
{
// assert(m_pkCurRaceData);
if (!pItemData)
return;
const char * szBoneName;
if (!GetAttachingBoneName(dwPartIndex, &szBoneName))
return;
// NOTE : (이도류처리)단도일 경우 형태가 다른 것으로 얻는다. 없을 경우 디폴트를 리턴
if (CRaceData::PART_WEAPON_LEFT == dwPartIndex)
{
RegisterModelThing(dwPartIndex, pItemData->GetSubModelThing());
}
else
{
RegisterModelThing(dwPartIndex, pItemData->GetModelThing());
}
for (DWORD i = 0; i < pItemData->GetLODModelThingCount(); ++i)
{
CGraphicThing * pThing;
if (!pItemData->GetLODModelThingPointer(i, &pThing))
continue;
RegisterLODThing(dwPartIndex, pThing);
}
SetModelInstance(dwPartIndex, dwPartIndex, 0);
AttachModelInstance(dwParentPartIndex, szBoneName, dwPartIndex);
// 20041208.myevan.무기스펙큘러(값옷은 SetShape에서 직접 해준다.)
if (USE_WEAPON_SPECULAR)
{
SMaterialData kMaterialData;
kMaterialData.pImage = NULL;
kMaterialData.isSpecularEnable = TRUE;
kMaterialData.fSpecularPower = pItemData->GetSpecularPowerf();
kMaterialData.bSphereMapIndex = 1;
SetMaterialData(dwPartIndex, NULL, kMaterialData);
}
// Weapon Trace
if (__IsWeaponTrace(pItemData->GetWeaponType()))
{
CWeaponTrace * pWeaponTrace = CWeaponTrace::New();
pWeaponTrace->SetWeaponInstance(this, dwPartIndex, szBoneName);
m_WeaponTraceVector.push_back(pWeaponTrace);
}
}
void CActorInstance::DettachEffect(DWORD dwEID)
{
std::list<TAttachingEffect>::iterator i = m_AttachingEffectList.begin();
while (i != m_AttachingEffectList.end())
{
TAttachingEffect & rkAttEft = (*i);
if (rkAttEft.dwEffectIndex == dwEID)
{
i = m_AttachingEffectList.erase(i);
CEffectManager::Instance().DestroyEffectInstance(dwEID);
}
else
{
++i;
}
}
}
DWORD CActorInstance::AttachEffectByName(DWORD dwParentPartIndex, const char * c_pszBoneName, const char * c_pszEffectName)
{
std::string str;
DWORD dwCRC;
StringPath(c_pszEffectName, str);
dwCRC = GetCaseCRC32(str.c_str(), str.length());
return AttachEffectByID(dwParentPartIndex, c_pszBoneName, dwCRC);
}
DWORD CActorInstance::AttachEffectByID(DWORD dwParentPartIndex, const char * c_pszBoneName, DWORD dwEffectID, const D3DXVECTOR3 * c_pv3Position)
{
TAttachingEffect ae;
ae.iLifeType = EFFECT_LIFE_INFINITE;
ae.dwEndTime = 0;
ae.dwModelIndex = dwParentPartIndex;
ae.dwEffectIndex = CEffectManager::Instance().GetEmptyIndex();
ae.isAttaching = TRUE;
if (c_pv3Position)
{
D3DXMatrixTranslation(&ae.matTranslation, c_pv3Position->x, c_pv3Position->y, c_pv3Position->z);
}
else
{
D3DXMatrixIdentity(&ae.matTranslation);
}
CEffectManager& rkEftMgr=CEffectManager::Instance();
rkEftMgr.CreateEffectInstance(ae.dwEffectIndex, dwEffectID);
if (c_pszBoneName)
{
int iBoneIndex;
if (!FindBoneIndex(dwParentPartIndex,c_pszBoneName, &iBoneIndex))
{
ae.iBoneIndex = -1;
//Tracef("Cannot get Bone Index\n");
//assert(false && "Cannot get Bone Index");
}
else
{
ae.iBoneIndex = iBoneIndex;
}
}
else
{
ae.iBoneIndex = -1;
}
m_AttachingEffectList.push_back(ae);
return ae.dwEffectIndex;
}
void CActorInstance::RefreshActorInstance()
{
if (!m_pkCurRaceData)
{
TraceError("void CActorInstance::RefreshActorInstance() - m_pkCurRaceData=NULL");
return;
}
// This is Temporary place before making the weapon detection system
// Setup Collison Detection Data
m_BodyPointInstanceList.clear();
//m_AttackingPointInstanceList.clear();
m_DefendingPointInstanceList.clear();
// Base
for (DWORD i = 0; i < m_pkCurRaceData->GetAttachingDataCount(); ++i)
{
const NRaceData::TAttachingData * c_pAttachingData;
if (!m_pkCurRaceData->GetAttachingDataPointer(i, &c_pAttachingData))
continue;
switch (c_pAttachingData->dwType)
{
case NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA:
{
const NRaceData::TCollisionData * c_pCollisionData = c_pAttachingData->pCollisionData;
TCollisionPointInstance PointInstance;
if (NRaceData::COLLISION_TYPE_ATTACKING == c_pCollisionData->iCollisionType)
continue;
if (!CreateCollisionInstancePiece(CRaceData::PART_MAIN, c_pAttachingData, &PointInstance))
continue;
switch (c_pCollisionData->iCollisionType)
{
case NRaceData::COLLISION_TYPE_ATTACKING:
//m_AttackingPointInstanceList.push_back(PointInstance);
break;
case NRaceData::COLLISION_TYPE_DEFENDING:
m_DefendingPointInstanceList.push_back(PointInstance);
break;
case NRaceData::COLLISION_TYPE_BODY:
m_BodyPointInstanceList.push_back(PointInstance);
break;
}
}
break;
case NRaceData::ATTACHING_DATA_TYPE_EFFECT:
// if (!m_bEffectInitialized)
// {
// DWORD dwCRC;
// StringPath(c_pAttachingData->pEffectData->strFileName);
// dwCRC = GetCaseCRC32(c_pAttachingData->pEffectData->strFileName.c_str(),c_pAttachingData->pEffectData->strFileName.length());
//
// TAttachingEffect ae;
// ae.iLifeType = EFFECT_LIFE_INFINITE;
// ae.dwEndTime = 0;
// ae.dwModelIndex = 0;
// ae.dwEffectIndex = CEffectManager::Instance().GetEmptyIndex();
// ae.isAttaching = TRUE;
// CEffectManager::Instance().CreateEffectInstance(ae.dwEffectIndex, dwCRC);
//
// if (c_pAttachingData->isAttaching)
// {
// int iBoneIndex;
// if (!FindBoneIndex(0,c_pAttachingData->strAttachingBoneName.c_str(), &iBoneIndex))
// {
// Tracef("Cannot get Bone Index\n");
// assert(false/*Cannot get Bone Index*/);
// }
//
// ae.iBoneIndex = iBoneIndex;
// }
// else
// {
// ae.iBoneIndex = -1;
// }
//
// m_AttachingEffectList.push_back(ae);
// }
if (c_pAttachingData->isAttaching)
{
AttachEffectByName(0, c_pAttachingData->strAttachingBoneName.c_str(), c_pAttachingData->pEffectData->strFileName.c_str());
}
else
{
AttachEffectByName(0, 0, c_pAttachingData->pEffectData->strFileName.c_str());
}
break;
case NRaceData::ATTACHING_DATA_TYPE_OBJECT:
break;
default:
assert(false/*NOT_IMPLEMENTED*/);
break;
}
}
for (DWORD j = 0; j < CRaceData::PART_MAX_NUM; ++j)
{
if (0 == m_adwPartItemID[j])
continue;
CItemData * pItemData;
if (!CItemManager::Instance().GetItemDataPointer(m_adwPartItemID[j], &pItemData))
return;
for (DWORD k = 0; k < pItemData->GetAttachingDataCount(); ++k)
{
const NRaceData::TAttachingData * c_pAttachingData;
if (!pItemData->GetAttachingDataPointer(k, &c_pAttachingData))
continue;
switch(c_pAttachingData->dwType)
{
case NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA:
{
const NRaceData::TCollisionData * c_pCollisionData = c_pAttachingData->pCollisionData;
// FIXME : 첫번째 인자는 Part의 번호다.
// Base는 무조건 0인가? - [levites]
TCollisionPointInstance PointInstance;
if (NRaceData::COLLISION_TYPE_ATTACKING == c_pCollisionData->iCollisionType)
continue;
if (!CreateCollisionInstancePiece(j, c_pAttachingData, &PointInstance))
continue;
switch (c_pCollisionData->iCollisionType)
{
case NRaceData::COLLISION_TYPE_ATTACKING:
//m_AttackingPointInstanceList.push_back(PointInstance);
break;
case NRaceData::COLLISION_TYPE_DEFENDING:
m_DefendingPointInstanceList.push_back(PointInstance);
break;
case NRaceData::COLLISION_TYPE_BODY:
m_BodyPointInstanceList.push_back(PointInstance);
break;
}
}
break;
case NRaceData::ATTACHING_DATA_TYPE_EFFECT:
if (!m_bEffectInitialized)
{
DWORD dwCRC;
StringPath(c_pAttachingData->pEffectData->strFileName);
dwCRC = GetCaseCRC32(c_pAttachingData->pEffectData->strFileName.c_str(),c_pAttachingData->pEffectData->strFileName.length());
TAttachingEffect ae;
ae.iLifeType = EFFECT_LIFE_INFINITE;
ae.dwEndTime = 0;
ae.dwModelIndex = j;
ae.dwEffectIndex = CEffectManager::Instance().GetEmptyIndex();
ae.isAttaching = TRUE;
CEffectManager::Instance().CreateEffectInstance(ae.dwEffectIndex, dwCRC);
int iBoneIndex;
if (!FindBoneIndex(j,c_pAttachingData->strAttachingBoneName.c_str(), &iBoneIndex))
{
Tracef("Cannot get Bone Index\n");
assert(false/*Cannot get Bone Index*/);
}
Tracef("Creating %p %d %d\n", this, j,k);
ae.iBoneIndex = iBoneIndex;
m_AttachingEffectList.push_back(ae);
}
break;
case NRaceData::ATTACHING_DATA_TYPE_OBJECT:
break;
default:
assert(false/*NOT_IMPLEMENTED*/);
break;
}
}
}
m_bEffectInitialized = true;
}
void CActorInstance::SetWeaponTraceTexture(const char * szTextureName)
{
std::vector<CWeaponTrace*>::iterator it;
for (it = m_WeaponTraceVector.begin(); it != m_WeaponTraceVector.end(); ++it)
{
(*it)->SetTexture(szTextureName);
}
}
void CActorInstance::UseTextureWeaponTrace()
{
for_each(
m_WeaponTraceVector.begin(),
m_WeaponTraceVector.end(),
std::mem_fn(&CWeaponTrace::UseTexture)
);
}
void CActorInstance::UseAlphaWeaponTrace()
{
for_each(
m_WeaponTraceVector.begin(),
m_WeaponTraceVector.end(),
std::mem_fn(&CWeaponTrace::UseAlpha)
);
}
void CActorInstance::UpdateAttachingInstances()
{
CEffectManager& rkEftMgr=CEffectManager::Instance();
std::list<TAttachingEffect>::iterator it;
DWORD dwCurrentTime = CTimer::Instance().GetCurrentMillisecond();
for (it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();)
{
if (EFFECT_LIFE_WITH_MOTION == it->iLifeType)
{
++it;
continue;
}
if ((EFFECT_LIFE_NORMAL == it->iLifeType && it->dwEndTime < dwCurrentTime) ||
!rkEftMgr.IsAliveEffect(it->dwEffectIndex))
{
rkEftMgr.DestroyEffectInstance(it->dwEffectIndex);
it = m_AttachingEffectList.erase(it);
}
else
{
if (it->isAttaching)
{
rkEftMgr.SelectEffectInstance(it->dwEffectIndex);
if (it->iBoneIndex == -1)
{
D3DXMATRIX matTransform;
matTransform = it->matTranslation;
matTransform *= m_worldMatrix;
rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform);
}
else
{
D3DXMATRIX * pBoneMat;
if (GetBoneMatrix(it->dwModelIndex, it->iBoneIndex, &pBoneMat))
{
D3DXMATRIX matTransform;
matTransform = *pBoneMat;
matTransform *= it->matTranslation;
matTransform *= m_worldMatrix;
rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform);
}
else
{
//TraceError("GetBoneMatrix(modelIndex(%d), boneIndex(%d)).NOT_FOUND_BONE",
// it->dwModelIndex, it->iBoneIndex);
}
}
}
++it;
}
}
}
void CActorInstance::ShowAllAttachingEffect()
{
std::list<TAttachingEffect>::iterator it;
for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();++it)
{
CEffectManager::Instance().SelectEffectInstance(it->dwEffectIndex);
CEffectManager::Instance().ShowEffect();
}
}
void CActorInstance::HideAllAttachingEffect()
{
std::list<TAttachingEffect>::iterator it;
for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();++it)
{
CEffectManager::Instance().SelectEffectInstance(it->dwEffectIndex);
CEffectManager::Instance().HideEffect();
}
}
void CActorInstance::__ClearAttachingEffect()
{
m_bEffectInitialized = false;
std::list<TAttachingEffect>::iterator it;
for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();++it)
{
CEffectManager::Instance().DestroyEffectInstance(it->dwEffectIndex);
}
m_AttachingEffectList.clear();
}
@@ -0,0 +1,967 @@
#include "StdAfx.h"
#include "../EffectLib/EffectManager.h"
#include "../MilesLib/SoundManager.h"
#include "ActorInstance.h"
#include "RaceData.h"
void CActorInstance::SetBattleHitEffect(DWORD dwID)
{
m_dwBattleHitEffectID = dwID;
}
void CActorInstance::SetBattleAttachEffect(DWORD dwID)
{
m_dwBattleAttachEffectID = dwID;
}
bool CActorInstance::CanAct()
{
if (IsDead())
return false;
if (IsStun())
return false;
if (IsParalysis())
return false;
if (IsFaint())
return false;
if (IsSleep())
return false;
return true;
}
bool CActorInstance::CanUseSkill()
{
if (!CanAct())
return false;
DWORD dwCurMotionIndex=__GetCurrentMotionIndex();
// Locked during attack
switch (dwCurMotionIndex)
{
case CRaceMotionData::NAME_FISHING_THROW:
case CRaceMotionData::NAME_FISHING_WAIT:
case CRaceMotionData::NAME_FISHING_STOP:
case CRaceMotionData::NAME_FISHING_REACT:
case CRaceMotionData::NAME_FISHING_CATCH:
case CRaceMotionData::NAME_FISHING_FAIL:
return TRUE;
break;
}
// Locked during using skill
if (IsUsingSkill())
{
if (m_pkCurRaceMotionData->IsCancelEnableSkill())
return TRUE;
return FALSE;
}
return true;
}
bool CActorInstance::CanMove()
{
if (!CanAct())
return false;
if (isLock())
return false;
return true;
}
bool CActorInstance::CanAttack()
{
if (!CanAct())
return false;
if (IsUsingSkill())
{
if (!CanCancelSkill())
return false;
}
return true;
}
bool CActorInstance::CanFishing()
{
if (!CanAct())
return false;
if (IsUsingSkill())
return false;
switch (__GetCurrentMotionIndex())
{
case CRaceMotionData::NAME_WAIT:
case CRaceMotionData::NAME_WALK:
case CRaceMotionData::NAME_RUN:
break;
default:
return false;
break;
}
return true;
}
BOOL CActorInstance::IsClickableDistanceDestInstance(CActorInstance & rkInstDst, float fDistance)
{
TPixelPosition kPPosSrc;
GetPixelPosition(&kPPosSrc);
D3DXVECTOR3 kD3DVct3Src(kPPosSrc);
TCollisionPointInstanceList& rkLstkDefPtInst=rkInstDst.m_DefendingPointInstanceList;
TCollisionPointInstanceList::iterator i;
for (i=rkLstkDefPtInst.begin(); i!=rkLstkDefPtInst.end(); ++i)
{
CDynamicSphereInstanceVector& rkVctkDefSphere = (*i).SphereInstanceVector;
CDynamicSphereInstanceVector::iterator j;
for (j=rkVctkDefSphere.begin(); j!=rkVctkDefSphere.end(); ++j)
{
CDynamicSphereInstance& rkSphere=(*j);
const auto vv = D3DXVECTOR3(rkSphere.v3Position - kD3DVct3Src);
float fMovDistance=D3DXVec3Length(&vv);
float fAtkDistance=rkSphere.fRadius+fDistance;
if (fAtkDistance>fMovDistance)
return TRUE;
}
}
return FALSE;
}
void CActorInstance::InputNormalAttackCommand(float fDirRot)
{
if (!__CanInputNormalAttackCommand())
return;
m_fAtkDirRot=fDirRot;
NormalAttack(m_fAtkDirRot);
}
bool CActorInstance::InputComboAttackCommand(float fDirRot)
{
m_fAtkDirRot=fDirRot;
if (m_isPreInput)
return false;
/////////////////////////////////////////////////////////////////////////////////
// Process Input
if (0 == m_dwcurComboIndex)
{
__RunNextCombo();
return true;
}
else if (m_pkCurRaceMotionData->IsComboInputTimeData())
{
// 동작 경과 시간
float fElapsedTime = GetAttackingElapsedTime();
// 이미 입력 한계 시간이 지났다면..
if (fElapsedTime > m_pkCurRaceMotionData->GetComboInputEndTime())
{
//Tracen("입력 한계 시간 지남");
if (IsBowMode())
m_isNextPreInput = TRUE;
return false;
}
if (fElapsedTime > m_pkCurRaceMotionData->GetNextComboTime()) // 콤보 발동 시간 이 후라면
{
//Tracen("다음 콤보 동작");
// args : BlendingTime
__RunNextCombo();
return true;
}
else if (fElapsedTime > m_pkCurRaceMotionData->GetComboInputStartTime()) // 선 입력 시간 범위 라면..
{
//Tracen("선 입력 설정");
m_isPreInput = TRUE;
return false;
}
}
else
{
float fElapsedTime = GetAttackingElapsedTime();
if (fElapsedTime > m_pkCurRaceMotionData->GetMotionDuration()*0.9f) // 콤보 발동 시간 이 후라면
{
//Tracen("다음 콤보 동작");
// args : BlendingTime
__RunNextCombo();
return true;
}
}
// Process Input
return false;
}
void CActorInstance::ComboProcess()
{
// If combo is on action
if (0 != m_dwcurComboIndex)
{
if (!m_pkCurRaceMotionData)
{
Tracef("Attacking motion data is NULL! : %d\n", m_dwcurComboIndex);
__ClearCombo();
return;
}
float fElapsedTime = GetAttackingElapsedTime();
// Process PreInput
if (m_isPreInput)
{
//Tracenf("선입력 %f 다음콤보시간 %f", fElapsedTime, m_pkCurRaceMotionData->GetNextComboTime());
if (fElapsedTime > m_pkCurRaceMotionData->GetNextComboTime())
{
__RunNextCombo();
m_isPreInput = FALSE;
return;
}
}
}
else
{
m_isPreInput = FALSE;
if (!IsUsingSkill()) // m_isNextPreInput는 활모드 일때만 사용하는 변수
if (m_isNextPreInput) // 활일때만 스킬이 캔슬 되는건 이곳 때문임
{
__RunNextCombo();
m_isNextPreInput = FALSE;
}
}
}
void CActorInstance::__RunNextCombo()
{
++m_dwcurComboIndex;
///////////////////////////
WORD wComboIndex = m_dwcurComboIndex;
WORD wComboType = __GetCurrentComboType();
if (wComboIndex==0)
{
TraceError("CActorInstance::__RunNextCombo(wComboType=%d, wComboIndex=%d)", wComboType, wComboIndex);
return;
}
DWORD dwComboArrayIndex = wComboIndex - 1;
CRaceData::TComboData * pComboData;
if (!m_pkCurRaceData->GetComboDataPointer(m_wcurMotionMode, wComboType, &pComboData))
{
TraceError("CActorInstance::__RunNextCombo(wComboType=%d, wComboIndex=%d) - m_pkCurRaceData->GetComboDataPointer(m_wcurMotionMode=%d, &pComboData) == NULL",
wComboType, wComboIndex, m_wcurMotionMode);
return;
}
if (dwComboArrayIndex >= pComboData->ComboIndexVector.size())
{
TraceError("CActorInstance::__RunNextCombo(wComboType=%d, wComboIndex=%d) - (dwComboArrayIndex=%d) >= (pComboData->ComboIndexVector.size()=%d)",
wComboType, wComboIndex, dwComboArrayIndex, pComboData->ComboIndexVector.size());
return;
}
WORD wcurComboMotionIndex = pComboData->ComboIndexVector[dwComboArrayIndex];
ComboAttack(wcurComboMotionIndex, m_fAtkDirRot, 0.1f);
////////////////////////////////
// 콤보가 끝났다면
if (m_dwcurComboIndex == pComboData->ComboIndexVector.size())
{
__OnEndCombo();
}
}
void CActorInstance::__OnEndCombo()
{
if (__IsMountingHorse())
{
m_dwcurComboIndex = 1;
}
// 여기서 콤보를 초기화 해선 안된다.
// 콤보가 초기화 되는 곳은 마지막 콤보가 끝나고 Motion 이 자동으로 Wait 으로 돌아가는 시점이다.
}
void CActorInstance::__ClearCombo()
{
m_dwcurComboIndex = 0;
m_isPreInput = FALSE;
m_pkCurRaceMotionData = NULL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CActorInstance::isAttacking()
{
if (isNormalAttacking())
return TRUE;
if (isComboAttacking())
return TRUE;
if (IsSplashAttacking())
return TRUE;
return FALSE;
}
BOOL CActorInstance::isValidAttacking()
{
if (!m_pkCurRaceMotionData)
return FALSE;
if (!m_pkCurRaceMotionData->isAttackingMotion())
return FALSE;
const NRaceData::TMotionAttackData * c_pData = m_pkCurRaceMotionData->GetMotionAttackDataPointer();
float fElapsedTime = GetAttackingElapsedTime();
NRaceData::THitDataContainer::const_iterator itor = c_pData->HitDataContainer.begin();
for (; itor != c_pData->HitDataContainer.end(); ++itor)
{
const NRaceData::THitData & c_rHitData = *itor;
if (fElapsedTime > c_rHitData.fAttackStartTime &&
fElapsedTime < c_rHitData.fAttackEndTime)
return TRUE;
}
return TRUE;
}
BOOL CActorInstance::CanCheckAttacking()
{
if (isAttacking())
return true;
return false;
}
bool CActorInstance::__IsInSplashTime()
{
if (m_kSplashArea.fDisappearingTime>GetLocalTime())
return true;
return false;
}
BOOL CActorInstance::isNormalAttacking()
{
if (!m_pkCurRaceMotionData)
return FALSE;
if (!m_pkCurRaceMotionData->isAttackingMotion())
return FALSE;
const NRaceData::TMotionAttackData * c_pData = m_pkCurRaceMotionData->GetMotionAttackDataPointer();
if (NRaceData::MOTION_TYPE_NORMAL != c_pData->iMotionType)
return FALSE;
return TRUE;
}
BOOL CActorInstance::isComboAttacking()
{
if (!m_pkCurRaceMotionData)
return FALSE;
if (!m_pkCurRaceMotionData->isAttackingMotion())
return FALSE;
const NRaceData::TMotionAttackData * c_pData = m_pkCurRaceMotionData->GetMotionAttackDataPointer();
if (NRaceData::MOTION_TYPE_COMBO != c_pData->iMotionType)
return FALSE;
return TRUE;
}
BOOL CActorInstance::IsSplashAttacking()
{
if (!m_pkCurRaceMotionData)
return FALSE;
if (m_pkCurRaceMotionData->HasSplashMotionEvent())
return TRUE;
return FALSE;
}
BOOL CActorInstance::__IsMovingSkill(WORD wSkillNumber)
{
enum
{
HORSE_DASH_SKILL_NUMBER = 137,
};
return HORSE_DASH_SKILL_NUMBER == wSkillNumber;
}
BOOL CActorInstance::IsActEmotion()
{
DWORD dwCurMotionIndex=__GetCurrentMotionIndex();
switch (dwCurMotionIndex)
{
case CRaceMotionData::NAME_FRENCH_KISS_START+0:
case CRaceMotionData::NAME_FRENCH_KISS_START+1:
case CRaceMotionData::NAME_FRENCH_KISS_START+2:
case CRaceMotionData::NAME_FRENCH_KISS_START+3:
case CRaceMotionData::NAME_KISS_START+0:
case CRaceMotionData::NAME_KISS_START+1:
case CRaceMotionData::NAME_KISS_START+2:
case CRaceMotionData::NAME_KISS_START+3:
return TRUE;
break;
}
return FALSE;
}
BOOL CActorInstance::IsUsingMovingSkill()
{
return __IsMovingSkill(m_kCurMotNode.uSkill);
}
DWORD CActorInstance::GetComboIndex()
{
return m_dwcurComboIndex;
}
float CActorInstance::GetAttackingElapsedTime()
{
return (GetLocalTime() - m_kCurMotNode.fStartTime) * m_kCurMotNode.fSpeedRatio;
// return (GetLocalTime() - m_kCurMotNode.fStartTime) * __GetAttackSpeed();
}
bool CActorInstance::__CanInputNormalAttackCommand()
{
if (IsWaiting())
return true;
if (isNormalAttacking())
{
float fElapsedTime = GetAttackingElapsedTime();
if (fElapsedTime > m_pkCurRaceMotionData->GetMotionDuration()*0.9f)
return true;
}
return false;
}
BOOL CActorInstance::NormalAttack(float fDirRot, float fBlendTime)
{
WORD wMotionIndex;
if (!m_pkCurRaceData->GetNormalAttackIndex(m_wcurMotionMode, &wMotionIndex))
return FALSE;
BlendRotation(fDirRot, fBlendTime);
SetAdvancingRotation(fDirRot);
InterceptOnceMotion(wMotionIndex, 0.1f, 0, __GetAttackSpeed());
__OnAttack(wMotionIndex);
NEW_SetAtkPixelPosition(NEW_GetCurPixelPositionRef());
return TRUE;
}
BOOL CActorInstance::ComboAttack(DWORD dwMotionIndex, float fDirRot, float fBlendTime)
{
BlendRotation(fDirRot, fBlendTime);
SetAdvancingRotation(fDirRot);
InterceptOnceMotion(dwMotionIndex, fBlendTime, 0, __GetAttackSpeed());
__OnAttack(dwMotionIndex);
NEW_SetAtkPixelPosition(NEW_GetCurPixelPositionRef());
return TRUE;
}
void CActorInstance::__ProcessMotionEventAttackSuccess(DWORD dwMotionKey, BYTE byEventIndex, CActorInstance & rVictim)
{
CRaceMotionData * pMotionData;
if (!m_pkCurRaceData->GetMotionDataPointer(dwMotionKey, &pMotionData))
return;
if (byEventIndex >= pMotionData->GetMotionEventDataCount())
return;
const CRaceMotionData::TMotionAttackingEventData * pMotionEventData;
if (!pMotionData->GetMotionAttackingEventDataPointer(byEventIndex, &pMotionEventData))
return;
const D3DXVECTOR3& c_rv3VictimPos=rVictim.GetPositionVectorRef();
__ProcessDataAttackSuccess(pMotionEventData->AttackData, rVictim, c_rv3VictimPos);
}
void CActorInstance::__ProcessMotionAttackSuccess(DWORD dwMotionKey, CActorInstance & rVictim)
{
CRaceMotionData * c_pMotionData;
if (!m_pkCurRaceData->GetMotionDataPointer(dwMotionKey, &c_pMotionData))
return;
const D3DXVECTOR3& c_rv3VictimPos=rVictim.GetPositionVectorRef();
__ProcessDataAttackSuccess(c_pMotionData->GetMotionAttackDataReference(), rVictim, c_rv3VictimPos);
}
DWORD CActorInstance::__GetOwnerVID()
{
return m_dwOwnerVID;
}
float CActorInstance::__GetOwnerTime()
{
return GetLocalTime()-m_fOwnerBaseTime;
}
bool IS_HUGE_RACE(unsigned int vnum)
{
switch (vnum)
{
case 2493:
return true;
}
return false;
}
bool CActorInstance::__CanPushDestActor(CActorInstance& rkActorDst)
{
if (rkActorDst.IsBuilding())
return false;
if (rkActorDst.IsDoor())
return false;
if (rkActorDst.IsStone())
return false;
if (rkActorDst.IsNPC())
return false;
// 거대 몬스터 밀림 제외
extern bool IS_HUGE_RACE(unsigned int vnum);
if (IS_HUGE_RACE(rkActorDst.GetRace()))
return false;
if (rkActorDst.IsStun())
return true;
if (rkActorDst.__GetOwnerVID()!=GetVirtualID())
return false;
if (rkActorDst.__GetOwnerTime()>3.0f)
return false;
return true;
}
bool IS_PARTY_HUNTING_RACE(unsigned int vnum)
{
return true;
// 모든 몬스터 파티 사냥 적용
/*
if (vnum < 8) // 플레이어
return true;
if (vnum >= 8000 && vnum <= 8112) // 메틴석
return true;
if (vnum >= 2400 && vnum < 5000) // 천의 동굴 이후 몬스터
return true;
return false;
*/
}
void CActorInstance::__ProcessDataAttackSuccess(const NRaceData::TAttackData & c_rAttackData, CActorInstance & rVictim, const D3DXVECTOR3 & c_rv3Position, UINT uiSkill, BOOL isSendPacket)
{
if (NRaceData::HIT_TYPE_NONE == c_rAttackData.iHittingType)
return;
InsertDelay(c_rAttackData.fStiffenTime);
if (__CanPushDestActor(rVictim) && c_rAttackData.fExternalForce > 0.0f)
{
__PushCircle(rVictim);
// VICTIM_COLLISION_TEST
const D3DXVECTOR3& kVictimPos = rVictim.GetPosition();
rVictim.m_PhysicsObject.IncreaseExternalForce(kVictimPos, c_rAttackData.fExternalForce); //*nForceRatio/100.0f);
// VICTIM_COLLISION_TEST_END
}
// Invisible Time
if (IS_PARTY_HUNTING_RACE(rVictim.GetRace()))
{
if (uiSkill) // 파티 사냥 몬스터라도 스킬이면 무적시간 적용
rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime;
if (m_isMain) // #0000794: [M2KR] 폴리모프 - 밸런싱 문제 타인 공격에 의한 무적 타임은 고려하지 않고 자신 공격에 의한것만 체크한다
rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime;
}
else // 파티 사냥 몬스터가 아닐 경우만 적용
{
rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime;
}
// Stiffen Time
rVictim.InsertDelay(c_rAttackData.fStiffenTime);
// Hit Effect
D3DXVECTOR3 vec3Effect(rVictim.m_x, rVictim.m_y, rVictim.m_z);
// #0000780: [M2KR] 수룡 타격구 문제
extern bool IS_HUGE_RACE(unsigned int vnum);
if (IS_HUGE_RACE(rVictim.GetRace()))
{
vec3Effect = c_rv3Position;
}
const D3DXVECTOR3 & v3Pos = GetPosition();
float fHeight = D3DXToDegree(atan2(-vec3Effect.x + v3Pos.x,+vec3Effect.y - v3Pos.y));
// 2004.08.03.myevan.빌딩이나 문의 경우 타격 효과가 보이지 않는다
if (rVictim.IsBuilding()||rVictim.IsDoor())
{
D3DXVECTOR3 vec3Delta=vec3Effect-v3Pos;
D3DXVec3Normalize(&vec3Delta, &vec3Delta);
vec3Delta*=30.0f;
CEffectManager& rkEftMgr=CEffectManager::Instance();
if (m_dwBattleHitEffectID)
rkEftMgr.CreateEffect(m_dwBattleHitEffectID, v3Pos+vec3Delta, D3DXVECTOR3(0.0f, 0.0f, 0.0f));
}
else
{
CEffectManager& rkEftMgr=CEffectManager::Instance();
if (m_dwBattleHitEffectID)
rkEftMgr.CreateEffect(m_dwBattleHitEffectID, vec3Effect, D3DXVECTOR3(0.0f, 0.0f, fHeight));
if (m_dwBattleAttachEffectID)
rVictim.AttachEffectByID(0, NULL, m_dwBattleAttachEffectID);
}
if (rVictim.IsBuilding())
{
// 2004.08.03.빌딩의 경우 흔들리면 이상하다
}
else if (rVictim.IsStone() || rVictim.IsDoor())
{
__HitStone(rVictim);
}
else
{
///////////
// Motion
if (NRaceData::HIT_TYPE_GOOD == c_rAttackData.iHittingType || rVictim.IsResistFallen())
{
__HitGood(rVictim);
}
else if (NRaceData::HIT_TYPE_GREAT == c_rAttackData.iHittingType)
{
__HitGreate(rVictim);
}
else
{
TraceError("ProcessSucceedingAttacking: Unknown AttackingData.iHittingType %d", c_rAttackData.iHittingType);
}
}
__OnHit(uiSkill, rVictim, isSendPacket);
}
void CActorInstance::OnShootDamage()
{
if (IsStun())
{
Die();
}
else
{
__Shake(100);
if (!isLock() && !__IsKnockDownMotion() && !__IsStandUpMotion())
{
if (InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE))
PushLoopMotion(CRaceMotionData::NAME_WAIT);
}
}
}
void CActorInstance::__Shake(DWORD dwDuration)
{
DWORD dwCurTime=ELTimer_GetMSec();
m_dwShakeTime=dwCurTime+dwDuration;
}
void CActorInstance::ShakeProcess()
{
if (m_dwShakeTime)
{
D3DXVECTOR3 v3Pos(0.0f, 0.0f, 0.0f);
DWORD dwCurTime=ELTimer_GetMSec();
if (m_dwShakeTime<dwCurTime)
{
m_dwShakeTime=0;
}
else
{
int nShakeSize=10;
switch (rand()%2)
{
case 0:v3Pos.x+=rand()%nShakeSize;break;
case 1:v3Pos.x-=rand()%nShakeSize;break;
}
switch (rand()%2)
{
case 0:v3Pos.y+=rand()%nShakeSize;break;
case 1:v3Pos.y-=rand()%nShakeSize;break;
}
switch (rand()%2)
{
case 0:v3Pos.z+=rand()%nShakeSize;break;
case 1:v3Pos.z-=rand()%nShakeSize;break;
}
}
m_worldMatrix._41 += v3Pos.x;
m_worldMatrix._42 += v3Pos.y;
m_worldMatrix._43 += v3Pos.z;
}
}
void CActorInstance::__HitStone(CActorInstance& rVictim)
{
if (rVictim.IsStun())
{
rVictim.Die();
}
else
{
rVictim.__Shake(100);
}
}
void CActorInstance::__HitGood(CActorInstance& rVictim)
{
if (rVictim.IsKnockDown())
return;
if (rVictim.IsStun())
{
rVictim.Die();
}
else
{
rVictim.__Shake(100);
if (!rVictim.isLock())
{
float fRotRad = D3DXToRadian(GetRotation());
float fVictimRotRad = D3DXToRadian(rVictim.GetRotation());
D3DXVECTOR2 v2Normal(sin(fRotRad), cos(fRotRad));
D3DXVECTOR2 v2VictimNormal(sin(fVictimRotRad), cos(fVictimRotRad));
D3DXVec2Normalize(&v2Normal, &v2Normal);
D3DXVec2Normalize(&v2VictimNormal, &v2VictimNormal);
float fScalar = D3DXVec2Dot(&v2Normal, &v2VictimNormal);
if (fScalar < 0.0f)
{
if (rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE))
rVictim.PushLoopMotion(CRaceMotionData::NAME_WAIT);
}
else
{
if (rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_BACK))
rVictim.PushLoopMotion(CRaceMotionData::NAME_WAIT);
else if (rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE))
rVictim.PushLoopMotion(CRaceMotionData::NAME_WAIT);
}
}
}
}
void CActorInstance::__HitGreate(CActorInstance& rVictim)
{
// DISABLE_KNOCKDOWN_ATTACK
if (rVictim.IsKnockDown())
return;
if (rVictim.__IsStandUpMotion())
return;
// END_OF_DISABLE_KNOCKDOWN_ATTACK
float fRotRad = D3DXToRadian(GetRotation());
float fVictimRotRad = D3DXToRadian(rVictim.GetRotation());
D3DXVECTOR2 v2Normal(sin(fRotRad), cos(fRotRad));
D3DXVECTOR2 v2VictimNormal(sin(fVictimRotRad), cos(fVictimRotRad));
D3DXVec2Normalize(&v2Normal, &v2Normal);
D3DXVec2Normalize(&v2VictimNormal, &v2VictimNormal);
float fScalar = D3DXVec2Dot(&v2Normal, &v2VictimNormal);
rVictim.__Shake(100);
if (rVictim.IsUsingSkill())
return;
if (rVictim.IsStun())
{
if (fScalar < 0.0f)
rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING);
else
{
if (!rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING_BACK))
rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING);
}
rVictim.m_isRealDead=true;
}
else
{
if (fScalar < 0.0f)
{
if (rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING))
{
rVictim.PushOnceMotion(CRaceMotionData::NAME_STAND_UP);
rVictim.PushLoopMotion(CRaceMotionData::NAME_WAIT);
}
}
else
{
if (!rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING_BACK))
{
if (rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING))
{
rVictim.PushOnceMotion(CRaceMotionData::NAME_STAND_UP);
rVictim.PushLoopMotion(CRaceMotionData::NAME_WAIT);
}
}
else
{
rVictim.PushOnceMotion(CRaceMotionData::NAME_STAND_UP_BACK);
rVictim.PushLoopMotion(CRaceMotionData::NAME_WAIT);
}
}
}
}
void CActorInstance::SetBlendingPosition(const TPixelPosition & c_rPosition, float fBlendingTime)
{
//return;
TPixelPosition Position;
Position.x = c_rPosition.x - m_x;
Position.y = c_rPosition.y - m_y;
Position.z = 0;
m_PhysicsObject.SetLastPosition(Position, fBlendingTime);
}
void CActorInstance::ResetBlendingPosition()
{
m_PhysicsObject.Initialize();
}
void CActorInstance::GetBlendingPosition(TPixelPosition * pPosition)
{
if (m_PhysicsObject.isBlending())
{
m_PhysicsObject.GetLastPosition(pPosition);
pPosition->x += m_x;
pPosition->y += m_y;
pPosition->z += m_z;
}
else
{
pPosition->x = m_x;
pPosition->y = m_y;
pPosition->z = m_z;
}
}
void CActorInstance::__PushCircle(CActorInstance & rVictim)
{
const TPixelPosition& c_rkPPosAtk=NEW_GetAtkPixelPositionRef();
D3DXVECTOR3 v3SrcPos(c_rkPPosAtk.x, -c_rkPPosAtk.y, c_rkPPosAtk.z);
const D3DXVECTOR3& c_rv3SrcPos = v3SrcPos;
const D3DXVECTOR3& c_rv3DstPos = rVictim.GetPosition();
D3DXVECTOR3 v3Direction;
v3Direction.x = c_rv3DstPos.x - c_rv3SrcPos.x;
v3Direction.y = c_rv3DstPos.y - c_rv3SrcPos.y;
v3Direction.z = 0.0f;
D3DXVec3Normalize(&v3Direction, &v3Direction);
rVictim.__SetFallingDirection(v3Direction.x, v3Direction.y);
}
void CActorInstance::__PushDirect(CActorInstance & rVictim)
{
D3DXVECTOR3 v3Direction;
v3Direction.x = cosf(D3DXToRadian(m_fcurRotation + 270.0f));
v3Direction.y = sinf(D3DXToRadian(m_fcurRotation + 270.0f));
v3Direction.z = 0.0f;
rVictim.__SetFallingDirection(v3Direction.x, v3Direction.y);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CActorInstance::__isInvisible()
{
if (IsDead())
return true;
if (CTimer::Instance().GetCurrentSecond() >= m_fInvisibleTime)
return false;
return true;
}
void CActorInstance::__SetFallingDirection(float fx, float fy)
{
m_PhysicsObject.SetDirection(D3DXVECTOR3(fx, fy, 0.0f));
}
@@ -0,0 +1,83 @@
#include "StdAfx.h"
#include "ActorInstance.h"
void CActorInstance::BlendAlphaValue(float fDstAlpha, float fDuration)
{
__BlendAlpha_Apply(fDstAlpha, fDuration);
}
void CActorInstance::SetBlendRenderMode()
{
m_iRenderMode = RENDER_MODE_BLEND;
}
void CActorInstance::SetAlphaValue(float fAlpha)
{
m_fAlphaValue = fAlpha;
}
float CActorInstance::GetAlphaValue()
{
return m_fAlphaValue;
}
void CActorInstance::__BlendAlpha_Initialize()
{
m_kBlendAlpha.m_isBlending=false;
m_kBlendAlpha.m_fBaseTime=0.0f;
m_kBlendAlpha.m_fDuration=0.0f;
m_kBlendAlpha.m_fBaseAlpha=0.0f;
m_kBlendAlpha.m_fDstAlpha=0.0f;
m_kBlendAlpha.m_iOldRenderMode=RENDER_MODE_NORMAL;
}
void CActorInstance::__BlendAlpha_Apply(float fDstAlpha, float fDuration)
{
m_kBlendAlpha.m_isBlending=true;
m_kBlendAlpha.m_fBaseAlpha=GetAlphaValue();
m_kBlendAlpha.m_fBaseTime=GetLocalTime();
m_kBlendAlpha.m_fDuration=fDuration;
m_kBlendAlpha.m_fDstAlpha=fDstAlpha;
m_kBlendAlpha.m_iOldRenderMode=m_iRenderMode;
}
void CActorInstance::__BlendAlpha_Update()
{
if (!m_kBlendAlpha.m_isBlending)
return;
float fElapsedTime=__BlendAlpha_GetElapsedTime();
if (fElapsedTime<m_kBlendAlpha.m_fDuration)
{
float fCurAlpha=m_kBlendAlpha.m_fBaseAlpha+(m_kBlendAlpha.m_fDstAlpha-m_kBlendAlpha.m_fBaseAlpha)*fElapsedTime/m_kBlendAlpha.m_fDuration;
SetBlendRenderMode();
SetAlphaValue(fCurAlpha);
}
else
{
if (1.0f>m_kBlendAlpha.m_fDstAlpha)
{
SetBlendRenderMode();
}
else
{
m_iRenderMode=m_kBlendAlpha.m_iOldRenderMode;
}
SetAlphaValue(m_kBlendAlpha.m_fDstAlpha);
__BlendAlpha_UpdateComplete();
}
}
void CActorInstance::__BlendAlpha_UpdateComplete()
{
m_kBlendAlpha.m_isBlending=false;
}
float CActorInstance::__BlendAlpha_GetElapsedTime()
{
float fCurTime=GetLocalTime();
return fCurTime-m_kBlendAlpha.m_fBaseTime;
}
@@ -0,0 +1,744 @@
#include "StdAfx.h"
#include "../EterLib/GrpMath.h"
#include "ActorInstance.h"
void CActorInstance::__InitializeCollisionData()
{
m_canSkipCollision=false;
}
void CActorInstance::EnableSkipCollision()
{
m_canSkipCollision=true;
}
void CActorInstance::DisableSkipCollision()
{
m_canSkipCollision=false;
}
bool CActorInstance::CanSkipCollision()
{
return m_canSkipCollision;
}
void CActorInstance::UpdatePointInstance()
{
TCollisionPointInstanceListIterator itor;
for (itor = m_DefendingPointInstanceList.begin(); itor != m_DefendingPointInstanceList.end(); ++itor)
UpdatePointInstance(&(*itor));
}
void CActorInstance::UpdatePointInstance(TCollisionPointInstance * pPointInstance)
{
if (!pPointInstance)
{
assert(!"CActorInstance::UpdatePointInstance - pPointInstance is NULL"); // 레퍼런스로 교체하시오
return;
}
D3DXMATRIX matBone;
if (pPointInstance->isAttached)
{
if (pPointInstance->dwModelIndex>=m_LODControllerVector.size())
{
//Tracenf("CActorInstance::UpdatePointInstance - rInstance.dwModelIndex=%d >= m_LODControllerVector.size()=%d",
// pPointInstance->dwModelIndex>m_LODControllerVector.size());
return;
}
CGrannyLODController* pGrnLODController=m_LODControllerVector[pPointInstance->dwModelIndex];
if (!pGrnLODController)
{
//Tracenf("CActorInstance::UpdatePointInstance - m_LODControllerVector[pPointInstance->dwModelIndex=%d] is NULL", pPointInstance->dwModelIndex);
return;
}
CGrannyModelInstance * pModelInstance = pGrnLODController->GetModelInstance();
if (!pModelInstance)
{
//Tracenf("CActorInstance::UpdatePointInstance - pGrnLODController->GetModelInstance() is NULL");
return;
}
D3DXMATRIX * pmatBone = (D3DXMATRIX *)pModelInstance->GetBoneMatrixPointer(pPointInstance->dwBoneIndex);
matBone = *(D3DXMATRIX *)pModelInstance->GetCompositeBoneMatrixPointer(pPointInstance->dwBoneIndex);
matBone._41 = pmatBone->_41;
matBone._42 = pmatBone->_42;
matBone._43 = pmatBone->_43;
matBone *= m_worldMatrix;
}
else
{
matBone = m_worldMatrix;
}
// Update Collsion Sphere
CSphereCollisionInstanceVector::const_iterator sit = pPointInstance->c_pCollisionData->SphereDataVector.begin();
CDynamicSphereInstanceVector::iterator dit=pPointInstance->SphereInstanceVector.begin();
for (;sit!=pPointInstance->c_pCollisionData->SphereDataVector.end();++sit,++dit)
{
const TSphereData & c = sit->GetAttribute();//c_pCollisionData->SphereDataVector[j].GetAttribute();
D3DXMATRIX matPoint;
D3DXMatrixTranslation(&matPoint, c.v3Position.x, c.v3Position.y, c.v3Position.z);
matPoint = matPoint * matBone;
dit->v3LastPosition = dit->v3Position;
dit->v3Position.x = matPoint._41;
dit->v3Position.y = matPoint._42;
dit->v3Position.z = matPoint._43;
}
}
void CActorInstance::UpdateAdvancingPointInstance()
{
// 말을 탔을 경우 사람은 이동값을 가지고 있지 않기 때문에 말로 부터 얻어와야 한다 - [levites]
D3DXVECTOR3 v3Movement = m_v3Movement;
if (m_pkHorse)
v3Movement = m_pkHorse->m_v3Movement;
// 말은 업데이트 하지 않아도 된다 - [levites]
if (m_pkHorse)
m_pkHorse->UpdateAdvancingPointInstance();
D3DXMATRIX matPoint;
D3DXMATRIX matCenter;
TCollisionPointInstanceListIterator itor = m_BodyPointInstanceList.begin();
for (; itor != m_BodyPointInstanceList.end(); ++itor)
{
TCollisionPointInstance & rInstance = *itor;
if (rInstance.isAttached)
{
if (rInstance.dwModelIndex>=m_LODControllerVector.size())
{
Tracenf("CActorInstance::UpdateAdvancingPointInstance - rInstance.dwModelIndex=%d >= m_LODControllerVector.size()=%d",
rInstance.dwModelIndex, m_LODControllerVector.size());
continue;
}
CGrannyLODController* pGrnLODController=m_LODControllerVector[rInstance.dwModelIndex];
if (!pGrnLODController)
{
Tracenf("CActorInstance::UpdateAdvancingPointInstance - m_LODControllerVector[rInstance.dwModelIndex=%d] is NULL", rInstance.dwModelIndex);
continue;
}
CGrannyModelInstance * pModelInstance = pGrnLODController->GetModelInstance();
if (!pModelInstance)
{
//Tracenf("CActorInstance::UpdateAdvancingPointInstance - pGrnLODController->GetModelInstance() is NULL");
continue;
}
matCenter = *(D3DXMATRIX *)pModelInstance->GetBoneMatrixPointer(rInstance.dwBoneIndex);
matCenter *= m_worldMatrix;
}
else
{
matCenter = m_worldMatrix;
}
// Update Collision Sphere
const NRaceData::TCollisionData * c_pCollisionData = rInstance.c_pCollisionData;
if (c_pCollisionData)
{
for (DWORD j = 0; j < c_pCollisionData->SphereDataVector.size(); ++j)
{
const TSphereData & c = c_pCollisionData->SphereDataVector[j].GetAttribute();
CDynamicSphereInstance & rSphereInstance = rInstance.SphereInstanceVector[j];
D3DXMatrixTranslation(&matPoint, c.v3Position.x, c.v3Position.y, c.v3Position.z);
matPoint = matPoint * matCenter;
rSphereInstance.v3LastPosition.x = matPoint._41;
rSphereInstance.v3LastPosition.y = matPoint._42;
rSphereInstance.v3LastPosition.z = matPoint._43;
rSphereInstance.v3Position = rSphereInstance.v3LastPosition;
rSphereInstance.v3Position += v3Movement;
}
}
}
}
bool CActorInstance::CheckCollisionDetection(const CDynamicSphereInstanceVector * c_pAttackingSphereVector, D3DXVECTOR3 * pv3Position)
{
if (!c_pAttackingSphereVector)
{
assert(!"CActorInstance::CheckCollisionDetection - c_pAttackingSphereVector is NULL"); // 레퍼런스로 교체하시오
return false;
}
TCollisionPointInstanceListIterator itor;
for (itor = m_DefendingPointInstanceList.begin(); itor != m_DefendingPointInstanceList.end(); ++itor)
{
const CDynamicSphereInstanceVector * c_pDefendingSphereVector = &(*itor).SphereInstanceVector;
for (DWORD i = 0; i < c_pAttackingSphereVector->size(); ++i)
for (DWORD j = 0; j < c_pDefendingSphereVector->size(); ++j)
{
const CDynamicSphereInstance & c_rAttackingSphere = c_pAttackingSphereVector->at(i);
const CDynamicSphereInstance & c_rDefendingSphere = c_pDefendingSphereVector->at(j);
if (DetectCollisionDynamicSphereVSDynamicSphere(c_rAttackingSphere, c_rDefendingSphere))
{
// FIXME : 두 원의 교점을 찾아내는 식으로 바꿔야 한다.
*pv3Position = (c_rAttackingSphere.v3Position + c_rDefendingSphere.v3Position) / 2.0f;
return true;
}
}
}
return false;
}
bool CActorInstance::CreateCollisionInstancePiece(DWORD dwAttachingModelIndex, const NRaceData::TAttachingData * c_pAttachingData, TCollisionPointInstance * pPointInstance)
{
if (!c_pAttachingData)
{
assert(!"CActorInstance::CreateCollisionInstancePiece - c_pAttachingData is NULL"); // 레퍼런스로 교체하시오
return false;
}
if (!c_pAttachingData->pCollisionData)
{
assert(!"CActorInstance::CreateCollisionInstancePiece - c_pAttachingData->pCollisionData is NULL"); // 레퍼런스로 교체하시오
return false;
}
if (!pPointInstance)
{
assert(!"CActorInstance::CreateCollisionInstancePiece - pPointInstance is NULL"); // 레퍼런스로 교체하시오
return false;
}
pPointInstance->dwModelIndex = dwAttachingModelIndex;
pPointInstance->isAttached = FALSE;
pPointInstance->dwBoneIndex = 0;
pPointInstance->c_pCollisionData = c_pAttachingData->pCollisionData;
if (c_pAttachingData->isAttaching)
{
int iAttachingBoneIndex;
CGrannyModelInstance * pModelInstance = m_LODControllerVector[dwAttachingModelIndex]->GetModelInstance();
if (pModelInstance && pModelInstance->GetBoneIndexByName(c_pAttachingData->strAttachingBoneName.c_str(),
&iAttachingBoneIndex))
{
pPointInstance->isAttached = TRUE;
pPointInstance->dwBoneIndex = iAttachingBoneIndex;
}
else
{
//TraceError("CActorInstance::CreateCollisionInstancePiece: Cannot get matrix of bone %s ModelInstance 0x%p", c_pAttachingData->strAttachingBoneName.c_str(), pModelInstance);
pPointInstance->isAttached = TRUE;
pPointInstance->dwBoneIndex = 0;
}
}
const CSphereCollisionInstanceVector & c_rSphereDataVector = c_pAttachingData->pCollisionData->SphereDataVector;
pPointInstance->SphereInstanceVector.clear();
pPointInstance->SphereInstanceVector.reserve(c_rSphereDataVector.size());
CSphereCollisionInstanceVector::const_iterator it;
CDynamicSphereInstance dsi;
dsi.v3LastPosition = D3DXVECTOR3(0.0f,0.0f,0.0f);
dsi.v3Position = D3DXVECTOR3(0.0f,0.0f,0.0f);
for (it = c_rSphereDataVector.begin(); it!=c_rSphereDataVector.end(); ++it)
{
const TSphereData & c_rSphereData = it->GetAttribute();
dsi.fRadius = c_rSphereData.fRadius;
pPointInstance->SphereInstanceVector.push_back(dsi);
}
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CActorInstance::__SplashAttackProcess(CActorInstance & rVictim)
{
D3DXVECTOR3 v3Distance(rVictim.m_x - m_x, rVictim.m_z - m_z, rVictim.m_z - m_z);
float fDistance = D3DXVec3LengthSq(&v3Distance);
if (fDistance >= 1000.0f*1000.0f)
return FALSE;
// Check Distance
if (!__IsInSplashTime())
return FALSE;
const CRaceMotionData::TMotionAttackingEventData * c_pAttackingEvent = m_kSplashArea.c_pAttackingEvent;
const NRaceData::TAttackData & c_rAttackData = c_pAttackingEvent->AttackData;
THittedInstanceMap & rHittedInstanceMap = m_kSplashArea.HittedInstanceMap;
// NOTE : 이미 때렸다면 때릴 수 없음
if (rHittedInstanceMap.end() != rHittedInstanceMap.find(&rVictim))
{
return FALSE;
}
// NOTE : Snipe 모드이고..
if (NRaceData::ATTACK_TYPE_SNIPE == c_rAttackData.iAttackType)
{
// Target 이 PC 라면..
if (__IsFlyTargetPC())
// 다른 객체는 때릴 수 없다
if (!__IsSameFlyTarget(&rVictim))
return FALSE;
/*
if (IsFlyTargetObject())
{
CActorInstance * pActorInstance = (CActorInstance *)m_kFlyTarget.GetFlyTarget();
// NOTE : Target 이 PC 일때는 한명만 때릴 수 있다.
if (pActorInstance->IsPC())
if (&rVictim != pActorInstance)
return FALSE;
}
*/
}
D3DXVECTOR3 v3HitPosition;
if (rVictim.CheckCollisionDetection(&m_kSplashArea.SphereInstanceVector, &v3HitPosition))
{
rHittedInstanceMap.insert(std::make_pair(&rVictim, GetLocalTime()+c_rAttackData.fInvisibleTime));
int iCurrentHitCount = rHittedInstanceMap.size();
int iMaxHitCount = (0 == c_rAttackData.iHitLimitCount ? 16 : c_rAttackData.iHitLimitCount);
//Tracef(" ------------------- Splash Hit : %d\n", iCurrentHitCount);
if (iCurrentHitCount > iMaxHitCount)
{
//Tracef(" ------------------- OVER FLOW :: Splash Hit Count : %d\n", iCurrentHitCount);
return FALSE;
}
NEW_SetAtkPixelPosition(NEW_GetCurPixelPositionRef());
__ProcessDataAttackSuccess(c_rAttackData, rVictim, v3HitPosition, m_kSplashArea.uSkill, m_kSplashArea.isEnableHitProcess);
return TRUE;
}
return FALSE;
}
BOOL CActorInstance::__NormalAttackProcess(CActorInstance & rVictim)
{
// Check Distance
// NOTE - 일단 근접 체크만 하고 있음
D3DXVECTOR3 v3Distance(rVictim.m_x - m_x, rVictim.m_z - m_z, rVictim.m_z - m_z);
float fDistance = D3DXVec3LengthSq(&v3Distance);
extern bool IS_HUGE_RACE(unsigned int vnum);
if (IS_HUGE_RACE(rVictim.GetRace()))
{
if (fDistance >= 500.0f*500.0f)
return FALSE;
}
else
{
if (fDistance >= 300.0f*300.0f)
return FALSE;
}
if (!isValidAttacking())
return FALSE;
const float c_fAttackRadius = 20.0f;
const NRaceData::TMotionAttackData * pad = m_pkCurRaceMotionData->GetMotionAttackDataPointer();
const float motiontime = GetAttackingElapsedTime();
NRaceData::THitDataContainer::const_iterator itorHitData = pad->HitDataContainer.begin();
for (; itorHitData != pad->HitDataContainer.end(); ++itorHitData)
{
const NRaceData::THitData & c_rHitData = *itorHitData;
// NOTE : 이미 맞았는지 체크
THitDataMap::iterator itHitData = m_HitDataMap.find(&c_rHitData);
if (itHitData != m_HitDataMap.end())
{
THittedInstanceMap & rHittedInstanceMap = itHitData->second;
THittedInstanceMap::iterator itInstance;
if ((itInstance=rHittedInstanceMap.find(&rVictim)) != rHittedInstanceMap.end())
{
if (pad->iMotionType==NRaceData::MOTION_TYPE_COMBO || itInstance->second > GetLocalTime())
continue;
}
}
NRaceData::THitTimePositionMap::const_iterator range_start, range_end;
range_start = c_rHitData.mapHitPosition.lower_bound(motiontime-CTimer::Instance().GetElapsedSecond());
range_end = c_rHitData.mapHitPosition.upper_bound(motiontime);
float c = cosf(D3DXToRadian(GetRotation()));
float s = sinf(D3DXToRadian(GetRotation()));
for(;range_start!=range_end;++range_start)
{
const CDynamicSphereInstance& dsiSrc=range_start->second;
CDynamicSphereInstance dsi;
dsi = dsiSrc;
dsi.fRadius = c_fAttackRadius;
{
D3DXVECTOR3 v3SrcDir=dsiSrc.v3Position-dsiSrc.v3LastPosition;
v3SrcDir*=__GetReachScale();
const D3DXVECTOR3& v3Src = dsiSrc.v3LastPosition+v3SrcDir;
D3DXVECTOR3& v3Dst = dsi.v3Position;
v3Dst.x = v3Src.x * c - v3Src.y * s;
v3Dst.y = v3Src.x * s + v3Src.y * c;
v3Dst += GetPosition();
}
{
const D3DXVECTOR3& v3Src = dsiSrc.v3LastPosition;
D3DXVECTOR3& v3Dst = dsi.v3LastPosition;
v3Dst.x = v3Src.x * c - v3Src.y * s;
v3Dst.y = v3Src.x * s + v3Src.y * c;
v3Dst += GetPosition();
}
TCollisionPointInstanceList::iterator cpit;
for(cpit = rVictim.m_DefendingPointInstanceList.begin(); cpit!=rVictim.m_DefendingPointInstanceList.end();++cpit)
{
int index = 0;
const CDynamicSphereInstanceVector & c_DefendingSphereVector = cpit->SphereInstanceVector;
CDynamicSphereInstanceVector::const_iterator dsit;
for(dsit = c_DefendingSphereVector.begin(); dsit!= c_DefendingSphereVector.end();++dsit, ++index)
{
const CDynamicSphereInstance& sub = *dsit;
if (DetectCollisionDynamicZCylinderVSDynamicZCylinder(dsi, sub))
{
THitDataMap::iterator itHitData = m_HitDataMap.find(&c_rHitData);
if (itHitData == m_HitDataMap.end())
{
THittedInstanceMap HittedInstanceMap;
HittedInstanceMap.insert(std::make_pair(&rVictim, GetLocalTime()+pad->fInvisibleTime));
//HittedInstanceMap.insert(std::make_pair(&rVictim, GetLocalTime()+HIT_COOL_TIME));
m_HitDataMap.insert(std::make_pair(&c_rHitData, HittedInstanceMap));
//Tracef(" ----------- First Hit\n");
}
else
{
itHitData->second.insert(std::make_pair(&rVictim, GetLocalTime()+pad->fInvisibleTime));
//itHitData->second.insert(std::make_pair(&rVictim, GetLocalTime()+HIT_COOL_TIME));
//Tracef(" ----------- Next Hit : %d\n", itHitData->second.size());
int iCurrentHitCount = itHitData->second.size();
// NOTE : 보통 공격은 16명이 한계
if (NRaceData::MOTION_TYPE_COMBO == pad->iMotionType || NRaceData::MOTION_TYPE_NORMAL == pad->iMotionType)
{
if (iCurrentHitCount > 16)
{
//Tracef(" Type NORMAL :: Overflow - Can't process, skip\n");
return FALSE;
}
}
else
{
if (iCurrentHitCount > pad->iHitLimitCount)
{
//Tracef(" Type SKILL :: Overflow - Can't process, skip\n");
return FALSE;
}
}
}
D3DXVECTOR3 v3HitPosition = (GetPosition() + rVictim.GetPosition()) *0.5f;
// #0000780: [M2KR] 수룡 타격구 문제
extern bool IS_HUGE_RACE(unsigned int vnum);
if (IS_HUGE_RACE(rVictim.GetRace()))
{
v3HitPosition = (GetPosition() + sub.v3Position) * 0.5f;
}
__ProcessDataAttackSuccess(*pad, rVictim, v3HitPosition, m_kCurMotNode.uSkill);
return TRUE;
}
}
}
}
}
return FALSE;
}
BOOL CActorInstance::AttackingProcess(CActorInstance & rVictim)
{
if (rVictim.__isInvisible())
return FALSE;
if (__SplashAttackProcess(rVictim))
return TRUE;
if (__NormalAttackProcess(rVictim))
return TRUE;
return FALSE;
}
BOOL CActorInstance::TestPhysicsBlendingCollision(CActorInstance & rVictim)
{
if (rVictim.IsDead())
return FALSE;
TPixelPosition kPPosLast;
GetBlendingPosition( &kPPosLast );
D3DXVECTOR3 v3Distance = D3DXVECTOR3(rVictim.m_x - kPPosLast.x, rVictim.m_y - kPPosLast.y, rVictim.m_z - kPPosLast.z);
float fDistance = D3DXVec3LengthSq(&v3Distance);
if (fDistance > 800.0f*800.0f)
return FALSE;
// NOTE : 공격 중일때는 Defending Sphere로 Collision Check를 합니다.
// NOTE : Wait로 블렌딩 되는 도중에 뚫고 들어가는 문제가 있어서.. - [levites]
TCollisionPointInstanceList * pMainList;
TCollisionPointInstanceList * pVictimList;
if (isAttacking() || IsWaiting())
{
pMainList = &m_DefendingPointInstanceList;
pVictimList = &rVictim.m_DefendingPointInstanceList;
}
else
{
pMainList = &m_BodyPointInstanceList;
pVictimList = &rVictim.m_BodyPointInstanceList;
}
TPixelPosition kPDelta;
m_PhysicsObject.GetLastPosition(&kPDelta);
D3DXVECTOR3 prevLastPosition, prevPosition;
const int nSubCheckCount = 50;
TCollisionPointInstanceListIterator itorMain = pMainList->begin();
TCollisionPointInstanceListIterator itorVictim = pVictimList->begin();
for (; itorMain != pMainList->end(); ++itorMain)
{
for (; itorVictim != pVictimList->end(); ++itorVictim)
{
CDynamicSphereInstanceVector & c_rMainSphereVector = (*itorMain).SphereInstanceVector;
CDynamicSphereInstanceVector & c_rVictimSphereVector = (*itorVictim).SphereInstanceVector;
for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i)
{
CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i];
//adjust main sphere center
prevLastPosition = c_rMainSphere.v3LastPosition;
prevPosition = c_rMainSphere.v3Position;
c_rMainSphere.v3LastPosition = prevPosition;
for( int i = 1; i <= nSubCheckCount; ++ i )
{
c_rMainSphere.v3Position = prevPosition + (float)(i/(float)nSubCheckCount) * kPDelta;
for (DWORD j = 0; j < c_rVictimSphereVector.size(); ++j)
{
CDynamicSphereInstance & c_rVictimSphere = c_rVictimSphereVector[j];
if (DetectCollisionDynamicSphereVSDynamicSphere(c_rMainSphere, c_rVictimSphere))
{
BOOL bResult = GetVector3Distance(c_rMainSphere.v3Position, c_rVictimSphere.v3Position) <= GetVector3Distance(c_rMainSphere.v3LastPosition, c_rVictimSphere.v3Position);
c_rMainSphere.v3LastPosition = prevLastPosition;
c_rMainSphere.v3Position = prevPosition;
return bResult;
}
}
}
//restore
c_rMainSphere.v3LastPosition = prevLastPosition;
c_rMainSphere.v3Position = prevPosition;
}
}
}
return FALSE;
}
BOOL CActorInstance::TestActorCollision(CActorInstance & rVictim)
{
/*
if (m_pkHorse)
{
if (m_pkHorse->TestActorCollision(rVictim))
return TRUE;
return FALSE;
}
*/
if (rVictim.IsDead())
return FALSE;
// Check Distance
// NOTE : 적당히 멀면 체크 안함
// 프레임 스킵시나 대상 오브젝트의 크기가 클경우 문제가 생길 여지가 있음
// 캐릭터가 자신의 Body Sphere Radius 보다 더 크게 이동했는지를 체크하고,
// 만약 그렇지 않다면 거리로 체크해서 걸러준다.
D3DXVECTOR3 v3Distance = D3DXVECTOR3(rVictim.m_x - m_x, rVictim.m_y - m_y, rVictim.m_z - m_z);
float fDistance = D3DXVec3LengthSq(&v3Distance);
if (fDistance > 800.0f*800.0f)
return FALSE;
// NOTE : 공격 중일때는 Defending Sphere로 Collision Check를 합니다.
// NOTE : Wait로 블렌딩 되는 도중에 뚫고 들어가는 문제가 있어서.. - [levites]
TCollisionPointInstanceList * pMainList;
TCollisionPointInstanceList * pVictimList;
if (isAttacking() || IsWaiting())
{
pMainList = &m_DefendingPointInstanceList;
pVictimList = &rVictim.m_DefendingPointInstanceList;
}
else
{
pMainList = &m_BodyPointInstanceList;
pVictimList = &rVictim.m_BodyPointInstanceList;
}
TCollisionPointInstanceListIterator itorMain = pMainList->begin();
TCollisionPointInstanceListIterator itorVictim = pVictimList->begin();
for (; itorMain != pMainList->end(); ++itorMain)
for (; itorVictim != pVictimList->end(); ++itorVictim)
{
const CDynamicSphereInstanceVector & c_rMainSphereVector = (*itorMain).SphereInstanceVector;
const CDynamicSphereInstanceVector & c_rVictimSphereVector = (*itorVictim).SphereInstanceVector;
for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i)
for (DWORD j = 0; j < c_rVictimSphereVector.size(); ++j)
{
const CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i];
const CDynamicSphereInstance & c_rVictimSphere = c_rVictimSphereVector[j];
if (DetectCollisionDynamicSphereVSDynamicSphere(c_rMainSphere, c_rVictimSphere))
{
if (GetVector3Distance(c_rMainSphere.v3Position, c_rVictimSphere.v3Position) <=
GetVector3Distance(c_rMainSphere.v3LastPosition, c_rVictimSphere.v3Position))
{
return TRUE;
}
return FALSE;
}
}
}
return FALSE;
}
bool CActorInstance::AvoidObject(const CGraphicObjectInstance& c_rkBGObj)
{
#ifdef __MOVIE_MODE__
if (IsMovieMode())
return false;
#endif
if (this==&c_rkBGObj)
return false;
if (!__TestObjectCollision(&c_rkBGObj))
return false;
__AdjustCollisionMovement(&c_rkBGObj);
return true;
}
bool CActorInstance::IsBlockObject(const CGraphicObjectInstance& c_rkBGObj)
{
if (this==&c_rkBGObj)
return false;
if (!__TestObjectCollision(&c_rkBGObj))
return false;
return true;
}
void CActorInstance::BlockMovement()
{
if (m_pkHorse)
{
m_pkHorse->__InitializeMovement();
return;
}
__InitializeMovement();
}
BOOL CActorInstance::__TestObjectCollision(const CGraphicObjectInstance * c_pObjectInstance)
{
if (m_pkHorse)
{
if (m_pkHorse->__TestObjectCollision(c_pObjectInstance))
return TRUE;
return FALSE;
}
if (m_canSkipCollision)
return FALSE;
if (m_v3Movement.x == 0.0f && m_v3Movement.y == 0.0f && m_v3Movement.z == 0.0f)
return FALSE;
TCollisionPointInstanceListIterator itorMain = m_BodyPointInstanceList.begin();
for (; itorMain != m_BodyPointInstanceList.end(); ++itorMain)
{
const CDynamicSphereInstanceVector & c_rMainSphereVector = (*itorMain).SphereInstanceVector;
for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i)
{
const CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i];
if (c_pObjectInstance->MovementCollisionDynamicSphere(c_rMainSphere))
{
//const D3DXVECTOR3 & c_rv3Position = c_pObjectInstance->GetPosition();
//if (GetVector3Distance(c_rMainSphere.v3Position, c_rv3Position) <
// GetVector3Distance(c_rMainSphere.v3LastPosition, c_rv3Position))
{
return TRUE;
}
//return FALSE;
}
}
}
return FALSE;
}
bool CActorInstance::TestCollisionWithDynamicSphere(const CDynamicSphereInstance & dsi)
{
TCollisionPointInstanceListIterator itorMain = m_BodyPointInstanceList.begin();
for (; itorMain != m_BodyPointInstanceList.end(); ++itorMain)
{
const CDynamicSphereInstanceVector & c_rMainSphereVector = (*itorMain).SphereInstanceVector;
for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i)
{
const CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i];
if (DetectCollisionDynamicSphereVSDynamicSphere(c_rMainSphere, dsi))
{
return true;
}
}
}
return false;
}
@@ -0,0 +1,180 @@
#include "StdAfx.h"
#include "ActorInstance.h"
void CActorInstance::__OnSyncing()
{
IEventHandler& rkEventHandler=__GetEventHandlerRef();
IEventHandler::SState kState;
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
kState.fAdvRotSelf=GetAdvancingRotation();
rkEventHandler.OnSyncing(kState);
}
void CActorInstance::__OnWaiting()
{
assert(!IsPushing());
IEventHandler& rkEventHandler=__GetEventHandlerRef();
IEventHandler::SState kState;
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
kState.fAdvRotSelf=GetAdvancingRotation();
rkEventHandler.OnWaiting(kState);
}
void CActorInstance::__OnMoving()
{
assert(!IsPushing());
IEventHandler& rkEventHandler=__GetEventHandlerRef();
const TPixelPosition& c_rkPPosCur=NEW_GetCurPixelPositionRef();
const TPixelPosition& c_rkPPosDst=NEW_GetDstPixelPositionRef();
TPixelPosition kPPosDir=c_rkPPosDst-c_rkPPosCur;
float distance=sqrt(kPPosDir.x*kPPosDir.x+kPPosDir.y*kPPosDir.y);
IEventHandler::SState kState;
if (distance>1000.0f)
{
D3DXVec3Normalize(&kPPosDir, &kPPosDir);
D3DXVec3Scale(&kPPosDir, &kPPosDir, 1000.0f);
D3DXVec3Add(&kState.kPPosSelf, &kPPosDir, &c_rkPPosCur);
}
else
{
kState.kPPosSelf=c_rkPPosDst;
}
kState.fAdvRotSelf=GetAdvancingRotation();
rkEventHandler.OnMoving(kState);
}
void CActorInstance::__OnMove()
{
IEventHandler& rkEventHandler=__GetEventHandlerRef();
IEventHandler::SState kState;
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
kState.fAdvRotSelf=GetAdvancingRotation();
rkEventHandler.OnMove(kState);
}
void CActorInstance::__OnStop()
{
IEventHandler& rkEventHandler=__GetEventHandlerRef();
IEventHandler::SState kState;
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
kState.fAdvRotSelf=GetAdvancingRotation();
rkEventHandler.OnStop(kState);
}
void CActorInstance::__OnWarp()
{
IEventHandler& rkEventHandler=__GetEventHandlerRef();
IEventHandler::SState kState;
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
kState.fAdvRotSelf=GetAdvancingRotation();
rkEventHandler.OnWarp(kState);
}
void CActorInstance::__OnAttack(WORD wMotionIndex)
{
IEventHandler& rkEventHandler=__GetEventHandlerRef();
IEventHandler::SState kState;
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
kState.fAdvRotSelf=GetTargetRotation();
rkEventHandler.OnAttack(kState, wMotionIndex);
}
void CActorInstance::__OnUseSkill(UINT uMotSkill, UINT uLoopCount, bool isMovingSkill)
{
IEventHandler& rkEventHandler=__GetEventHandlerRef();
IEventHandler::SState kState;
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
kState.fAdvRotSelf=GetAdvancingRotation();
UINT uArg=uLoopCount;
if (isMovingSkill)
uArg|=1<<4;
rkEventHandler.OnUseSkill(kState, uMotSkill, uArg);
}
void CActorInstance::__OnHit(UINT uSkill, CActorInstance& rkActorVictm, BOOL isSendPacket)
{
IEventHandler& rkEventHandler=__GetEventHandlerRef();
rkEventHandler.OnHit(uSkill, rkActorVictm, isSendPacket);
}
void CActorInstance::__OnClearAffects()
{
IEventHandler& rkEventHandler=__GetEventHandlerRef();
rkEventHandler.OnClearAffects();
}
void CActorInstance::__OnSetAffect(UINT uAffect)
{
IEventHandler& rkEventHandler=__GetEventHandlerRef();
rkEventHandler.OnSetAffect(uAffect);
}
void CActorInstance::__OnResetAffect(UINT uAffect)
{
IEventHandler& rkEventHandler=__GetEventHandlerRef();
rkEventHandler.OnResetAffect(uAffect);
}
CActorInstance::IEventHandler& CActorInstance::__GetEventHandlerRef()
{
assert(m_pkEventHandler!=NULL && "CActorInstance::GetEventHandlerRef");
return *m_pkEventHandler;
}
CActorInstance::IEventHandler* CActorInstance::__GetEventHandlerPtr()
{
return m_pkEventHandler;
}
void CActorInstance::SetEventHandler(IEventHandler* pkEventHandler)
{
m_pkEventHandler=pkEventHandler;
}
CActorInstance::IEventHandler* CActorInstance::IEventHandler::GetEmptyPtr()
{
static class CEmptyEventHandler : public IEventHandler
{
public:
CEmptyEventHandler() {}
virtual ~CEmptyEventHandler() {}
virtual void OnSyncing(const SState& c_rkState) {}
virtual void OnWaiting(const SState& c_rkState) {}
virtual void OnMoving(const SState& c_rkState) {}
virtual void OnMove(const SState& c_rkState) {}
virtual void OnStop(const SState& c_rkState) {}
virtual void OnWarp(const SState& c_rkState) {}
virtual void OnClearAffects() {}
virtual void OnSetAffect(UINT uAffect) {}
virtual void OnResetAffect(UINT uAffect) {}
virtual void OnAttack(const SState& c_rkState, WORD wMotionIndex) {}
virtual void OnUseSkill(const SState& c_rkState, UINT uMotSkill, UINT uMotLoopCount) {}
virtual void OnHit(UINT uMotAttack, CActorInstance& rkActorVictim, BOOL isSendPacket) {}
virtual void OnChangeShape() {}
} s_kEmptyEventHandler;
return &s_kEmptyEventHandler;
}
@@ -0,0 +1,117 @@
#include "StdAfx.h"
#include "ActorInstance.h"
D3DXVECTOR3 CActorInstance::OnGetFlyTargetPosition()
{
D3DXVECTOR3 v3Center;
if (m_fRadius<=0)
{
BuildBoundingSphere();
v3Center = m_v3Center;
}
else
{
v3Center = m_v3Center;
}
D3DXVec3TransformCoord(&v3Center, &v3Center, &GetTransform());
return v3Center;
}
void CActorInstance::ClearFlyTarget()
{
m_kFlyTarget.Clear();
m_kBackupFlyTarget.Clear();
m_kQue_kFlyTarget.clear();
}
bool CActorInstance::IsFlyTargetObject()
{
return m_kFlyTarget.IsObject();
}
bool CActorInstance::__IsFlyTargetPC()
{
if (!IsFlyTargetObject())
return false;
CActorInstance * pFlyInstance = (CActorInstance *)m_kFlyTarget.GetFlyTarget();
if (pFlyInstance->IsPC())
return true;
return true;
}
bool CActorInstance::__IsSameFlyTarget(CActorInstance * pInstance)
{
if (!IsFlyTargetObject())
return false;
CActorInstance * pFlyInstance = (CActorInstance *)m_kFlyTarget.GetFlyTarget();
if (pInstance == pFlyInstance)
return true;
return true;
}
D3DXVECTOR3 CActorInstance::__GetFlyTargetPosition()
{
if (!m_kFlyTarget.IsValidTarget())
{
return D3DXVECTOR3(0.0f, 0.0f, 0.0f);
}
return m_kFlyTarget.GetFlyTargetPosition();
}
float CActorInstance::GetFlyTargetDistance()
{
const D3DXVECTOR3& c_rv3FlyTargetPos=m_kFlyTarget.GetFlyTargetPosition();
const D3DXVECTOR3& c_rkPosSrc=GetPosition();
D3DXVECTOR3 kPPosDelta=c_rv3FlyTargetPos-c_rkPosSrc;
kPPosDelta.z=0;
return D3DXVec3Length(&kPPosDelta);
}
void CActorInstance::LookAtFlyTarget()
{
if (!IsFlyTargetObject())
return;
const D3DXVECTOR3& c_rv3FlyTargetPos=m_kFlyTarget.GetFlyTargetPosition();
LookAt(c_rv3FlyTargetPos.x, c_rv3FlyTargetPos.y);
}
void CActorInstance::AddFlyTarget(const CFlyTarget & cr_FlyTarget)
{
if (m_kFlyTarget.IsValidTarget())
m_kQue_kFlyTarget.push_back(cr_FlyTarget);
else
SetFlyTarget(cr_FlyTarget);
}
void CActorInstance::SetFlyTarget(const CFlyTarget & cr_FlyTarget)
{
m_kFlyTarget = cr_FlyTarget;
}
void CActorInstance::ClearFlyEventHandler()
{
m_pFlyEventHandler = 0;
}
void CActorInstance::SetFlyEventHandler(IFlyEventHandler * pHandler)
{
m_pFlyEventHandler = pHandler;
}
// 2004. 07. 07. [levites] - 스킬 사용중 타겟이 바뀌는 문제 해결을 위한 코드
bool CActorInstance::CanChangeTarget()
{
if (__IsNeedFlyTargetMotion())
return false;
return true;
}
@@ -0,0 +1,911 @@
#include "StdAfx.h"
#include "ActorInstance.h"
#include "RaceData.h"
#include "FlyHandler.h"
UINT CActorInstance::__GetMotionType()
{
if (!m_pkCurRaceMotionData)
return CRaceMotionData::TYPE_NONE;
return m_pkCurRaceMotionData->GetType();
}
void CActorInstance::__MotionEventProcess(BOOL isPC)
{
if (isAttacking())
{
DWORD dwNextFrame = DWORD(GetAttackingElapsedTime() * g_fGameFPS);
for (; m_kCurMotNode.dwcurFrame < dwNextFrame; ++m_kCurMotNode.dwcurFrame)
{
MotionEventProcess();
SoundEventProcess(!isPC);
}
}
else
{
MotionEventProcess();
SoundEventProcess(!isPC);
++m_kCurMotNode.dwcurFrame;
}
}
void CActorInstance::MotionProcess(BOOL isPC)
{
__MotionEventProcess(isPC);
CurrentMotionProcess();
ReservingMotionProcess();
}
void CActorInstance::HORSE_MotionProcess(BOOL isPC)
{
__MotionEventProcess(isPC);
if (MOTION_TYPE_LOOP == m_kCurMotNode.iMotionType)
if (m_kCurMotNode.dwcurFrame >= m_kCurMotNode.dwFrameCount)
m_kCurMotNode.dwcurFrame = 0;
}
void CActorInstance::ReservingMotionProcess()
{
if (m_MotionDeque.empty())
return;
TReservingMotionNode & rReservingMotionNode = m_MotionDeque.front();
float fCurrentTime = GetLocalTime();
if (rReservingMotionNode.fStartTime > fCurrentTime)
return;
DWORD dwNextMotionIndex = GET_MOTION_INDEX(rReservingMotionNode.dwMotionKey);
switch (dwNextMotionIndex)
{
case CRaceMotionData::NAME_STAND_UP:
case CRaceMotionData::NAME_STAND_UP_BACK:
if (IsFaint())
{
//Tracenf("일어서려고 했으나 기절중");
SetEndStopMotion();
// 이후의 모션 전부 1초씩 딜레이
TMotionDeque::iterator itor = m_MotionDeque.begin();
for (; itor != m_MotionDeque.end(); ++itor)
{
TReservingMotionNode & rNode = *itor;
rNode.fStartTime += 1.0f;
}
return;
}
break;
}
SCurrentMotionNode kPrevMotionNode=m_kCurMotNode;
EMotionPushType iMotionType=rReservingMotionNode.iMotionType;
float fSpeedRatio=rReservingMotionNode.fSpeedRatio;
float fBlendTime=rReservingMotionNode.fBlendTime;
DWORD dwMotionKey=rReservingMotionNode.dwMotionKey;
m_MotionDeque.pop_front();
DWORD dwCurrentMotionIndex=GET_MOTION_INDEX(dwMotionKey);
switch (dwCurrentMotionIndex)
{
case CRaceMotionData::NAME_STAND_UP:
case CRaceMotionData::NAME_STAND_UP_BACK:
if (IsDead())
{
//Tracenf("일어서려고 했으나 사망");
// 예전 데이터로 복구
m_kCurMotNode=kPrevMotionNode;
__ClearMotion();
// 이전 동작 마지막 상태 유지
SetEndStopMotion();
return;
}
break;
}
//Tracenf("MOTION %d", GET_MOTION_INDEX(dwMotionKey));
int iLoopCount;
if (MOTION_TYPE_ONCE == iMotionType)
iLoopCount=1;
else
iLoopCount=0;
SSetMotionData kSetMotData;
kSetMotData.dwMotKey=dwMotionKey;
kSetMotData.fBlendTime=fBlendTime;
kSetMotData.fSpeedRatio=fSpeedRatio;
kSetMotData.iLoopCount=iLoopCount;
DWORD dwRealMotionKey = __SetMotion(kSetMotData);
if (0 == dwRealMotionKey)
return;
// FIX: 위에서 호출한 __SetMotion 함수 안에서 랜덤으로 다른 모션을 재생할 가능성도 있으므로 duration은 '현재 재생중인' 모션의 duration값을 사용해야 함.
//float fDurationTime=rReservingMotionNode.fDuration;
float fDurationTime = GetMotionDuration(dwRealMotionKey) / fSpeedRatio;
float fStartTime = rReservingMotionNode.fStartTime;
float fEndTime = fStartTime + fDurationTime;
if (dwRealMotionKey == 16777473)
{
int bp = 0;
bp++;
}
m_kCurMotNode.uSkill = 0;
m_kCurMotNode.iMotionType = iMotionType;
m_kCurMotNode.fSpeedRatio = fSpeedRatio;
m_kCurMotNode.fStartTime = fStartTime;
m_kCurMotNode.fEndTime = fEndTime;
m_kCurMotNode.dwMotionKey = dwRealMotionKey;
m_kCurMotNode.dwcurFrame = 0;
m_kCurMotNode.dwFrameCount = fDurationTime / (1.0f / g_fGameFPS);
}
void CActorInstance::CurrentMotionProcess()
{
if (MOTION_TYPE_LOOP == m_kCurMotNode.iMotionType) // 임시다. 최종적인 목표는 Once도 절대로 넘어가선 안된다. - [levites]
if (m_kCurMotNode.dwcurFrame >= m_kCurMotNode.dwFrameCount)
m_kCurMotNode.dwcurFrame = 0;
if (IsDead())
return;
if (!m_MotionDeque.empty())
return;
float fCurrentTime = GetLocalTime();
DWORD dwMotionIndex=GET_MOTION_INDEX(m_kCurMotNode.dwMotionKey);
bool isLooping=false;
// 끝났다면 Playing Flag를 끈다
if (m_pkCurRaceMotionData && m_pkCurRaceMotionData->IsLoopMotion())
{
if (m_kCurMotNode.iLoopCount > 1 || m_kCurMotNode.iLoopCount == -1)
{
if (fCurrentTime - m_kCurMotNode.fStartTime > m_pkCurRaceMotionData->GetLoopEndTime())
{
m_kCurMotNode.dwcurFrame = DWORD(m_pkCurRaceMotionData->GetLoopStartTime() * g_fGameFPS);
__SetLocalTime(m_kCurMotNode.fStartTime + m_pkCurRaceMotionData->GetLoopStartTime());
if (-1 != m_kCurMotNode.iLoopCount)
--m_kCurMotNode.iLoopCount;
isLooping=true;
}
}
else if (!m_kQue_kFlyTarget.empty())
{
if (!m_kBackupFlyTarget.IsObject())
{
m_kBackupFlyTarget = m_kFlyTarget;
}
if (fCurrentTime - m_kCurMotNode.fStartTime > m_pkCurRaceMotionData->GetLoopEndTime())
{
m_kCurMotNode.dwcurFrame = DWORD(m_pkCurRaceMotionData->GetLoopStartTime() * g_fGameFPS);
__SetLocalTime(m_kCurMotNode.fStartTime + m_pkCurRaceMotionData->GetLoopStartTime());
SetFlyTarget(m_kQue_kFlyTarget.front());
m_kQue_kFlyTarget.pop_front();
isLooping=true;
}
}
}
if (!isLooping)
{
if (fCurrentTime > m_kCurMotNode.fEndTime)
{
if (m_kBackupFlyTarget.IsValidTarget())
{
m_kFlyTarget = m_kBackupFlyTarget;
m_kBackupFlyTarget.Clear();
}
////////////////////////////////////////////
if (MOTION_TYPE_ONCE == m_kCurMotNode.iMotionType)
{
switch (dwMotionIndex)
{
case CRaceMotionData::NAME_DAMAGE_FLYING:
case CRaceMotionData::NAME_DAMAGE_FLYING_BACK:
case CRaceMotionData::NAME_DEAD:
case CRaceMotionData::NAME_INTRO_SELECTED:
case CRaceMotionData::NAME_INTRO_NOT_SELECTED:
m_kCurMotNode.fEndTime+=3.0f;
SetEndStopMotion();
break;
default:
InterceptLoopMotion(CRaceMotionData::NAME_WAIT);
break;
}
}
else if (MOTION_TYPE_LOOP == m_kCurMotNode.iMotionType)
{
if (CRaceMotionData::NAME_WAIT == dwMotionIndex)
{
PushLoopMotion(CRaceMotionData::NAME_WAIT, 0.5f);
}
}
}
}
}
void CActorInstance::SetMotionMode(int iMotionMode)
{
if (IsPoly())
iMotionMode=CRaceMotionData::MODE_GENERAL;
m_wcurMotionMode = iMotionMode;
}
int CActorInstance::GetMotionMode()
{
return m_wcurMotionMode;
}
void CActorInstance::SetMotionLoopCount(int iCount)
{
assert(iCount >= -1 && iCount < 100);
m_kCurMotNode.iLoopCount = iCount;
}
void CActorInstance::PushMotion(EMotionPushType iMotionType, DWORD dwMotionKey, float fBlendTime, float fSpeedRatio)
{
if (!CheckMotionThingIndex(dwMotionKey))
{
Tracef(" Error - Not found want to using motion : %d\n", GET_MOTION_INDEX(dwMotionKey));
return;
}
TReservingMotionNode MotionNode;
MotionNode.iMotionType = iMotionType;
MotionNode.dwMotionKey = dwMotionKey;
MotionNode.fStartTime = GetLastMotionTime(fBlendTime);
MotionNode.fBlendTime = fBlendTime;
MotionNode.fSpeedRatio = fSpeedRatio;
MotionNode.fDuration = GetMotionDuration(dwMotionKey);
m_MotionDeque.push_back(MotionNode);
}
bool CActorInstance::InterceptOnceMotion(DWORD dwMotion, float fBlendTime, UINT uSkill, float fSpeedRatio)
{
return InterceptMotion(MOTION_TYPE_ONCE, dwMotion, fBlendTime, uSkill, fSpeedRatio);
}
bool CActorInstance::InterceptLoopMotion(DWORD dwMotion, float fBlendTime)
{
return InterceptMotion(MOTION_TYPE_LOOP, dwMotion, fBlendTime);
}
void CActorInstance::SetLoopMotion(DWORD dwMotion, float fBlendTime, float fSpeedRatio)
{
if (!m_pkCurRaceData)
{
Tracenf("CActorInstance::SetLoopMotion(dwMotion=%d, fBlendTime=%f, fSpeedRatio=%f)",
dwMotion, fBlendTime, fSpeedRatio);
return;
}
MOTION_KEY dwMotionKey;
if (!m_pkCurRaceData->GetMotionKey(m_wcurMotionMode, dwMotion, &dwMotionKey))
{
Tracenf("CActorInstance::SetLoopMotion(dwMotion=%d, fBlendTime=%f, fSpeedRatio=%f) - GetMotionKey(m_wcurMotionMode=%d, dwMotion=%d, &MotionKey) ERROR",
dwMotion, fBlendTime, fSpeedRatio, m_wcurMotionMode, dwMotion);
return;
}
__ClearMotion();
SSetMotionData kSetMotData;
kSetMotData.dwMotKey=dwMotionKey;
kSetMotData.fBlendTime=fBlendTime;
kSetMotData.fSpeedRatio=fSpeedRatio;
DWORD dwRealMotionKey = __SetMotion(kSetMotData);
if (0 == dwRealMotionKey)
return;
m_kCurMotNode.iMotionType = MOTION_TYPE_LOOP;
m_kCurMotNode.fStartTime = GetLocalTime();
m_kCurMotNode.dwMotionKey = dwRealMotionKey;
m_kCurMotNode.fEndTime = 0.0f;
m_kCurMotNode.fSpeedRatio = fSpeedRatio;
m_kCurMotNode.dwcurFrame = 0;
m_kCurMotNode.dwFrameCount = GetMotionDuration(dwRealMotionKey) / (1.0f / g_fGameFPS);
m_kCurMotNode.uSkill = 0;
}
// 리턴값 == SetMotion의 리턴값 == 실제로 애니메이션 데이터를 플레이 했느냐?
bool CActorInstance::InterceptMotion(EMotionPushType iMotionType, WORD wMotion, float fBlendTime, UINT uSkill, float fSpeedRatio)
{
if (!m_pkCurRaceData)
{
Tracef("CActorInstance::InterceptMotion(iMotionType=%d, wMotion=%d, fBlendTime=%f) - m_pkCurRaceData=NULL", iMotionType, wMotion, fBlendTime);
return false;
}
MOTION_KEY dwMotionKey;
if (!m_pkCurRaceData->GetMotionKey(m_wcurMotionMode, wMotion, &dwMotionKey))
{
Tracenf("CActorInstance::InterceptMotion(iLoopType=%d, wMotionMode=%d, wMotion=%d, fBlendTime=%f) - GetMotionKey(m_wcurMotionMode=%d, wMotion=%d, &MotionKey) ERROR",
iMotionType, m_wcurMotionMode, wMotion, fBlendTime, m_wcurMotionMode, wMotion);
return false;
}
__ClearMotion();
int iLoopCount;
if (MOTION_TYPE_ONCE == iMotionType)
iLoopCount=1;
else
iLoopCount=0;
SSetMotionData kSetMotData;
kSetMotData.dwMotKey=dwMotionKey;
kSetMotData.fBlendTime=fBlendTime;
kSetMotData.iLoopCount=iLoopCount;
kSetMotData.fSpeedRatio=fSpeedRatio;
kSetMotData.uSkill=uSkill;
DWORD dwRealMotionKey = __SetMotion(kSetMotData);
if (0 == dwRealMotionKey)
return false;
if (m_pFlyEventHandler)
{
if (__IsNeedFlyTargetMotion())
{
m_pFlyEventHandler->OnSetFlyTarget();
}
}
assert(NULL != m_pkCurRaceMotionData);
// FIX : 위에서 호출한 __SetMotion 함수 내에서 랜덤으로 다른 모션을 선택할 수도 있기 때문에 dwMotionKey값은 유효하지 않고
// 따라서 해당 키로 산출한 duration은 유효하지 않음. 당연히 현재 play중인 모션의 시간을 구해야 함.. -_-;;
// float fDuration=GetMotionDuration(dwMotionKey)/fSpeedRatio;
float fDuration = GetMotionDuration(dwRealMotionKey) / fSpeedRatio;
m_kCurMotNode.iMotionType = iMotionType;
m_kCurMotNode.fStartTime = GetLocalTime();
m_kCurMotNode.fEndTime = m_kCurMotNode.fStartTime + fDuration;
m_kCurMotNode.dwMotionKey = dwRealMotionKey;
m_kCurMotNode.dwcurFrame = 0;
m_kCurMotNode.dwFrameCount = fDuration / (1.0f / g_fGameFPS);
m_kCurMotNode.uSkill = uSkill;
m_kCurMotNode.fSpeedRatio = fSpeedRatio;
return true;
}
bool CActorInstance::PushOnceMotion(DWORD dwMotion, float fBlendTime, float fSpeedRatio)
{
assert(m_pkCurRaceData);
MOTION_KEY MotionKey;
if (!m_pkCurRaceData->GetMotionKey(m_wcurMotionMode, dwMotion, &MotionKey))
return false;
PushMotion(MOTION_TYPE_ONCE, MotionKey, fBlendTime, fSpeedRatio);
return true;
}
bool CActorInstance::PushLoopMotion(DWORD dwMotion, float fBlendTime, float fSpeedRatio)
{
assert(m_pkCurRaceData);
MOTION_KEY MotionKey;
if (!m_pkCurRaceData->GetMotionKey(m_wcurMotionMode, dwMotion, &MotionKey))
return false;
PushMotion(MOTION_TYPE_LOOP, MotionKey, fBlendTime, fSpeedRatio);
return true;
}
WORD CActorInstance::__GetCurrentMotionIndex()
{
return GET_MOTION_INDEX(m_kCurMotNode.dwMotionKey);
}
DWORD CActorInstance::__GetCurrentMotionKey()
{
return m_kCurMotNode.dwMotionKey;
}
BOOL CActorInstance::IsUsingSkill()
{
DWORD dwCurMotionIndex=__GetCurrentMotionIndex();
if (dwCurMotionIndex>=CRaceMotionData::NAME_SKILL && dwCurMotionIndex<CRaceMotionData::NAME_SKILL_END)
return TRUE;
switch (dwCurMotionIndex)
{
case CRaceMotionData::NAME_SPECIAL_1:
case CRaceMotionData::NAME_SPECIAL_2:
case CRaceMotionData::NAME_SPECIAL_3:
case CRaceMotionData::NAME_SPECIAL_4:
case CRaceMotionData::NAME_SPECIAL_5:
case CRaceMotionData::NAME_SPECIAL_6:
return TRUE;
}
return FALSE;
}
BOOL CActorInstance::IsFishing()
{
if (!m_pkCurRaceMotionData)
return FALSE;
if (__GetCurrentMotionIndex() == CRaceMotionData::NAME_FISHING_WAIT ||
__GetCurrentMotionIndex() == CRaceMotionData::NAME_FISHING_REACT)
return TRUE;
return FALSE;
}
BOOL CActorInstance::CanCancelSkill()
{
assert(IsUsingSkill());
return m_pkCurRaceMotionData->IsCancelEnableSkill();
}
BOOL CActorInstance::isLock()
{
DWORD dwCurMotionIndex=__GetCurrentMotionIndex();
// Locked during attack
switch (dwCurMotionIndex)
{
case CRaceMotionData::NAME_NORMAL_ATTACK:
case CRaceMotionData::NAME_COMBO_ATTACK_1:
case CRaceMotionData::NAME_COMBO_ATTACK_2:
case CRaceMotionData::NAME_COMBO_ATTACK_3:
case CRaceMotionData::NAME_COMBO_ATTACK_4:
case CRaceMotionData::NAME_COMBO_ATTACK_5:
case CRaceMotionData::NAME_COMBO_ATTACK_6:
case CRaceMotionData::NAME_COMBO_ATTACK_7:
case CRaceMotionData::NAME_COMBO_ATTACK_8:
case CRaceMotionData::NAME_SPECIAL_1:
case CRaceMotionData::NAME_SPECIAL_2:
case CRaceMotionData::NAME_SPECIAL_3:
case CRaceMotionData::NAME_SPECIAL_4:
case CRaceMotionData::NAME_SPECIAL_5:
case CRaceMotionData::NAME_SPECIAL_6:
case CRaceMotionData::NAME_FISHING_THROW:
case CRaceMotionData::NAME_FISHING_WAIT:
case CRaceMotionData::NAME_FISHING_STOP:
case CRaceMotionData::NAME_FISHING_REACT:
case CRaceMotionData::NAME_FISHING_CATCH:
case CRaceMotionData::NAME_FISHING_FAIL:
case CRaceMotionData::NAME_CLAP:
case CRaceMotionData::NAME_DANCE_1:
case CRaceMotionData::NAME_DANCE_2:
case CRaceMotionData::NAME_DANCE_3:
case CRaceMotionData::NAME_DANCE_4:
case CRaceMotionData::NAME_DANCE_5:
case CRaceMotionData::NAME_DANCE_6:
case CRaceMotionData::NAME_CONGRATULATION:
case CRaceMotionData::NAME_FORGIVE:
case CRaceMotionData::NAME_ANGRY:
case CRaceMotionData::NAME_ATTRACTIVE:
case CRaceMotionData::NAME_SAD:
case CRaceMotionData::NAME_SHY:
case CRaceMotionData::NAME_CHEERUP:
case CRaceMotionData::NAME_BANTER:
case CRaceMotionData::NAME_JOY:
case CRaceMotionData::NAME_CHEERS_1:
case CRaceMotionData::NAME_CHEERS_2:
case CRaceMotionData::NAME_KISS_WITH_WARRIOR:
case CRaceMotionData::NAME_KISS_WITH_ASSASSIN:
case CRaceMotionData::NAME_KISS_WITH_SURA:
case CRaceMotionData::NAME_KISS_WITH_SHAMAN:
case CRaceMotionData::NAME_FRENCH_KISS_WITH_WARRIOR:
case CRaceMotionData::NAME_FRENCH_KISS_WITH_ASSASSIN:
case CRaceMotionData::NAME_FRENCH_KISS_WITH_SURA:
case CRaceMotionData::NAME_FRENCH_KISS_WITH_SHAMAN:
case CRaceMotionData::NAME_SLAP_HIT_WITH_WARRIOR:
case CRaceMotionData::NAME_SLAP_HIT_WITH_ASSASSIN:
case CRaceMotionData::NAME_SLAP_HIT_WITH_SURA:
case CRaceMotionData::NAME_SLAP_HIT_WITH_SHAMAN:
case CRaceMotionData::NAME_SLAP_HURT_WITH_WARRIOR:
case CRaceMotionData::NAME_SLAP_HURT_WITH_ASSASSIN:
case CRaceMotionData::NAME_SLAP_HURT_WITH_SURA:
case CRaceMotionData::NAME_SLAP_HURT_WITH_SHAMAN:
return TRUE;
break;
}
// Locked during using skill
if (IsUsingSkill())
{
if (m_pkCurRaceMotionData->IsCancelEnableSkill())
return FALSE;
return TRUE;
}
return FALSE;
}
float CActorInstance::GetLastMotionTime(float fBlendTime)
{
if (m_MotionDeque.empty())
{
if (MOTION_TYPE_ONCE == m_kCurMotNode.iMotionType)
return (m_kCurMotNode.fEndTime - fBlendTime);
return GetLocalTime();
}
TReservingMotionNode & rMotionNode = m_MotionDeque[m_MotionDeque.size()-1];
return rMotionNode.fStartTime + rMotionNode.fDuration - fBlendTime;
}
float CActorInstance::GetMotionDuration(DWORD dwMotionKey)
{
CGraphicThing * pMotion;
if (!GetMotionThingPointer(dwMotionKey, &pMotion))
{
Tracenf("CActorInstance::GetMotionDuration - Cannot get motion: %d / %d",
GET_MOTION_MODE(dwMotionKey), GET_MOTION_INDEX(dwMotionKey));
return 0.0f;
}
if (0 == pMotion->GetMotionCount())
{
#ifdef _DEBUG
Tracenf("CActorInstance::GetMotionDuration - Invalid Motion Key : %d, %d, %d",
GET_MOTION_MODE(dwMotionKey), GET_MOTION_INDEX(dwMotionKey), GET_MOTION_SUB_INDEX(dwMotionKey));
#endif
return 0.0f;
}
CGrannyMotion * pGrannyMotion = pMotion->GetMotionPointer(0);
return pGrannyMotion->GetDuration();
}
MOTION_KEY CActorInstance::GetRandomMotionKey(MOTION_KEY dwMotionKey)
{
// NOTE : 자주 호출 되는 부분은 아니지만 어느 정도의 최적화 여지가 있음 - [levites]
// FIXME : 처음에 선택된 모션이 없는 것에 대한 처리가 되어 있지 않다.
WORD wMode = GET_MOTION_MODE(dwMotionKey);
WORD wIndex = GET_MOTION_INDEX(dwMotionKey);
const CRaceData::TMotionVector * c_pMotionVector;
if (m_pkCurRaceData->GetMotionVectorPointer(wMode, wIndex, &c_pMotionVector))
if (c_pMotionVector->size() > 1)
{
int iPercentage = random() % 100;
for (DWORD i = 0; i < c_pMotionVector->size(); ++i)
{
const CRaceData::TMotion & c_rMotion = c_pMotionVector->at(i);
iPercentage -= c_rMotion.byPercentage;
if (iPercentage < 0)
{
dwMotionKey = MAKE_RANDOM_MOTION_KEY(wMode, wIndex, i);
// Temporary
// NOTE: 현재로선 여기서 해봤자 의미없다. 전체적으로 확인결과 아래는 씹히는 코드고 다른곳에서 해결해야 하므로 일단 주석처리함. 나중에 통채로 지우자..
// m_kCurMotNode.fEndTime = m_kCurMotNode.fStartTime + GetMotionDuration(dwMotionKey);
// Temporary
return dwMotionKey;
}
}
}
return dwMotionKey;
}
void CActorInstance::PreAttack()
{
}
void CActorInstance::__ClearMotion()
{
__HideWeaponTrace();
m_MotionDeque.clear();
m_kCurMotNode.dwcurFrame=0;
m_kCurMotNode.dwFrameCount=0;
m_kCurMotNode.uSkill=0;
m_kCurMotNode.iLoopCount=0;
m_kCurMotNode.iMotionType=MOTION_TYPE_NONE;
}
DWORD CActorInstance::__SetMotion(const SSetMotionData& c_rkSetMotData, DWORD dwRandMotKey)
{
DWORD dwMotKey = dwRandMotKey;
if (dwMotKey == 0)
dwMotKey = GetRandomMotionKey(c_rkSetMotData.dwMotKey);
UINT uNextMot = GET_MOTION_INDEX(c_rkSetMotData.dwMotKey);
if (IsDead())
{
if (uNextMot!=CRaceMotionData::NAME_DAMAGE_FLYING && uNextMot!=CRaceMotionData::NAME_DAMAGE_FLYING_BACK && uNextMot!=CRaceMotionData::NAME_DEAD && uNextMot!=CRaceMotionData::NAME_DEAD_BACK)
return 0;
}
if (IsUsingSkill())
{
__OnStop();
}
if (__IsStandUpMotion())
{
__OnStop();
}
if (__IsMoveMotion())
{
if (uNextMot==CRaceMotionData::NAME_DAMAGE || uNextMot==CRaceMotionData::NAME_DAMAGE_BACK || uNextMot==CRaceMotionData::NAME_DAMAGE_FLYING || uNextMot==CRaceMotionData::NAME_DAMAGE_FLYING_BACK)
{
if (!m_isMain)
{
Logn(0, "\301\326\300\316\260\370\300\314 \276\306\264\317\266\363\270\351 \300\314\265\277\301\337\300\314\266\363 \265\245\271\314\301\366 \265\277\300\333\300\273 \303\353\307\317\301\366 \276\312\300\275");
return false;
}
}
if (uNextMot!=CRaceMotionData::NAME_RUN &&
uNextMot!=CRaceMotionData::NAME_WALK &&
!__IsMovingSkill(c_rkSetMotData.uSkill))
{
__OnStop();
}
}
else
{
if (uNextMot==CRaceMotionData::NAME_RUN || __IsMovingSkill(c_rkSetMotData.uSkill))
{
__OnMove();
}
}
// NOTE : 스킬 사용중 사라지는 문제를 위한 안전 장치 - [levites]
if (__IsHiding())
{
__ShowEvent();
}
if (-1 != m_iFishingEffectID)
{
CEffectManager& rkEftMgr=CEffectManager::Instance();
rkEftMgr.DeactiveEffectInstance(m_iFishingEffectID);
m_iFishingEffectID = -1;
}
if (m_pkHorse)
{
WORD wMotionIndex = GET_MOTION_INDEX(dwMotKey);
WORD wMotionSubIndex = GET_MOTION_SUB_INDEX(dwMotKey);
DWORD dwChildMotKey = MAKE_RANDOM_MOTION_KEY(m_pkHorse->m_wcurMotionMode, wMotionIndex, wMotionSubIndex);
if (CRaceMotionData::NAME_DEAD == wMotionIndex)
CGraphicThingInstance::ChangeMotion(dwMotKey, c_rkSetMotData.iLoopCount, c_rkSetMotData.fSpeedRatio);
else
CGraphicThingInstance::SetMotion(dwMotKey, c_rkSetMotData.fBlendTime, c_rkSetMotData.iLoopCount, c_rkSetMotData.fSpeedRatio);
m_pkHorse->SetMotion(dwChildMotKey, c_rkSetMotData.fBlendTime, c_rkSetMotData.iLoopCount, c_rkSetMotData.fSpeedRatio);
m_pkHorse->__BindMotionData(dwChildMotKey);
if (c_rkSetMotData.iLoopCount)
m_pkHorse->m_kCurMotNode.iMotionType = MOTION_TYPE_ONCE; // 무조건 이전 모션 타입으로 설정되고 있었음
else
m_pkHorse->m_kCurMotNode.iMotionType = MOTION_TYPE_LOOP;
m_pkHorse->m_kCurMotNode.dwFrameCount = m_pkHorse->GetMotionDuration(dwChildMotKey) / (1.0f / g_fGameFPS);
m_pkHorse->m_kCurMotNode.dwcurFrame = 0;
m_pkHorse->m_kCurMotNode.dwMotionKey = dwChildMotKey;
}
else
{
CGraphicThingInstance::SetMotion(dwMotKey, c_rkSetMotData.fBlendTime, c_rkSetMotData.iLoopCount, c_rkSetMotData.fSpeedRatio);
}
__HideWeaponTrace();
if (__BindMotionData(dwMotKey))
{
int iLoopCount = __GetLoopCount();
SetMotionLoopCount(iLoopCount);
if (__CanAttack())
{
// 여기서 공격 모션일 경우의 처리를 합니다 - [levites]
__ShowWeaponTrace();
m_HitDataMap.clear();
//PreAttack();
}
if (__IsComboAttacking())
{
if (!__CanNextComboAttack())
{
// 2004.11.19.myevan.동물 변신시 이부분에서 바로 리셋되어 다음동작 안나온다
m_dwcurComboIndex = 0; // 콤보 리셋 - [levites]
// NOTE : ClearCombo() 를 수행해서는 안된다.
// 콤보 다음에 스킬을 이어서 사용할 경우 m_pkCurRaceMotionData까지 초기화 되어 버린다.
//Tracef("MotionData에 콤보 데이타가 들어 있지 않습니다.\n");
}
}
}
return dwMotKey;
}
bool CActorInstance::__BindMotionData(DWORD dwMotionKey)
{
if (!m_pkCurRaceData->GetMotionDataPointer(dwMotionKey, &m_pkCurRaceMotionData))
{
Tracen("Failed to bind motion.");
m_pkCurRaceMotionData=NULL;
m_dwcurComboIndex=0;
return false;
}
return true;
}
int CActorInstance::__GetLoopCount()
{
if (!m_pkCurRaceMotionData)
{
TraceError("CActorInstance::__GetLoopCount() - m_pkCurRaceMotionData==NULL");
return -1;
}
return m_pkCurRaceMotionData->GetLoopCount();
}
bool CActorInstance::__CanAttack()
{
if (!m_pkCurRaceMotionData)
{
TraceError("CActorInstance::__CanAttack() - m_pkCurRaceMotionData==NULL");
return false;
}
if (!m_pkCurRaceMotionData->isAttackingMotion())
return false;
return true;
}
bool CActorInstance::__CanNextComboAttack()
{
if (!m_pkCurRaceMotionData)
{
TraceError("CActorInstance::__CanNextComboAttack() - m_pkCurRaceMotionData==NULL");
return false;
}
if (!m_pkCurRaceMotionData->IsComboInputTimeData())
return false;
return true;
}
bool CActorInstance::__IsComboAttacking()
{
if (0 == m_dwcurComboIndex)
return false;
return true;
}
bool CActorInstance::__IsNeedFlyTargetMotion()
{
if (!m_pkCurRaceMotionData)
return true;
for (DWORD i = 0; i < m_pkCurRaceMotionData->GetMotionEventDataCount(); ++i)
{
const CRaceMotionData::TMotionEventData * c_pData;
if (!m_pkCurRaceMotionData->GetMotionEventDataPointer(i, &c_pData))
continue;
if (c_pData->iType == CRaceMotionData::MOTION_EVENT_TYPE_WARP)
return true;
if (c_pData->iType == CRaceMotionData::MOTION_EVENT_TYPE_FLY)
return true;
if (c_pData->iType == CRaceMotionData::MOTION_EVENT_TYPE_EFFECT_TO_TARGET)
return true;
}
return false;
}
bool CActorInstance::__HasMotionFlyEvent()
{
if (!m_pkCurRaceMotionData)
return true;
for (DWORD i = 0; i < m_pkCurRaceMotionData->GetMotionEventDataCount(); ++i)
{
const CRaceMotionData::TMotionEventData * c_pData;
if (!m_pkCurRaceMotionData->GetMotionEventDataPointer(i, &c_pData))
continue;
if (c_pData->iType == CRaceMotionData::MOTION_EVENT_TYPE_FLY)
return true;
}
return false;
}
bool CActorInstance::__IsWaitMotion()
{
return (__GetMotionType()==CRaceMotionData::TYPE_WAIT);
}
bool CActorInstance::__IsMoveMotion()
{
return (__GetMotionType()==CRaceMotionData::TYPE_MOVE);
}
bool CActorInstance::__IsAttackMotion()
{
return (__GetMotionType()==CRaceMotionData::TYPE_ATTACK);
}
bool CActorInstance::__IsComboAttackMotion()
{
return (__GetMotionType()==CRaceMotionData::TYPE_COMBO);
}
bool CActorInstance::__IsDamageMotion()
{
return (__GetMotionType()==CRaceMotionData::TYPE_DAMAGE);
}
bool CActorInstance::__IsKnockDownMotion()
{
return (__GetMotionType()==CRaceMotionData::TYPE_KNOCKDOWN);
}
bool CActorInstance::__IsDieMotion()
{
if (__IsKnockDownMotion())
return true;
return (__GetMotionType()==CRaceMotionData::TYPE_DIE);
}
bool CActorInstance::__IsStandUpMotion()
{
return (__GetMotionType()==CRaceMotionData::TYPE_STANDUP);
}
@@ -0,0 +1,331 @@
#include "StdAfx.h"
#include "../EffectLib/EffectManager.h"
#include "../MilesLib/SoundManager.h"
#include "ActorInstance.h"
#include "FlyingObjectManager.h"
#include "FlyingInstance.h"
#include "GameEventManager.h"
#include "FlyHandler.h"
void CActorInstance::MotionEventProcess()
{
if (!m_pkCurRaceMotionData)
return;
for (DWORD i = 0; i < m_pkCurRaceMotionData->GetMotionEventDataCount(); ++i)
{
const CRaceMotionData::TMotionEventData * c_pData;
if (!m_pkCurRaceMotionData->GetMotionEventDataPointer(i, &c_pData))
continue;
MotionEventProcess(m_kCurMotNode.dwcurFrame, i, c_pData);
}
}
void CActorInstance::SoundEventProcess(BOOL bCheckFrequency)
{
if (!m_pkCurRaceMotionData)
return;
CSoundManager& rkSndMgr=CSoundManager::Instance();
const NSound::TSoundInstanceVector* c_pkVct_kSndInst=m_pkCurRaceMotionData->GetSoundInstanceVectorPointer();
rkSndMgr.UpdateSoundInstance(m_x, m_y, m_z, m_kCurMotNode.dwcurFrame, c_pkVct_kSndInst, bCheckFrequency);
}
void CActorInstance::MotionEventProcess(DWORD dwcurFrame, int iIndex, const CRaceMotionData::TMotionEventData * c_pData)
{
if (c_pData->dwFrame != dwcurFrame)
return;
switch (c_pData->iType)
{
case CRaceMotionData::MOTION_EVENT_TYPE_EFFECT:
ProcessMotionEventEffectEvent(c_pData);
break;
case CRaceMotionData::MOTION_EVENT_TYPE_EFFECT_TO_TARGET:
ProcessMotionEventEffectToTargetEvent(c_pData);
break;
case CRaceMotionData::MOTION_EVENT_TYPE_SCREEN_WAVING:
CGameEventManager::Instance().ProcessEventScreenWaving(this, (const CRaceMotionData::TScreenWavingEventData *)c_pData);
break;
case CRaceMotionData::MOTION_EVENT_TYPE_SPECIAL_ATTACKING:
ProcessMotionEventSpecialAttacking(iIndex, c_pData);
break;
case CRaceMotionData::MOTION_EVENT_TYPE_SOUND:
ProcessMotionEventSound(c_pData);
break;
case CRaceMotionData::MOTION_EVENT_TYPE_FLY:
ProcessMotionEventFly(c_pData);
break;
case CRaceMotionData::MOTION_EVENT_TYPE_CHARACTER_SHOW:
__ShowEvent();
break;
case CRaceMotionData::MOTION_EVENT_TYPE_CHARACTER_HIDE:
__HideEvent();
break;
case CRaceMotionData::MOTION_EVENT_TYPE_WARP:
#ifndef WORLD_EDITOR
ProcessMotionEventWarp(c_pData);
#endif
break;
}
}
void CActorInstance::__ShowEvent()
{
m_isHiding = FALSE;
RestoreRenderMode();
SetAlphaValue(1.0f);
}
void CActorInstance::__HideEvent()
{
m_isHiding = TRUE;
SetBlendRenderMode();
SetAlphaValue(0.0f);
}
BOOL CActorInstance::__IsHiding()
{
return m_isHiding;
}
void CActorInstance::ProcessMotionEventEffectEvent(const CRaceMotionData::TMotionEventData * c_pData)
{
if (CRaceMotionData::MOTION_EVENT_TYPE_EFFECT != c_pData->iType)
return;
const CRaceMotionData::TMotionEffectEventData * c_pEffectData = (const CRaceMotionData::TMotionEffectEventData *)c_pData;
if (c_pEffectData->isIndependent)
{
int iIndex = CEffectManager::Instance().CreateEffect(c_pEffectData->dwEffectIndex, D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f));
D3DXMATRIX matLocalPosition;
D3DXMatrixTranslation(&matLocalPosition, c_pEffectData->v3EffectPosition.x, c_pEffectData->v3EffectPosition.y, c_pEffectData->v3EffectPosition.z);
D3DXMATRIX matWorld;
matWorld = matLocalPosition;
matWorld *= m_worldMatrix;
CEffectManager::Instance().SelectEffectInstance(iIndex);
CEffectManager::Instance().SetEffectInstanceGlobalMatrix(matWorld);
return;
}
if (c_pEffectData->isAttaching)
{
if (c_pEffectData->isFollowing)
{
AttachEffectByID(0,
c_pEffectData->strAttachingBoneName.c_str(),
c_pEffectData->dwEffectIndex,
&c_pEffectData->v3EffectPosition);
}
else
{
int iBoneIndex;
DWORD dwPartIndex = 0;
if (FindBoneIndex(dwPartIndex, c_pEffectData->strAttachingBoneName.c_str(), &iBoneIndex))
{
D3DXMATRIX * pBoneMat;
GetBoneMatrix(dwPartIndex, iBoneIndex, &pBoneMat);
D3DXMATRIX matLocalPosition;
D3DXMatrixTranslation(&matLocalPosition, c_pEffectData->v3EffectPosition.x, c_pEffectData->v3EffectPosition.y, c_pEffectData->v3EffectPosition.z);
/////////////////////////////////////////////////////////////////////
D3DXMATRIX matWorld;
matWorld = *pBoneMat;
matWorld *= matLocalPosition;
matWorld *= m_worldMatrix;
/////////////////////////////////////////////////////////////////////
int iIndex = CEffectManager::Instance().CreateEffect(c_pEffectData->dwEffectIndex,
c_pEffectData->v3EffectPosition,
D3DXVECTOR3(0.0f, 0.0f, 0.0f));
CEffectManager::Instance().SelectEffectInstance(iIndex);
CEffectManager::Instance().SetEffectInstanceGlobalMatrix(matWorld);
}
}
}
else
{
AttachEffectByID(0, NULL, c_pEffectData->dwEffectIndex, &c_pEffectData->v3EffectPosition);
}
}
void CActorInstance::ProcessMotionEventEffectToTargetEvent(const CRaceMotionData::TMotionEventData * c_pData)
{
if (CRaceMotionData::MOTION_EVENT_TYPE_EFFECT_TO_TARGET != c_pData->iType)
return;
const CRaceMotionData::TMotionEffectToTargetEventData * c_pEffectToTargetData = (const CRaceMotionData::TMotionEffectToTargetEventData *)c_pData;
if (c_pEffectToTargetData->isFishingEffect)
{
CEffectManager& rkEftMgr=CEffectManager::Instance();
if (-1 != m_iFishingEffectID)
{
rkEftMgr.DeactiveEffectInstance(m_iFishingEffectID);
}
m_iFishingEffectID = rkEftMgr.CreateEffect(c_pEffectToTargetData->dwEffectIndex, m_v3FishingPosition, D3DXVECTOR3(0.0f, 0.0f, 0.0f));
}
else
{
if (!m_kFlyTarget.IsValidTarget())
return;
if (c_pEffectToTargetData->isFollowing && IsFlyTargetObject())
{
CActorInstance * pTargetInstance = (CActorInstance *)m_kFlyTarget.GetFlyTarget();
D3DXVECTOR3 v3Position( c_pEffectToTargetData->v3EffectPosition.x,
c_pEffectToTargetData->v3EffectPosition.y,
c_pEffectToTargetData->v3EffectPosition.z);
pTargetInstance->AttachEffectByID(0, NULL, c_pEffectToTargetData->dwEffectIndex, &v3Position);
}
else
{
const D3DXVECTOR3 & c_rv3FlyTarget = m_kFlyTarget.GetFlyTargetPosition();
D3DXVECTOR3 v3Position( c_rv3FlyTarget.x + c_pEffectToTargetData->v3EffectPosition.x,
c_rv3FlyTarget.y + c_pEffectToTargetData->v3EffectPosition.y,
c_rv3FlyTarget.z + c_pEffectToTargetData->v3EffectPosition.z);
CEffectManager::Instance().CreateEffect(c_pEffectToTargetData->dwEffectIndex, v3Position, D3DXVECTOR3(0.0f, 0.0f, 0.0f));
}
}
}
void CActorInstance::ProcessMotionEventSpecialAttacking(int iMotionEventIndex, const CRaceMotionData::TMotionEventData * c_pData)
{
if (CRaceMotionData::MOTION_EVENT_TYPE_SPECIAL_ATTACKING != c_pData->iType)
return;
const CRaceMotionData::TMotionAttackingEventData * c_pAttackingData = (const CRaceMotionData::TMotionAttackingEventData *)c_pData;
float fRadian = D3DXToRadian(270.0f + 360.0f - GetRotation());
m_kSplashArea.isEnableHitProcess=c_pAttackingData->isEnableHitProcess;
m_kSplashArea.uSkill=m_kCurMotNode.uSkill;
m_kSplashArea.MotionKey = m_kCurMotNode.dwMotionKey;
m_kSplashArea.fDisappearingTime = GetLocalTime() + c_pAttackingData->fDurationTime;
m_kSplashArea.c_pAttackingEvent = c_pAttackingData;
m_kSplashArea.HittedInstanceMap.clear();
m_kSplashArea.SphereInstanceVector.clear();
m_kSplashArea.SphereInstanceVector.resize(c_pAttackingData->CollisionData.SphereDataVector.size());
for (DWORD i = 0; i < c_pAttackingData->CollisionData.SphereDataVector.size(); ++i)
{
const TSphereData & c_rSphereData = c_pAttackingData->CollisionData.SphereDataVector[i].GetAttribute();
CDynamicSphereInstance & rSphereInstance = m_kSplashArea.SphereInstanceVector[i];
rSphereInstance.fRadius = c_rSphereData.fRadius;
//rSphereInstance.v3Advance = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
rSphereInstance.v3Position.x = m_x + c_rSphereData.v3Position.x*sinf(fRadian) + c_rSphereData.v3Position.y*cosf(fRadian);
rSphereInstance.v3Position.y = m_y + c_rSphereData.v3Position.x*cosf(fRadian) - c_rSphereData.v3Position.y*sinf(fRadian);
rSphereInstance.v3Position.z = m_z + c_rSphereData.v3Position.z;
rSphereInstance.v3LastPosition = rSphereInstance.v3Position;
}
}
void CActorInstance::ProcessMotionEventSound(const CRaceMotionData::TMotionEventData * c_pData)
{
if (CRaceMotionData::MOTION_EVENT_TYPE_SOUND != c_pData->iType)
return;
const CRaceMotionData::TMotionSoundEventData * c_pSoundData = (const CRaceMotionData::TMotionSoundEventData *)c_pData;
Tracenf("PLAY SOUND: %s", c_pSoundData->strSoundFileName.c_str());
CSoundManager::Instance().PlaySound3D(m_x, m_y, m_z, c_pSoundData->strSoundFileName.c_str());
}
void CActorInstance::ProcessMotionEventFly(const CRaceMotionData::TMotionEventData * c_pData)
{
if (CRaceMotionData::MOTION_EVENT_TYPE_FLY != c_pData->iType)
return;
const CRaceMotionData::TMotionFlyEventData * c_pFlyData = (const CRaceMotionData::TMotionFlyEventData *)c_pData;
if (m_kFlyTarget.IsValidTarget())
{
CFlyingManager & rfm = CFlyingManager::Instance();
D3DXVECTOR3 v3Start(c_pFlyData->v3FlyPosition);
v3Start += m_v3Position;
if (c_pFlyData->isAttaching)
{
D3DXMATRIX * pBoneMat;
int iBoneIndex;
DWORD dwPartIndex = 0;
if (FindBoneIndex(dwPartIndex, c_pFlyData->strAttachingBoneName.c_str(), &iBoneIndex))
if (GetBoneMatrix(dwPartIndex,iBoneIndex,&pBoneMat))
{
v3Start.x += pBoneMat->_41;
v3Start.y += pBoneMat->_42;
v3Start.z += pBoneMat->_43;
}
}
CFlyingInstance * pInstance = rfm.CreateFlyingInstanceFlyTarget(c_pFlyData->dwFlyIndex,v3Start,m_kFlyTarget,true);
if (pInstance)
{
pInstance->SetEventHandler(m_pFlyEventHandler);
pInstance->SetOwner(this);
pInstance->SetSkillIndex(m_kCurMotNode.uSkill);
}
if (m_pFlyEventHandler)
{
m_pFlyEventHandler->OnShoot(m_kCurMotNode.uSkill);
}
}
else
{
//TraceError("ActorInstance::ProcessMotionEventFly No Target");
}
}
void CActorInstance::ProcessMotionEventWarp(const CRaceMotionData::TMotionEventData * c_pData)
{
if (CRaceMotionData::MOTION_EVENT_TYPE_WARP != c_pData->iType)
return;
// FIXME : TMotionWarpEventData로 뺄 변수 - [levites]
static const float sc_fDistanceFromTarget = 270.0f;
if (m_kFlyTarget.IsValidTarget())
{
D3DXVECTOR3 v3MainPosition(m_x, m_y, m_z);
const D3DXVECTOR3 & c_rv3TargetPosition = __GetFlyTargetPosition();
D3DXVECTOR3 v3Distance = c_rv3TargetPosition - v3MainPosition;
D3DXVec3Normalize(&v3Distance, &v3Distance);
TPixelPosition DestPixelPosition = c_rv3TargetPosition - (v3Distance * sc_fDistanceFromTarget);
// 2004.07.05.myevan.궁신탄영 맵에 끼이는 문제해결. 목표위치가 이동 못하는 곳일 경우 이동하지 않는다
IBackground& rkBG=GetBackground();
if (!rkBG.IsBlock(DestPixelPosition.x, -DestPixelPosition.y))
SetPixelPosition(DestPixelPosition);
LookAt(c_rv3TargetPosition.x, c_rv3TargetPosition.y);
__OnWarp();
}
else
{
//TraceError("ActorInstance::ProcessMotionEventFly No Target");
}
}
@@ -0,0 +1,119 @@
#include "StdAfx.h"
#include "ActorInstance.h"
const TPixelPosition& CActorInstance::NEW_GetLastPixelPositionRef()
{
GetBlendingPosition(&m_kPPosLast);
m_kPPosLast.y=-m_kPPosLast.y;
return m_kPPosLast;
}
const D3DXVECTOR3& CActorInstance::GetPositionVectorRef()
{
m_v3Pos.x=m_x;
m_v3Pos.y=m_y;
m_v3Pos.z=m_z;
return m_v3Pos;
}
const D3DXVECTOR3& CActorInstance::GetMovementVectorRef()
{
if (m_pkHorse)
return m_pkHorse->GetMovementVectorRef();
return m_v3Movement;
}
void CActorInstance::NEW_SetAtkPixelPosition(const TPixelPosition& c_rkPPosAtk)
{
m_kPPosAtk=c_rkPPosAtk;
}
void CActorInstance::SetCurPixelPosition(const TPixelPosition& c_rkPPosCur)
{
D3DXVECTOR3 v3PosCur;
v3PosCur.x=+c_rkPPosCur.x;
v3PosCur.y=-c_rkPPosCur.y;
v3PosCur.z=+c_rkPPosCur.z;
SetPixelPosition(v3PosCur);
}
void CActorInstance::NEW_SetSrcPixelPosition(const TPixelPosition& c_rkPPosSrc)
{
m_kPPosSrc=c_rkPPosSrc;
}
void CActorInstance::NEW_SetDstPixelPositionZ(float z)
{
m_kPPosDst.z=z;
}
void CActorInstance::NEW_SetDstPixelPosition(const TPixelPosition& c_rkPPosDst)
{
m_kPPosDst=c_rkPPosDst;
}
const TPixelPosition& CActorInstance::NEW_GetAtkPixelPositionRef()
{
return m_kPPosAtk;
}
const TPixelPosition& CActorInstance::NEW_GetSrcPixelPositionRef()
{
return m_kPPosSrc;
}
const TPixelPosition& CActorInstance::NEW_GetDstPixelPositionRef()
{
return m_kPPosDst;
}
const TPixelPosition& CActorInstance::NEW_GetCurPixelPositionRef()
{
m_kPPosCur.x=+m_x;
m_kPPosCur.y=-m_y;
m_kPPosCur.z=+m_z;
return m_kPPosCur;
}
void CActorInstance::GetPixelPosition(TPixelPosition * pPixelPosition)
{
pPixelPosition->x = m_x;
pPixelPosition->y = m_y;
pPixelPosition->z = m_z;
}
void CActorInstance::SetPixelPosition(const TPixelPosition& c_rPixelPos)
{
if (m_pkTree)
{
__SetTreePosition(c_rPixelPos.x, c_rPixelPos.y, c_rPixelPos.z);
}
if (m_pkHorse)
m_pkHorse->SetPixelPosition(c_rPixelPos);
m_x = c_rPixelPos.x;
m_y = c_rPixelPos.y;
m_z = c_rPixelPos.z;
m_bNeedUpdateCollision = TRUE;
}
void CActorInstance::__InitializePositionData()
{
m_dwShakeTime = 0;
m_x = 0.0f;
m_y = 0.0f;
m_z = 0.0f;
m_bNeedUpdateCollision = FALSE;
m_kPPosAtk=m_kPPosLast=m_kPPosDst=m_kPPosCur=m_kPPosSrc=TPixelPosition(0.0f, 0.0f, 0.0f);
__InitializeMovement();
}
@@ -0,0 +1,385 @@
#include "StdAfx.h"
#include "../EterLib/StateManager.h"
#include "ActorInstance.h"
bool CActorInstance::ms_isDirLine=false;
bool CActorInstance::IsDirLine()
{
return ms_isDirLine;
}
void CActorInstance::ShowDirectionLine(bool isVisible)
{
ms_isDirLine=isVisible;
}
void CActorInstance::SetMaterialColor(DWORD dwColor)
{
if (m_pkHorse)
m_pkHorse->SetMaterialColor(dwColor);
m_dwMtrlColor&=0xff000000;
m_dwMtrlColor|=(dwColor&0x00ffffff);
}
void CActorInstance::SetMaterialAlpha(DWORD dwAlpha)
{
m_dwMtrlAlpha=dwAlpha;
}
void CActorInstance::OnRender()
{
D3DMATERIAL8 kMtrl;
STATEMANAGER.GetMaterial(&kMtrl);
kMtrl.Diffuse=D3DXCOLOR(m_dwMtrlColor);
STATEMANAGER.SetMaterial(&kMtrl);
// 현재는 이렇게.. 최종적인 형태는 Diffuse와 Blend의 분리로..
// 아니면 이런 형태로 가되 Texture & State Sorting 지원으로.. - [levites]
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
switch(m_iRenderMode)
{
case RENDER_MODE_NORMAL:
BeginDiffuseRender();
RenderWithOneTexture();
EndDiffuseRender();
BeginOpacityRender();
BlendRenderWithOneTexture();
EndOpacityRender();
break;
case RENDER_MODE_BLEND:
if (m_fAlphaValue == 1.0f)
{
BeginDiffuseRender();
RenderWithOneTexture();
EndDiffuseRender();
BeginOpacityRender();
BlendRenderWithOneTexture();
EndOpacityRender();
}
else if (m_fAlphaValue > 0.0f)
{
BeginBlendRender();
RenderWithOneTexture();
BlendRenderWithOneTexture();
EndBlendRender();
}
break;
case RENDER_MODE_ADD:
BeginAddRender();
RenderWithOneTexture();
BlendRenderWithOneTexture();
EndAddRender();
break;
case RENDER_MODE_MODULATE:
BeginModulateRender();
RenderWithOneTexture();
BlendRenderWithOneTexture();
EndModulateRender();
break;
}
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
kMtrl.Diffuse=D3DXCOLOR(0xffffffff);
STATEMANAGER.SetMaterial(&kMtrl);
if (ms_isDirLine)
{
D3DXVECTOR3 kD3DVt3Cur(m_x, m_y, m_z);
D3DXVECTOR3 kD3DVt3LookDir(0.0f, -1.0f, 0.0f);
D3DXMATRIX kD3DMatLook;
D3DXMatrixRotationZ(&kD3DMatLook, D3DXToRadian(GetRotation()));
D3DXVec3TransformCoord(&kD3DVt3LookDir, &kD3DVt3LookDir, &kD3DMatLook);
D3DXVec3Scale(&kD3DVt3LookDir, &kD3DVt3LookDir, 200.0f);
D3DXVec3Add(&kD3DVt3LookDir, &kD3DVt3LookDir, &kD3DVt3Cur);
D3DXVECTOR3 kD3DVt3AdvDir(0.0f, -1.0f, 0.0f);
D3DXMATRIX kD3DMatAdv;
D3DXMatrixRotationZ(&kD3DMatAdv, D3DXToRadian(GetAdvancingRotation()));
D3DXVec3TransformCoord(&kD3DVt3AdvDir, &kD3DVt3AdvDir, &kD3DMatAdv);
D3DXVec3Scale(&kD3DVt3AdvDir, &kD3DVt3AdvDir, 200.0f);
D3DXVec3Add(&kD3DVt3AdvDir, &kD3DVt3AdvDir, &kD3DVt3Cur);
static CScreen s_kScreen;
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE);
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
s_kScreen.SetDiffuseColor(1.0f, 1.0f, 0.0f);
s_kScreen.RenderLine3d(kD3DVt3Cur.x, kD3DVt3Cur.y, kD3DVt3Cur.z, kD3DVt3AdvDir.x, kD3DVt3AdvDir.y, kD3DVt3AdvDir.z);
s_kScreen.SetDiffuseColor(0.0f, 1.0f, 1.0f);
s_kScreen.RenderLine3d(kD3DVt3Cur.x, kD3DVt3Cur.y, kD3DVt3Cur.z, kD3DVt3LookDir.x, kD3DVt3LookDir.y, kD3DVt3LookDir.z);
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE);
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP);
STATEMANAGER.RestoreVertexShader();
}
}
void CActorInstance::BeginDiffuseRender()
{
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
void CActorInstance::EndDiffuseRender()
{
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
}
void CActorInstance::BeginOpacityRender()
{
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0);
STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
}
void CActorInstance::EndOpacityRender()
{
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC);
}
void CActorInstance::BeginBlendRender()
{
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(1.0f, 1.0f, 1.0f, m_fAlphaValue));
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
}
void CActorInstance::EndBlendRender()
{
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
}
void CActorInstance::BeginAddRender()
{
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, m_AddColor);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
void CActorInstance::EndAddRender()
{
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
}
void CActorInstance::RestoreRenderMode()
{
// NOTE : This is temporary code. I wanna convert this code to that restore the mode to
// model's default setting which had has as like specular or normal. - [levites]
m_iRenderMode = RENDER_MODE_NORMAL;
if (m_kBlendAlpha.m_isBlending)
{
m_kBlendAlpha.m_iOldRenderMode = m_iRenderMode;
}
}
void CActorInstance::SetAddRenderMode()
{
m_iRenderMode = RENDER_MODE_ADD;
if (m_kBlendAlpha.m_isBlending)
{
m_kBlendAlpha.m_iOldRenderMode = m_iRenderMode;
}
}
void CActorInstance::SetRenderMode(int iRenderMode)
{
m_iRenderMode = iRenderMode;
if (m_kBlendAlpha.m_isBlending)
{
m_kBlendAlpha.m_iOldRenderMode = iRenderMode;
}
}
void CActorInstance::SetAddColor(const D3DXCOLOR & c_rColor)
{
m_AddColor = c_rColor;
m_AddColor.a = 1.0f;
}
void CActorInstance::BeginModulateRender()
{
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, m_AddColor);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
void CActorInstance::EndModulateRender()
{
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
}
void CActorInstance::SetModulateRenderMode()
{
m_iRenderMode = RENDER_MODE_MODULATE;
if (m_kBlendAlpha.m_isBlending)
{
m_kBlendAlpha.m_iOldRenderMode = m_iRenderMode;
}
}
void CActorInstance::RenderCollisionData()
{
static CScreen s_Screen;
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
if (m_pAttributeInstance)
{
for (DWORD col=0; col < GetCollisionInstanceCount(); ++col)
{
CBaseCollisionInstance * pInstance = GetCollisionInstanceData(col);
pInstance->Render();
}
}
STATEMANAGER.SetRenderState(D3DRS_ZENABLE, FALSE);
s_Screen.SetColorOperation();
s_Screen.SetDiffuseColor(1.0f, 0.0f, 0.0f);
TCollisionPointInstanceList::iterator itor;
/*itor = m_AttackingPointInstanceList.begin();
for (; itor != m_AttackingPointInstanceList.end(); ++itor)
{
const TCollisionPointInstance & c_rInstance = *itor;
for (DWORD i = 0; i < c_rInstance.SphereInstanceVector.size(); ++i)
{
const CDynamicSphereInstance & c_rSphereInstance = c_rInstance.SphereInstanceVector[i];
s_Screen.RenderCircle3d(c_rSphereInstance.v3Position.x,
c_rSphereInstance.v3Position.y,
c_rSphereInstance.v3Position.z,
c_rSphereInstance.fRadius);
}
}*/
s_Screen.SetDiffuseColor(1.0f, (isShow())?1.0f:0.0f, 0.0f);
D3DXVECTOR3 center;
float r;
GetBoundingSphere(center,r);
s_Screen.RenderCircle3d(center.x,center.y,center.z,r);
s_Screen.SetDiffuseColor(0.0f, 0.0f, 1.0f);
itor = m_DefendingPointInstanceList.begin();
for (; itor != m_DefendingPointInstanceList.end(); ++itor)
{
const TCollisionPointInstance & c_rInstance = *itor;
for (DWORD i = 0; i < c_rInstance.SphereInstanceVector.size(); ++i)
{
const CDynamicSphereInstance & c_rSphereInstance = c_rInstance.SphereInstanceVector[i];
s_Screen.RenderCircle3d(c_rSphereInstance.v3Position.x,
c_rSphereInstance.v3Position.y,
c_rSphereInstance.v3Position.z,
c_rSphereInstance.fRadius);
}
}
s_Screen.SetDiffuseColor(0.0f, 1.0f, 0.0f);
itor = m_BodyPointInstanceList.begin();
for (; itor != m_BodyPointInstanceList.end(); ++itor)
{
const TCollisionPointInstance & c_rInstance = *itor;
for (DWORD i = 0; i < c_rInstance.SphereInstanceVector.size(); ++i)
{
const CDynamicSphereInstance & c_rSphereInstance = c_rInstance.SphereInstanceVector[i];
s_Screen.RenderCircle3d(c_rSphereInstance.v3Position.x,
c_rSphereInstance.v3Position.y,
c_rSphereInstance.v3Position.z,
c_rSphereInstance.fRadius);
}
}
s_Screen.SetDiffuseColor(1.0f, 0.0f, 0.0f);
// if (m_SplashArea.fDisappearingTime > GetLocalTime())
{
CDynamicSphereInstanceVector::iterator itor = m_kSplashArea.SphereInstanceVector.begin();
for (; itor != m_kSplashArea.SphereInstanceVector.end(); ++itor)
{
const CDynamicSphereInstance & c_rInstance = *itor;
s_Screen.RenderCircle3d(c_rInstance.v3Position.x,
c_rInstance.v3Position.y,
c_rInstance.v3Position.z,
c_rInstance.fRadius);
}
}
STATEMANAGER.SetRenderState(D3DRS_ZENABLE, TRUE);
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE);
}
void CActorInstance::RenderToShadowMap()
{
if (RENDER_MODE_BLEND == m_iRenderMode)
if (GetAlphaValue() < 0.5f)
return;
CGraphicThingInstance::RenderToShadowMap();
if (m_pkHorse)
m_pkHorse->RenderToShadowMap();
}
@@ -0,0 +1,128 @@
#include "StdAfx.h"
#include "ActorInstance.h"
void CActorInstance::SetXYRotation(float fRotX, float fRotY)
{
m_rotX = fRotX;
m_rotY = fRotY;
}
void CActorInstance::SetRotation(float fRot)
{
if (m_pkHorse)
m_pkHorse->SetRotation(fRot);
m_fcurRotation = fRot;
m_rotBegin = m_fcurRotation;
m_rotEnd = m_fcurRotation;
m_rotBlendTime = 0.0f;
m_rotBeginTime = 0.0f;
m_rotEndTime = 0.0f;
m_bNeedUpdateCollision = TRUE;
}
void CActorInstance::BlendRotation(float fRot, float fBlendTime)
{
if (m_pkHorse)
m_pkHorse->BlendRotation(fRot, fBlendTime);
if (m_fcurRotation == fRot)
return;
m_rotBegin = fmod(m_fcurRotation, 360.0f);
m_rotEnd = fRot;
m_rotBlendTime = fBlendTime;
m_rotBeginTime = GetLocalTime();
m_rotEndTime = m_rotBeginTime + m_rotBlendTime;
}
void CActorInstance::SetAdvancingRotation(float fRot)
{
if (m_pkHorse)
m_pkHorse->SetAdvancingRotation(fRot);
m_fAdvancingRotation = fRot;
}
void CActorInstance::RotationProcess()
{
if (m_pkHorse)
m_pkHorse->RotationProcess();
if (GetLocalTime() < m_rotEndTime)
{
m_fcurRotation = GetInterpolatedRotation(m_rotBegin, m_rotEnd, (GetLocalTime() - m_rotBeginTime) / m_rotBlendTime);
SetAdvancingRotation(m_fcurRotation);
}
else
{
m_fcurRotation = m_rotEnd;
}
// FIXME : "건물일때만 체크"로 바꾼다. - [levites]
if (0.0f != m_rotX || 0.0f != m_rotY)
{
CGraphicObjectInstance::SetRotation(m_rotX, m_rotY, m_fcurRotation);
}
else
{
CGraphicObjectInstance::SetRotation(m_fcurRotation);
}
}
void CActorInstance::LookAtFromXY(float x, float y, CActorInstance * pDestInstance)
{
float rot = GetDegreeFromPosition2(pDestInstance->m_x,
pDestInstance->m_y,
x,
y);
LookAt(rot);
}
void CActorInstance::LookAt(float fDirRot)
{
BlendRotation(fDirRot, 0.3f);
}
void CActorInstance::LookAt(float fx, float fy)
{
float rot = GetDegreeFromPosition2(m_x, m_y, fx, fy);
LookAt(rot);
}
void CActorInstance::LookAt(CActorInstance * pInstance)
{
TPixelPosition PixelPosition;
pInstance->GetPixelPosition(&PixelPosition);
LookAt(PixelPosition.x, PixelPosition.y);
}
void CActorInstance::LookWith(CActorInstance * pInstance)
{
BlendRotation(pInstance->m_rotEnd, 0.3f);
}
float CActorInstance::GetRotation()
{
return m_fcurRotation;
}
float CActorInstance::GetTargetRotation()
{
return m_rotEnd;
}
float CActorInstance::GetRotatingTime()
{
return m_rotEndTime;
}
float CActorInstance::GetAdvancingRotation()
{
return m_fAdvancingRotation;
}
@@ -0,0 +1,76 @@
#include "StdAfx.h"
#include "ActorInstance.h"
#include "RaceData.h"
void CActorInstance::__Push(int x, int y)
{
if (IsResistFallen())
return;
//DWORD dwVID=GetVirtualID();
//Tracenf("VID %d SyncPixelPosition %d %d", dwVID, x, y);
const D3DXVECTOR3& c_rv3Src=GetPosition();
const D3DXVECTOR3 c_v3Dst=D3DXVECTOR3(x, -y, c_rv3Src.z);
const D3DXVECTOR3 c_v3Delta=c_v3Dst-c_rv3Src;
const int LoopValue = 100;
const D3DXVECTOR3 inc=c_v3Delta / LoopValue;
D3DXVECTOR3 v3Movement(0.0f, 0.0f, 0.0f);
IPhysicsWorld* pWorld = IPhysicsWorld::GetPhysicsWorld();
if (!pWorld)
{
return;
}
for(int i = 0; i < LoopValue; ++i)
{
if (pWorld->isPhysicalCollision(c_rv3Src + v3Movement))
{
ResetBlendingPosition();
return;
}
v3Movement += inc;
}
SetBlendingPosition(c_v3Dst);
if (!IsUsingSkill())
{
int len=sqrt(c_v3Delta.x*c_v3Delta.x+c_v3Delta.y*c_v3Delta.y);
if (len>150.0f)
{
InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING);
PushOnceMotion(CRaceMotionData::NAME_STAND_UP);
}
}
}
void CActorInstance::TEMP_Push(int x, int y)
{
__Push(x, y);
}
bool CActorInstance::__IsSyncing()
{
if (IsDead())
return TRUE;
if (IsStun())
return TRUE;
if (IsPushing())
return TRUE;
return FALSE;
}
bool CActorInstance::IsPushing()
{
return m_PhysicsObject.isBlending();
}
@@ -0,0 +1,40 @@
#include "StdAfx.h"
#include "ActorInstance.h"
#include "WeaponTrace.h"
void CActorInstance::TraceProcess()
{
if (!m_WeaponTraceVector.empty())
{
std::vector<CWeaponTrace*>::iterator it;
for(it = m_WeaponTraceVector.begin(); it != m_WeaponTraceVector.end(); ++it)
{
CWeaponTrace * pWeaponTrace = (*it);
pWeaponTrace->SetPosition(m_x, m_y, m_z);
pWeaponTrace->SetRotation(m_fcurRotation);
pWeaponTrace->Update(__GetReachScale());
}
}
}
void CActorInstance::RenderTrace()
{
for_each(m_WeaponTraceVector.begin(), m_WeaponTraceVector.end(), std::mem_fn(&CWeaponTrace::Render));
}
void CActorInstance::__DestroyWeaponTrace()
{
std::for_each(m_WeaponTraceVector.begin(), m_WeaponTraceVector.end(), CWeaponTrace::Delete);
m_WeaponTraceVector.clear();
}
void CActorInstance::__ShowWeaponTrace()
{
for_each(m_WeaponTraceVector.begin(), m_WeaponTraceVector.end(), std::mem_fn(&CWeaponTrace::TurnOn));
}
void CActorInstance::__HideWeaponTrace()
{
for_each(m_WeaponTraceVector.begin(), m_WeaponTraceVector.end(), std::mem_fn(&CWeaponTrace::TurnOff));
}
+114
View File
@@ -0,0 +1,114 @@
#include "StdAfx.h"
#include "FlyTarget.h"
CFlyTarget::CFlyTarget()
{
__Initialize();
}
CFlyTarget::CFlyTarget(IFlyTargetableObject * pFlyTarget)
{
__Initialize();
m_eType=TYPE_OBJECT;
m_pFlyTarget=pFlyTarget;
m_pFlyTarget->AddFlyTargeter(this);
}
CFlyTarget::CFlyTarget(const D3DXVECTOR3& v3FlyTargetPosition)
{
__Initialize();
m_eType=TYPE_POSITION;
m_v3FlyTargetPosition=v3FlyTargetPosition;
}
CFlyTarget::CFlyTarget(const CFlyTarget& rhs)
{
__Initialize();
*this = rhs;
}
CFlyTarget::~CFlyTarget()
{
if (m_pFlyTarget)
m_pFlyTarget->RemoveFlyTargeter(this);
}
void CFlyTarget::__Initialize()
{
m_v3FlyTargetPosition=D3DXVECTOR3(0.0f,0.0f,0.0f);
m_pFlyTarget=NULL;
m_eType=TYPE_NONE;
}
void CFlyTarget::Clear()
{
m_eType = TYPE_NONE;
m_pFlyTarget = 0;
}
bool CFlyTarget::IsObject()
{
return (TYPE_OBJECT==GetType());
}
bool CFlyTarget::IsPosition()
{
return (TYPE_POSITION==GetType());
}
bool CFlyTarget::IsValidTarget()
{
return (TYPE_NONE!=GetType());
}
void CFlyTarget::NotifyTargetClear()
{
//if (m_eType == FLY_TARGET_TYPE_OBJECT)
m_eType = TYPE_POSITION;
m_pFlyTarget = 0;
}
CFlyTarget::EType CFlyTarget::GetType()
{
return m_eType;
}
IFlyTargetableObject* CFlyTarget::GetFlyTarget()
{
assert(TYPE_OBJECT==GetType() && "CFly::GetFlyTarget");
return m_pFlyTarget;
}
const D3DXVECTOR3 & CFlyTarget::GetFlyTargetPosition() const
{
if (m_eType == TYPE_OBJECT)
{
m_v3FlyTargetPosition = m_pFlyTarget->OnGetFlyTargetPosition();
}
return m_v3FlyTargetPosition;
}
CFlyTarget & CFlyTarget::operator = (const CFlyTarget & rhs)
{
if (m_pFlyTarget)
{
m_pFlyTarget->RemoveFlyTargeter(this);
}
m_eType = rhs.m_eType;
m_v3FlyTargetPosition = rhs.m_v3FlyTargetPosition;
m_pFlyTarget = rhs.m_pFlyTarget;
if (m_pFlyTarget)
{
m_pFlyTarget->AddFlyTargeter(this);
}
return *this;
}
void CFlyTarget::GetFlyTargetData(CFlyTarget * pFlyTarget)
{
pFlyTarget->m_eType = m_eType;
pFlyTarget->m_v3FlyTargetPosition = m_v3FlyTargetPosition;
pFlyTarget->m_pFlyTarget = m_pFlyTarget;
}
+111
View File
@@ -0,0 +1,111 @@
#pragma once
#include "FlyTarget.h"
#include "ActorInstanceInterface.h"
class CFlyingData;
class CFlyTrace;
class IFlyEventHandler;
class CActorInstance;
class CFlyingInstance
{
public:
// 2004. 3. 26. myevan. 적절한 네이밍이 필요. 게임에서 사용하지 않는다면 툴에서 툴 전용으로 상속받아 만들도록 하자
void Clear(); // Destroy와 같다
void SetDataPointer(CFlyingData * pData, const D3DXVECTOR3 & v3StartPosition);
void SetFlyTarget(const CFlyTarget & cr_Target); // Shot at Target
public:
friend class CSceneFly;
struct TAttachEffectInstance
{
int iAttachIndex;
DWORD dwEffectInstanceIndex;
CFlyTrace * pFlyTrace;
};
CFlyingInstance();
virtual ~CFlyingInstance();
void Destroy();
void Create(CFlyingData* pData, const D3DXVECTOR3& c_rv3StartPos, const CFlyTarget & c_rkTarget, bool canAttack);
bool Update();
void Render();
bool IsAlive() { return m_bAlive; }
const D3DXVECTOR3 & GetPosition() { return m_v3Position; }
void AdjustDirectionForHoming(const D3DXVECTOR3 & v3TargetPosition);
typedef std::vector<TAttachEffectInstance> TAttachEffectInstanceVector;
void BuildAttachInstance();
void UpdateAttachInstance();
void RenderAttachInstance();
void ClearAttachInstance();
void SetEventHandler(IFlyEventHandler * pHandler) { m_pHandler = pHandler; }
void ClearEventHandler() { m_pHandler = 0; }
void SetPierceCount(int iCount) { m_iPierceCount = iCount; }
void SetOwner(IActorInstance * pOwner) { m_pOwner = pOwner; }
void SetSkillIndex(DWORD dwIndex) { m_dwSkillIndex = dwIndex; }
// FIXME : 툴에서 사용하고 있습니다. 임시로 위로.. - [levites]
void __Explode(bool bBomb=true);
void __Bomb();
DWORD ID;
protected:
void __Initialize();
void __SetDataPointer(CFlyingData * pData, const D3DXVECTOR3 & v3StartPosition);
void __SetTargetDirection(const CFlyTarget& c_rkTarget);
void __SetTargetNormalizedDirection(const D3DXVECTOR3 & v3NormalizedDirection ); // 시작 타겟 방향 설정
protected:
CFlyingData * m_pData;
D3DXQUATERNION m_qRot;
float m_fStartTime;
bool m_bAlive;
bool m_canAttack;
int m_iPierceCount;
DWORD m_dwSkillIndex;
D3DXVECTOR3 m_v3Position;
D3DXVECTOR3 m_v3Velocity;
D3DXVECTOR3 m_v3LocalVelocity;
D3DXVECTOR3 m_v3Accel;
float m_fRemainRange;
CFlyTarget m_FlyTarget;
D3DXQUATERNION m_qAttachRotation;
TAttachEffectInstanceVector m_vecAttachEffectInstance;
IFlyEventHandler * m_pHandler;
IActorInstance * m_pOwner;
BOOL m_bTargetHitted;
std::set<IActorInstance *> m_HittedObjectSet;
public:
static CFlyingInstance * New() { return ms_kPool.Alloc(); }
static void Delete(CFlyingInstance * pInstance) { pInstance->Destroy(); ms_kPool.Free(pInstance); }
static void DestroySystem() { ms_kPool.Destroy(); }
static CDynamicPool<CFlyingInstance> ms_kPool;
};
@@ -0,0 +1,36 @@
#include "StdAfx.h"
#include "GameEventManager.h"
void CGameEventManager::SetCenterPosition(float fx, float fy, float fz)
{
m_CenterPosition.x = +fx;
m_CenterPosition.y = -fy;
m_CenterPosition.z = +fz;
}
void CGameEventManager::Update()
{
}
void CGameEventManager::ProcessEventScreenWaving(CActorInstance * pActorInstance, const CRaceMotionData::TScreenWavingEventData * c_pData)
{
TPixelPosition PixelPosition;
pActorInstance->GetPixelPosition(&PixelPosition);
float fdx = PixelPosition.x - m_CenterPosition.x;
float fdy = PixelPosition.y - m_CenterPosition.y;
float fdz = PixelPosition.z - m_CenterPosition.z;
if (fdx * fdx + fdy * fdy + fdz * fdz > c_pData->iAffectingRange * c_pData->iAffectingRange)
return;
SetScreenEffectWaving(c_pData->fDurationTime, c_pData->iPower);
}
CGameEventManager::CGameEventManager() : m_CenterPosition(0.0f, 0.0f, 0.0f)
{
}
CGameEventManager::~CGameEventManager()
{
}
+434
View File
@@ -0,0 +1,434 @@
#include "StdAfx.h"
#include "../EterLib/lineintersect_utils.h"
#include "GameUtil.h"
bool DetectCollisionDynamicZCylinderVSDynamicZCylinder(const CDynamicSphereInstance & c_rSphere1, const CDynamicSphereInstance & c_rSphere2)
{
CDynamicSphereInstance c_rCylinder1=c_rSphere1;
CDynamicSphereInstance c_rCylinder2=c_rSphere2;
c_rCylinder1.v3Position.z=0;
c_rCylinder1.v3LastPosition.z=0;
c_rCylinder2.v3Position.z=0;
c_rCylinder2.v3LastPosition.z=0;
float r = c_rCylinder1.fRadius+c_rCylinder2.fRadius;
float rsq = r*r;
// AABB check
D3DXVECTOR3 mi1=c_rCylinder1.v3LastPosition, mi2 = c_rCylinder1.v3Position;
D3DXVECTOR3 mi3=c_rCylinder2.v3LastPosition, mi4 = c_rCylinder2.v3Position;
if (mi1.x>mi2.x) std::swap(mi1.x,mi2.x);
if (mi1.y>mi2.y) std::swap(mi1.y,mi2.y);
if (mi1.z>mi2.z) std::swap(mi1.z,mi2.z);
if (mi3.x>mi4.x) std::swap(mi3.x,mi4.x);
if (mi3.y>mi4.y) std::swap(mi3.y,mi4.y);
if (mi3.z>mi4.z) std::swap(mi3.z,mi4.z);
mi1.x -= c_rCylinder1.fRadius; mi1.y -= c_rCylinder1.fRadius; mi1.z -= c_rCylinder1.fRadius;
mi2.x += c_rCylinder1.fRadius; mi2.y += c_rCylinder1.fRadius; mi2.z += c_rCylinder1.fRadius;
mi3.x -= c_rCylinder2.fRadius; mi3.y -= c_rCylinder2.fRadius; mi3.z -= c_rCylinder2.fRadius;
mi4.x += c_rCylinder2.fRadius; mi4.y += c_rCylinder2.fRadius; mi4.z += c_rCylinder2.fRadius;
if (mi4.x<mi1.x || mi2.x<mi3.x) return false;
if (mi4.y<mi1.y || mi2.y<mi3.y) return false;
if (mi4.z<mi1.z || mi2.z<mi3.z) return false;
D3DXVECTOR3 vA, vB;
IntersectLineSegments(c_rCylinder1.v3LastPosition, c_rCylinder1.v3Position,
c_rCylinder2.v3LastPosition, c_rCylinder2.v3Position,
vA, vB);
const auto vv = (vA - vB);
return (D3DXVec3LengthSq(&vv)<=rsq);
}
bool DetectCollisionDynamicSphereVSDynamicSphere(const CDynamicSphereInstance & c_rSphere1, const CDynamicSphereInstance & c_rSphere2)
{
float r = c_rSphere1.fRadius+c_rSphere2.fRadius;
float rsq = r*r;
/*if (D3DXVec3LengthSq(&(c_rSphere1.v3Position -c_rSphere2.v3Position ))<=rsq) return true;
if (D3DXVec3LengthSq(&(c_rSphere1.v3Position -c_rSphere2.v3LastPosition ))<=rsq) return true;
if (D3DXVec3LengthSq(&(c_rSphere1.v3LastPosition -c_rSphere2.v3Position ))<=rsq) return true;
if (D3DXVec3LengthSq(&(c_rSphere1.v3LastPosition -c_rSphere2.v3LastPosition ))<=rsq) return true;*/
/*
if (square_distance_between_linesegment_and_point(
c_rSphere1.v3Position,
c_rSphere1.v3LastPosition,
c_rSphere2.v3Position
)<=rsq) return true;
if (square_distance_between_linesegment_and_point(
c_rSphere1.v3Position,
c_rSphere1.v3LastPosition,
c_rSphere2.v3LastPosition
)<=rsq) return true;
if (square_distance_between_linesegment_and_point(
c_rSphere2.v3Position,
c_rSphere2.v3LastPosition,
c_rSphere1.v3Position
)<=rsq) return true;
if (square_distance_between_linesegment_and_point(
c_rSphere2.v3Position,
c_rSphere2.v3LastPosition,
c_rSphere1.v3LastPosition
)<=rsq) return true;
D3DXVECTOR3 da=c_rSphere1.v3Position-c_rSphere1.v3LastPosition;
D3DXVECTOR3 db=c_rSphere2.v3Position-c_rSphere2.v3LastPosition;
D3DXVECTOR3 n;
float la = D3DXVec3Length(&da);
float lb = D3DXVec3Length(&db);
if (la==0||lb==0)
{
D3DXVECTOR3 vA, vB;
IntersectLineSegments(
c_rSphere1.v3LastPosition.x,c_rSphere1.v3LastPosition.y,c_rSphere1.v3LastPosition.z,
c_rSphere1.v3Position.x, c_rSphere1.v3Position.y, c_rSphere1.v3Position.z,
c_rSphere2.v3LastPosition.x,c_rSphere2.v3LastPosition.y,c_rSphere2.v3LastPosition.z,
c_rSphere2.v3Position.x, c_rSphere2.v3Position.y, c_rSphere2.v3Position.z,
false, 1.e-5f, vA.x, vA.y, vA.z, vB.x, vB.y, vB.z);
return (D3DXVec3LengthSq(&(vA-vB))<=r*r);
}
D3DXVECTOR3 p=c_rSphere2.v3Position - c_rSphere1.v3LastPosition;
D3DXVec3Cross(&n, &da, &db);
float from_plane = D3DXVec3Dot(&n,&p)/la/lb;
if (from_plane>r || from_plane<-r)
return false;
p-=(from_plane/la/lb)*n;
float ta = D3DXVec3Dot(&p,&da)/la/la;
float tb = D3DXVec3Dot(&p,&db)/lb/lb;
// FIXME 구 체크가 아니다
if (ta<0)
return false;
if (tb<0)
return false;
if (ta>1)
return false;
if (tb>1)
return false;
return true;
*/
//*/
// using gpg line-collision
// AABB check
D3DXVECTOR3 mi1=c_rSphere1.v3LastPosition, mi2 = c_rSphere1.v3Position;
D3DXVECTOR3 mi3=c_rSphere2.v3LastPosition, mi4 = c_rSphere2.v3Position;
if (mi1.x>mi2.x) std::swap(mi1.x,mi2.x);
if (mi1.y>mi2.y) std::swap(mi1.y,mi2.y);
if (mi1.z>mi2.z) std::swap(mi1.z,mi2.z);
if (mi3.x>mi4.x) std::swap(mi3.x,mi4.x);
if (mi3.y>mi4.y) std::swap(mi3.y,mi4.y);
if (mi3.z>mi4.z) std::swap(mi3.z,mi4.z);
mi1.x -= c_rSphere1.fRadius; mi1.y -= c_rSphere1.fRadius; mi1.z -= c_rSphere1.fRadius;
mi2.x += c_rSphere1.fRadius; mi2.y += c_rSphere1.fRadius; mi2.z += c_rSphere1.fRadius;
mi3.x -= c_rSphere2.fRadius; mi3.y -= c_rSphere2.fRadius; mi3.z -= c_rSphere2.fRadius;
mi4.x += c_rSphere2.fRadius; mi4.y += c_rSphere2.fRadius; mi4.z += c_rSphere2.fRadius;
if (mi4.x<mi1.x || mi2.x<mi3.x) return false;
if (mi4.y<mi1.y || mi2.y<mi3.y) return false;
if (mi4.z<mi1.z || mi2.z<mi3.z) return false;
D3DXVECTOR3 vA, vB;/*
IntersectLineSegments(
c_rSphere1.v3LastPosition.x,c_rSphere1.v3LastPosition.y,c_rSphere1.v3LastPosition.z,
c_rSphere1.v3Position.x, c_rSphere1.v3Position.y, c_rSphere1.v3Position.z,
c_rSphere2.v3LastPosition.x,c_rSphere2.v3LastPosition.y,c_rSphere2.v3LastPosition.z,
c_rSphere2.v3Position.x, c_rSphere2.v3Position.y, c_rSphere2.v3Position.z,
false, 1.e-1f, vA.x, vA.y, vA.z, vB.x, vB.y, vB.z);*/
IntersectLineSegments(c_rSphere1.v3LastPosition, c_rSphere1.v3Position,
c_rSphere2.v3LastPosition, c_rSphere2.v3Position,
vA, vB);
const auto vvv = (vA - vB);
return (D3DXVec3LengthSq(&vvv)<=rsq);
//*/
/*
// NOTE : AABB 체크 할 것
///////////////////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR3 v3Distance = c_rSphere1.v3Position - c_rSphere2.v3Position;
float fDistance = D3DXVec3Length(&v3Distance);
float fRadiusSummary = c_rSphere1.fRadius + c_rSphere2.fRadius;
if (fDistance < fRadiusSummary)
return true;
///////////////////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR3 v3LastDistance = c_rSphere1.v3LastPosition - c_rSphere2.v3LastPosition; // A
D3DXVECTOR3 v3Advance = c_rSphere1.v3Advance - c_rSphere2.v3Advance; // B
float fdotAdvanceAdvance = D3DXVec3Dot(&v3Advance, &v3Advance);
if (0.0f == fdotAdvanceAdvance)
return false;
float fdotDistanceAdvance = D3DXVec3Dot(&v3LastDistance, &v3Advance);
float fdotDistanceDistance = D3DXVec3Dot(&v3LastDistance, &v3LastDistance);
float Value1 = fdotDistanceAdvance - fdotAdvanceAdvance * (fdotDistanceDistance - (fRadiusSummary * fRadiusSummary));
if (Value1 < 0.0f)
return false;
float Value2 = (-fdotDistanceAdvance - sqrtf(Value1)) / fdotAdvanceAdvance;
if (Value2 < 0.0f)
return false;
if (Value2 >= 1.0f)
return false;
return true;*/
}
/*
// Dynamic VS Static
bool DetectCollisionDynamicSphereVSStaticPlane(const CDynamicSphereInstance & c_rSphere, const TPlaneData & c_rPlane)
{
D3DXVECTOR3 v3SpherePosition = c_rSphere.v3Position - c_rPlane.v3Position;
D3DXVECTOR3 v3SphereLastPosition = c_rSphere.v3LastPosition - c_rPlane.v3Position;
float fPosition1 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SpherePosition);
float fPosition2 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SphereLastPosition);
if (fPosition1 >0.0f && fPosition2 < 0.0f || fPosition1 <0.0f && fPosition2 >0.0f || (fPosition1) <= c_rSphere.fRadius && fPosition1 >= -c_rSphere.fRadius)
{
D3DXVECTOR3 v3QuadPosition1 = c_rSphere.v3Position - c_rPlane.v3QuadPosition[0];
D3DXVECTOR3 v3QuadPosition2 = c_rSphere.v3Position - c_rPlane.v3QuadPosition[3];
if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[0]) < c_rSphere.fRadius)
if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[1]) < c_rSphere.fRadius)
if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[2]) < c_rSphere.fRadius)
if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[3]) < c_rSphere.fRadius)
return true;
}
return false;
}
bool DetectCollisionDynamicSphereVSStaticSphere(const CDynamicSphereInstance & c_rSphere, const TSphereData & c_rSphereData)
{
D3DXVECTOR3 v3Distance = c_rSphere.v3Position - c_rSphereData.v3Position;
float fDistanceSq = D3DXVec3LengthSq(&v3Distance);
float fRadiusSummary = c_rSphere.fRadius + c_rSphereData.fRadius;
if (fDistanceSq < fRadiusSummary*fRadiusSummary)
return true;
//D3DXVECTOR3 v3LastDistance = c_rSphere.v3LastPosition - c_rSphereData.v3Position;
//if (D3DXVec3Dot(&v3LastDistance, &v3Distance) < 0.0f)
// return true;
return false;
}
bool DetectCollisionDynamicSphereVSStaticCylinder(const CDynamicSphereInstance & c_rSphere, const TCylinderData & c_rCylinderData)
{
if (c_rSphere.v3Position.z + c_rSphere.fRadius < c_rCylinderData.v3Position.z)
return false;
if (c_rSphere.v3Position.z - c_rSphere.fRadius > c_rCylinderData.v3Position.z + c_rCylinderData.fHeight)
return false;
D3DXVECTOR3 v3curDistance = c_rSphere.v3Position - c_rCylinderData.v3Position;
float fDistance = D3DXVec3Length(&v3curDistance);
if (fDistance <= c_rSphere.fRadius + c_rCylinderData.fRadius)
return true;
//D3DXVECTOR3 v3lastDistance = c_rSphere.v3LastPosition - c_rCylinderData.v3Position;
//if (D3DXVec3Dot(&v3curDistance, &v3lastDistance) < 0.0f)
// return true;
return false;
}
*/
/*
bool DetectCollisionDynamicSphereVSStaticBox(const TSphereInstance & c_rSphere, const TBoxData & c_rBoxData)
{
return false;
}
*/
// Static VS Static
/*
bool DetectCollisionStaticSphereVSStaticSphere(const TSphereData & c_rSphere1, const TSphereData & c_rSphere2)
{
D3DXVECTOR3 v3Distance = c_rSphere1.v3Position - c_rSphere2.v3Position;
float fDistance = D3DXVec3Length(&v3Distance);
if (fDistance < c_rSphere1.fRadius + c_rSphere2.fRadius)
return true;
return false;
}
bool DetectCollisionStaticSphereVSStaticCylinder(const TSphereData & c_rSphere, const TCylinderData & c_rCylinder)
{
return false;
}
*/
/*bool DetectCollisionStaticSphereVSStaticBox(const TSphereData & c_rSphere, const TBoxData & c_rBox)
{
return false;
}
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
bool IsCWAcuteAngle(float begin, float end)
{
// 360 - src + dest // 시계 반대 방향
// src - dest // 시계 방향
return ((360.0f - begin + end) > (begin - end));
}
bool IsCCWAcuteAngle(float begin, float end)
{
// abs(360 - dest + src) // 시계 방향
// dest - src // 시계 반대 방향
int fValue = abs((int) (360.0f - end + begin));
return fValue >= (end - begin) ? true : false;
}
bool IsCWRotation(float begin, float end)
{
return !IsCCWRotation(begin, end);
}
bool IsCCWRotation(float begin, float end)
{
// 180
// 270 90
// 0
//
// 시계 반대
return (begin - end < 0);
}
float GetInterpolatedRotation(float begin, float end, float curRate)
{
if (IsCCWRotation(begin, end))
{
if (IsCCWAcuteAngle(begin, end))
return GetLinearInterpolation(begin, end, curRate);
return (360.0f + GetLinearInterpolation(begin, end - 360.0f, curRate));
}
if (IsCWAcuteAngle(begin, end))
return GetLinearInterpolation(begin, end, curRate);
return GetLinearInterpolation(begin, end + 360.0f, curRate);
}
float GetDegreeFromPosition(float x, float y)
{
D3DXVECTOR3 vtDir(floor(x), floor(y), 0.0f);
D3DXVec3Normalize(&vtDir, &vtDir);
D3DXVECTOR3 vtStan(0, -1, 0);
float ret = D3DXToDegree(acosf(D3DXVec3Dot(&vtDir, &vtStan)));
if (vtDir.x < 0.0f)
ret = 360.0f - ret;
return ret;
}
float GetDegreeFromPosition2(float sx, float sy, float ex, float ey)
{
return GetDegreeFromPosition(ex - sx, ey - sy);
}
float GetDegreeDifference(float fSource, float fTarget)
{
if (fSource < 180.0f)
{
if (fTarget < fSource)
return fSource - fTarget;
else if(fTarget - fSource > 180.0f)
return (360.0f - (fTarget - fSource));
return fTarget - fSource;
}
else
{
if (fTarget > fSource)
return fTarget - fSource;
else if (fSource - fTarget > 180.0f)
{
return (360.0f - (fSource - fTarget));
}
return fSource - fTarget;
}
}
int GetRotatingDirection(float fSource, float fTarget)
{
if (fSource < 180.0f)
{
if (fTarget < fSource)
return DEGREE_DIRECTION_RIGHT;
else if((360.0f - fTarget) + fSource < 180.0f)
return DEGREE_DIRECTION_RIGHT;
return DEGREE_DIRECTION_LEFT;
}
else
{
if (fTarget > fSource)
{
return DEGREE_DIRECTION_LEFT;
}
else if ((360.0f - fSource) + fTarget < 180.0f)
{
return DEGREE_DIRECTION_LEFT;
}
return DEGREE_DIRECTION_RIGHT;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
float CameraRotationToCharacterRotation(float fCameraRotation)
{
return fmod((540.0f - fCameraRotation), 360.0f);
}
float CharacterRotationToCameraRotation(float fCharacterRotation)
{
return fmod((540.0f - fCharacterRotation), 360.0f);
}
/*
bool DetectCollisionDynamicSphereVSStaticPlane(const TSphereInstance & c_rSphere, const TPlaneData & c_rPlane)
{
D3DXVECTOR3 v3SpherePosition = c_rSphere.v3Position - c_rPlane.v3Position;
D3DXVECTOR3 v3SphereLastPosition = c_rSphere.v3LastPosition - c_rPlane.v3Position;
float fPosition1 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SpherePosition);
float fPosition2 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SphereLastPosition);
if (fPosition1 * fPosition2 < 0.0f || fabs(fPosition1) <= c_rSphere.fRadius)
{
float fT = -fPosition1 / D3DXVec3Dot(&c_rPlane.v3Normal, &c_rSphere.v3Advance);
D3DXVECTOR3 v3CollisionPosition = c_rSphere.v3LastPosition + c_rSphere.v3Advance * fT;
D3DXVECTOR3 v3QuadPosition1 = v3CollisionPosition - c_rPlane.v3BeginPosition;
D3DXVECTOR3 v3QuadPosition2 = v3CollisionPosition - c_rPlane.v3EndPosition;
D3DXVec3Normalize(&v3QuadPosition1, &v3QuadPosition1);
D3DXVec3Normalize(&v3QuadPosition2, &v3QuadPosition2);
if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[0]) < 0.0f)
if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[1]) < 0.0f)
if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[2]) < 0.0f)
if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[3]) < 0.0f)
{
return true;
}
}
return false;
}
*/
+307
View File
@@ -0,0 +1,307 @@
#include "StdAfx.h"
#include "MapUtil.h"
#include <float.h> // PORT: FLT_EPSILON below; MSVC's <windows.h> pulled it in transitively
void Environment_Init(SEnvironmentData& envData)
{
for (int i = 0; i < ENV_DIRLIGHT_NUM; ++i)
{
envData.bDirLightsEnable[i] = false;
envData.DirLights[i].Type = D3DLIGHT_DIRECTIONAL;
envData.DirLights[i].Direction = D3DXVECTOR3(0.5f, 0.5f, -0.5f);
envData.DirLights[i].Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
envData.DirLights[i].Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
envData.DirLights[i].Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
envData.DirLights[i].Ambient = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);
envData.DirLights[i].Range = 0.0f; // Used by Point Light & Spot Light
envData.DirLights[i].Falloff = 1.0f; // Used by Spot Light
envData.DirLights[i].Theta = 0.0f; // Used by Spot Light
envData.DirLights[i].Phi = 0.0f; // Used by Spot Light
envData.DirLights[i].Attenuation0 = 0.0f;
envData.DirLights[i].Attenuation1 = 1.0f;
envData.DirLights[i].Attenuation2 = 0.0f;
}
envData.Material.Diffuse = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f);
envData.Material.Ambient = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f);
envData.Material.Emissive = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f);
envData.Material.Specular = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
envData.Material.Power = 0.0f;
envData.bFogEnable = FALSE;
envData.bDensityFog = FALSE;
envData.m_fFogNearDistance = 25600.0f * 0.5f;
envData.m_fFogFarDistance = 25600.0f * 0.7f;
envData.FogColor = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);
envData.bFilteringEnable = FALSE;
envData.FilteringColor = D3DXCOLOR(0.3f, 0.1f, 0.1f, 0.0f);
envData.byFilteringAlphaSrc = D3DBLEND_ONE;
envData.byFilteringAlphaDest = D3DBLEND_ONE;
envData.fWindStrength = 0.2f;
envData.fWindRandom = 0.0f;
envData.v3SkyBoxScale = D3DXVECTOR3(3500.0f, 3500.0f, 3500.0f);
envData.bySkyBoxGradientLevelUpper = 0;
envData.bySkyBoxGradientLevelLower = 0;
envData.bSkyBoxTextureRenderMode = FALSE;
envData.v2CloudScale = D3DXVECTOR2(200000.0f, 200000.0f);
envData.fCloudHeight = 30000.0f;
envData.v2CloudTextureScale = D3DXVECTOR2(4.0f, 4.0f);
envData.v2CloudSpeed = D3DXVECTOR2(0.001f, 0.001f);
envData.strCloudTextureFileName = "";
envData.CloudGradientColor.m_FirstColor = .0f;
envData.CloudGradientColor.m_SecondColor = .0f;
envData.SkyBoxGradientColorVector.clear();
envData.bLensFlareEnable = FALSE;
envData.LensFlareBrightnessColor = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
envData.fLensFlareMaxBrightness = 1.0f;
envData.bMainFlareEnable = FALSE;
envData.strMainFlareTextureFileName = "";
envData.fMainFlareSize = 0.2f;
envData.bReserve = FALSE;
}
bool Environment_Load(SEnvironmentData& envData, const char* envFileName)
{
CTextFileLoader textLoader;
if (!textLoader.Load(envFileName))
return false;
textLoader.SetTop();
textLoader.GetTokenBoolean("reserved", &envData.bReserve);
if (textLoader.SetChildNode("directionallight"))
{
D3DVECTOR v3Dir;
textLoader.GetTokenDirection("direction", &v3Dir);
if (textLoader.SetChildNode("background"))
{
envData.DirLights[ENV_DIRLIGHT_BACKGROUND].Direction = v3Dir;
textLoader.GetTokenBoolean("enable", &envData.bDirLightsEnable[ENV_DIRLIGHT_BACKGROUND]);
textLoader.GetTokenColor("diffuse", &envData.DirLights[ENV_DIRLIGHT_BACKGROUND].Diffuse);
textLoader.GetTokenColor("ambient", &envData.DirLights[ENV_DIRLIGHT_BACKGROUND].Ambient);
textLoader.SetParentNode();
}
if (textLoader.SetChildNode("character"))
{
envData.DirLights[ENV_DIRLIGHT_CHARACTER].Direction = v3Dir;
textLoader.GetTokenBoolean("enable", &envData.bDirLightsEnable[ENV_DIRLIGHT_CHARACTER]);
textLoader.GetTokenColor("diffuse", &envData.DirLights[ENV_DIRLIGHT_CHARACTER].Diffuse);
textLoader.GetTokenColor("ambient", &envData.DirLights[ENV_DIRLIGHT_CHARACTER].Ambient);
textLoader.SetParentNode();
}
textLoader.SetParentNode();
}
if (textLoader.SetChildNode("material"))
{
textLoader.GetTokenColor("diffuse", &envData.Material.Diffuse);
textLoader.GetTokenColor("ambient", &envData.Material.Ambient);
textLoader.GetTokenColor("emissive", &envData.Material.Emissive);
textLoader.SetParentNode();
}
if (textLoader.SetChildNode("fog"))
{
textLoader.GetTokenBoolean("enable", &envData.bFogEnable);
textLoader.GetTokenBoolean("isdensity", &envData.bDensityFog);
textLoader.GetTokenFloat("neardistance", &envData.m_fFogNearDistance);
textLoader.GetTokenFloat("fardistance", &envData.m_fFogFarDistance);
textLoader.GetTokenColor("color", &envData.FogColor);
textLoader.SetParentNode();
}
if (textLoader.SetChildNode("filter"))
{
textLoader.GetTokenBoolean("enable", (BOOL *) &envData.bFilteringEnable);
textLoader.GetTokenColor("color", &envData.FilteringColor);
textLoader.GetTokenByte("alphasrc", &envData.byFilteringAlphaSrc);
textLoader.GetTokenByte("alphadest", &envData.byFilteringAlphaDest);
textLoader.SetParentNode();
}
if (textLoader.SetChildNode("skybox"))
{
textLoader.GetTokenBoolean("btexturerendermode", (BOOL *) &envData.bSkyBoxTextureRenderMode);
textLoader.GetTokenVector3("scale", &envData.v3SkyBoxScale);
textLoader.GetTokenByte("gradientlevelupper", &envData.bySkyBoxGradientLevelUpper);
textLoader.GetTokenByte("gradientlevellower", &envData.bySkyBoxGradientLevelLower);
textLoader.GetTokenString("frontfacefilename", &envData.strSkyBoxFaceFileName[0]);
textLoader.GetTokenString("backfacefilename", &envData.strSkyBoxFaceFileName[1]);
textLoader.GetTokenString("leftfacefilename", &envData.strSkyBoxFaceFileName[2]);
textLoader.GetTokenString("rightfacefilename", &envData.strSkyBoxFaceFileName[3]);
textLoader.GetTokenString("topfacefilename", &envData.strSkyBoxFaceFileName[4]);
textLoader.GetTokenString("bottomfacefilename", &envData.strSkyBoxFaceFileName[5]);
textLoader.GetTokenVector2("cloudscale", &envData.v2CloudScale);
textLoader.GetTokenFloat("cloudheight", &envData.fCloudHeight);
textLoader.GetTokenVector2("cloudtexturescale", &envData.v2CloudTextureScale);
textLoader.GetTokenVector2("cloudspeed", &envData.v2CloudSpeed);
textLoader.GetTokenString("cloudtexturefilename", &envData.strCloudTextureFileName);
CTokenVector * pTokenVectorCloudColor;
if(textLoader.GetTokenVector("cloudcolor", &pTokenVectorCloudColor))
if ( 0 == pTokenVectorCloudColor->size()%8)
{
envData.CloudGradientColor.m_FirstColor.r = atof(pTokenVectorCloudColor->at(0).c_str());
envData.CloudGradientColor.m_FirstColor.g = atof(pTokenVectorCloudColor->at(1).c_str());
envData.CloudGradientColor.m_FirstColor.b = atof(pTokenVectorCloudColor->at(2).c_str());
envData.CloudGradientColor.m_FirstColor.a = atof(pTokenVectorCloudColor->at(3).c_str());
envData.CloudGradientColor.m_SecondColor.r = atof(pTokenVectorCloudColor->at(4).c_str());
envData.CloudGradientColor.m_SecondColor.g = atof(pTokenVectorCloudColor->at(5).c_str());
envData.CloudGradientColor.m_SecondColor.b = atof(pTokenVectorCloudColor->at(6).c_str());
envData.CloudGradientColor.m_SecondColor.a = atof(pTokenVectorCloudColor->at(7).c_str());
}
BYTE byGradientCount = envData.bySkyBoxGradientLevelUpper+envData.bySkyBoxGradientLevelLower;
CTokenVector * pTokenVector;
if (textLoader.GetTokenVector("gradient", &pTokenVector))
if (0 == pTokenVector->size()%8)
if (byGradientCount == pTokenVector->size()/8)
{
envData.SkyBoxGradientColorVector.clear();
envData.SkyBoxGradientColorVector.resize(byGradientCount);
for (DWORD i = 0; i < byGradientCount; ++i)
{
envData.SkyBoxGradientColorVector[i].m_FirstColor.r = atof(pTokenVector->at(i*8+0).c_str());
envData.SkyBoxGradientColorVector[i].m_FirstColor.g = atof(pTokenVector->at(i*8+1).c_str());
envData.SkyBoxGradientColorVector[i].m_FirstColor.b = atof(pTokenVector->at(i*8+2).c_str());
envData.SkyBoxGradientColorVector[i].m_FirstColor.a = atof(pTokenVector->at(i*8+3).c_str());
envData.SkyBoxGradientColorVector[i].m_SecondColor.r = atof(pTokenVector->at(i*8+4).c_str());
envData.SkyBoxGradientColorVector[i].m_SecondColor.g = atof(pTokenVector->at(i*8+5).c_str());
envData.SkyBoxGradientColorVector[i].m_SecondColor.b = atof(pTokenVector->at(i*8+6).c_str());
envData.SkyBoxGradientColorVector[i].m_SecondColor.a = atof(pTokenVector->at(i*8+7).c_str());
}
}
textLoader.SetParentNode();
}
if (textLoader.SetChildNode("lensflare"))
{
textLoader.GetTokenBoolean("enable", &envData.bLensFlareEnable);
textLoader.GetTokenColor("brightnesscolor", &envData.LensFlareBrightnessColor);
textLoader.GetTokenFloat("maxbrightness", &envData.fLensFlareMaxBrightness);
textLoader.GetTokenBoolean("mainflareenable", &envData.bMainFlareEnable);
textLoader.GetTokenString("mainflaretexturefilename", &envData.strMainFlareTextureFileName);
textLoader.GetTokenFloat("mainflaresize", &envData.fMainFlareSize);
textLoader.SetParentNode();
}
return true;
}
void GetInterpolatedPosition(float curPositionRate, TPixelPosition * PixelPosition)
{
}
float GetLinearInterpolation(float begin, float end, float curRate)
{
return (end - begin) * curRate + begin;
}
void PixelPositionToAttributeCellPosition(TPixelPosition PixelPosition, TCellPosition * pAttrCellPosition)
{
pAttrCellPosition->x = PixelPosition.x / c_Section_xAttributeCellSize;
pAttrCellPosition->y = PixelPosition.y / c_Section_yAttributeCellSize;
}
void AttributeCellPositionToPixelPosition(TCellPosition AttrCellPosition, TPixelPosition * pPixelPosition)
{
pPixelPosition->x = AttrCellPosition.x * c_Section_xAttributeCellSize;
pPixelPosition->y = AttrCellPosition.y * c_Section_yAttributeCellSize;
}
float GetPixelPositionDistance(const TPixelPosition & c_rsrcPosition, const TPixelPosition & c_rdstPosition)
{
int idx = c_rsrcPosition.x - c_rdstPosition.x;
int idy = c_rsrcPosition.y - c_rdstPosition.y;
return sqrtf(float(idx*idx + idy*idy));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
CEaseOutInterpolation::CEaseOutInterpolation()
{
Initialize();
}
CEaseOutInterpolation::~CEaseOutInterpolation()
{
}
void CEaseOutInterpolation::Initialize()
{
m_fRemainingTime = 0.0f;
m_fValue = 0.0f;
m_fSpeed = 0.0f;
m_fAcceleration = 0.0f;
m_fStartValue = 0.0f;
m_fLastValue = 0.0f;
}
BOOL CEaseOutInterpolation::Setup(float fStart, float fEnd, float fTime)
{
//for safety
if( fabs(fTime) < FLT_EPSILON )
{
fTime = 0.01f;
}
m_fValue = fStart;
m_fStartValue = fStart;
m_fLastValue = fStart;
m_fSpeed = (2.0f * (fEnd - fStart)) / fTime;
m_fAcceleration = 2.0f * (fEnd - fStart) / (fTime * fTime) - 2.0f * m_fSpeed / fTime;
m_fRemainingTime = fTime;
return TRUE;
}
void CEaseOutInterpolation::Interpolate(float fElapsedTime)
{
m_fLastValue = m_fValue;
m_fRemainingTime -= fElapsedTime;
m_fSpeed += m_fAcceleration * fElapsedTime;
m_fValue += m_fSpeed * fElapsedTime;
if (!isPlaying())
{
m_fValue = 0.0f;
m_fLastValue = 0.0f;
}
}
BOOL CEaseOutInterpolation::isPlaying()
{
return m_fRemainingTime > 0.0f;
}
float CEaseOutInterpolation::GetValue()
{
return m_fValue;
}
float CEaseOutInterpolation::GetChangingValue()
{
return m_fValue - m_fLastValue;
}
@@ -0,0 +1,177 @@
#include "StdAfx.h"
#include "PhysicsObject.h"
const float c_fFrameTime = 0.02f;
const float EPSILON = 0.001f;
IPhysicsWorld* IPhysicsWorld::ms_pWorld = NULL;
IObjectManager* IObjectManager::ms_ObjManager = NULL;
void CPhysicsObject::Update(float fElapsedTime)
{
if (m_xPushingPosition.isPlaying())
m_xPushingPosition.Interpolate(fElapsedTime);
if (m_yPushingPosition.isPlaying())
m_yPushingPosition.Interpolate(fElapsedTime);
}
void CPhysicsObject::Accumulate(D3DXVECTOR3 * pv3Position)
{
// If object is moving, give minor power to object.
float fForce = 0.0f;
if (fabs(m_v3Velocity.x) < EPSILON ||
fabs(m_v3Velocity.y) < EPSILON ||
fabs(m_v3Velocity.z) < EPSILON )
{
fForce -= (m_fMass * m_fFriction);
}
m_v3Acceleration = m_v3Direction * (fForce / m_fMass);
m_v3Velocity += m_v3Acceleration;
if (m_v3Velocity.x * m_v3Direction.x < EPSILON)
{
m_v3Velocity.x = 0.0f;
m_v3Direction.x = 0.0f;
}
if (m_v3Velocity.y * m_v3Direction.y < EPSILON)
{
m_v3Velocity.y = 0.0f;
m_v3Direction.y = 0.0f;
}
if (m_v3Velocity.z * m_v3Direction.z < EPSILON)
{
m_v3Velocity.z = 0.0f;
m_v3Direction.z = 0.0f;
}
pv3Position->x += m_v3Velocity.x;
pv3Position->y += m_v3Velocity.y;
pv3Position->z += m_v3Velocity.z;
}
void CPhysicsObject::IncreaseExternalForce(const D3DXVECTOR3 & c_rvBasePosition, float fForce)
{
// Accumulate Acceleration by External Force
m_v3Acceleration = m_v3Direction * (fForce / m_fMass);
m_v3Velocity = m_v3Acceleration;
/*
Tracenf("force %f, mass %f, accel (%f, %f, %f)", fForce, m_fMass,
m_v3Acceleration.x,
m_v3Acceleration.y,
m_v3Acceleration.z);
*/
// NOTE : 최종 위치를 구해둔다. 근데 100보다 크다면? ;
const int LoopValue = 100;
D3DXVECTOR3 v3Movement(0.0f, 0.0f, 0.0f);
for(int i = 0; i < LoopValue; ++i)
{
Accumulate(&v3Movement);
// VICTIM_COLLISION_TEST
IPhysicsWorld* pWorld = IPhysicsWorld::GetPhysicsWorld();
if (pWorld)
{
if (pWorld->isPhysicalCollision(c_rvBasePosition + v3Movement))
{
Initialize();
return;
//for (float fRatio = 0.0f; fRatio < 1.0f; fRatio += 0.1f)
//{
// // 좀더 정밀하게 체크한다
// if (pWorld->isPhysicalCollision(c_rvBasePosition + v3Movement * fRatio))
// {
// v3Movement = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
// break;
// }
//}
//break;
}
}
// VICTIM_COLLISION_TEST_END
if (fabs(m_v3Velocity.x) < EPSILON &&
fabs(m_v3Velocity.y) < EPSILON &&
fabs(m_v3Velocity.z) < EPSILON )
break;
}
SetLastPosition(v3Movement, float(LoopValue) * c_fFrameTime);
if( m_pActorInstance )
{
IObjectManager* pObjectManager = IObjectManager::GetObjectManager();
pObjectManager->AdjustCollisionWithOtherObjects( m_pActorInstance );
}
}
void CPhysicsObject::SetLastPosition(const TPixelPosition & c_rPosition, float fBlendingTime)
{
m_v3LastPosition.x = float(c_rPosition.x);
m_v3LastPosition.y = float(c_rPosition.y);
m_v3LastPosition.z = float(c_rPosition.z);
m_xPushingPosition.Setup(0.0f, c_rPosition.x, fBlendingTime);
m_yPushingPosition.Setup(0.0f, c_rPosition.y, fBlendingTime);
}
void CPhysicsObject::GetLastPosition(TPixelPosition * pPosition)
{
pPosition->x = (m_v3LastPosition.x);
pPosition->y = (m_v3LastPosition.y);
pPosition->z = (m_v3LastPosition.z);
}
void CPhysicsObject::SetDirection(const D3DXVECTOR3 & c_rv3Direction)
{
m_v3Direction.x = c_rv3Direction.x;
m_v3Direction.y = c_rv3Direction.y;
m_v3Direction.z = c_rv3Direction.z;
}
float CPhysicsObject::GetXMovement()
{
return m_xPushingPosition.GetChangingValue();
}
float CPhysicsObject::GetYMovement()
{
return m_yPushingPosition.GetChangingValue();
}
bool CPhysicsObject::isBlending()
{
// NOTE : IncreaseExternalForce() 에 의해 밀리는 처리중인가?
if (0.0f != D3DXVec3Length(&m_v3Velocity))
return true;
// NOTE : SetLastPosition() 에 의해 밀리는 처리중인가?
if (m_xPushingPosition.isPlaying() ||
m_yPushingPosition.isPlaying())
return true;
return false;
}
void CPhysicsObject::Initialize()
{
m_fMass = 1.0f;
m_fFriction = 0.3f;
m_v3Direction = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_v3Acceleration = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_v3Velocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_v3LastPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_xPushingPosition.Initialize();
m_yPushingPosition.Initialize();
}
CPhysicsObject::CPhysicsObject()
{
m_pActorInstance = NULL;
}
CPhysicsObject::~CPhysicsObject()
{
}
+490
View File
@@ -0,0 +1,490 @@
#include "StdAfx.h"
#include "../EterLib/ResourceManager.h"
#include "../EterLib/StateManager.h"
#include "WeaponTrace.h"
CDynamicPool<CWeaponTrace> CWeaponTrace::ms_kPool;
void CWeaponTrace::DestroySystem()
{
ms_kPool.Destroy();
}
void CWeaponTrace::Delete(CWeaponTrace* pkWTDel)
{
assert(pkWTDel!=NULL && "CWeaponTrace::Delete");
pkWTDel->Clear();
ms_kPool.Free(pkWTDel);
}
CWeaponTrace* CWeaponTrace::New()
{
return ms_kPool.Alloc();
}
void CWeaponTrace::Update(float fReachScale)
{
float fElapsedTime = CTimer::Instance().GetCurrentSecond() - m_fLastUpdate;
m_fLastUpdate = CTimer::Instance().GetCurrentSecond();
if (!m_pInstance)
return;
{
// 잔상을 남기는 시간 범위 내의 점들만 유지합니다.
TTimePointList::iterator it;
for(it=m_ShortTimePointList.begin();it!=m_ShortTimePointList.end();++it)
{
it->first += fElapsedTime;
if (it->first>m_fLifeTime)
{
it++;
break;
}
}
if (it!=m_ShortTimePointList.end())
m_ShortTimePointList.erase(it,m_ShortTimePointList.end());
for(it=m_LongTimePointList.begin();it!=m_LongTimePointList.end();++it)
{
it->first += fElapsedTime;
if (it->first>m_fLifeTime)
{
it++;
break;
}
}
if (it!=m_LongTimePointList.end())
m_LongTimePointList.erase(it, m_LongTimePointList.end());
}
if (m_isPlaying && m_fz>=0.0001f)
{
D3DXMATRIX * pMatrix;
if (m_pInstance->GetCompositeBoneMatrix(m_dwModelInstanceIndex, m_iBoneIndex, &pMatrix))
{
D3DXMATRIX * pBoneMat;
m_pInstance->GetBoneMatrix(m_dwModelInstanceIndex, m_iBoneIndex, &pBoneMat);
D3DXMATRIX mat = *pMatrix;
mat._41 = pBoneMat->_41;
mat._42 = pBoneMat->_42;
mat._43 = pBoneMat->_43;
// 현재 위치를 추가합니다.
D3DXMATRIX matPoint;
D3DXMATRIX matTranslation;
D3DXMATRIX matRotation;
//D3DXMatrixTranslation(&matTranslation, 0.0f, m_fLength, 0.0f);
D3DXMatrixTranslation(&matTranslation, 0.0f, 0.0f, m_fLength*fReachScale);
D3DXMatrixRotationZ(&matRotation, D3DXToRadian(m_fRotation));
matPoint = /**pMatrix*/mat * matRotation;
/*TPDTVertex PDTVertex;
PDTVertex.position.x = m_fx + matPoint._41;
PDTVertex.position.y = m_fy + matPoint._42;
PDTVertex.position.z = m_fz + matPoint._43;
PDTVertex.diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 0.1f);
m_PDTVertexVector.push_back(PDTVertex);*/
m_ShortTimePointList.push_front(
TTimePoint(
0.0f,
D3DXVECTOR3(
m_fx + matPoint._41,
m_fy + matPoint._42,
m_fz + matPoint._43
)
)
);
matPoint = matTranslation * matPoint;
/*PDTVertex.position.x = m_fx + matPoint._41;
PDTVertex.position.y = m_fy + matPoint._42;
PDTVertex.position.z = m_fz + matPoint._43;
PDTVertex.diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 0.1f);
m_PDTVertexVector.push_back(PDTVertex);*/
m_LongTimePointList.push_front(
TTimePoint(
0.0f,
D3DXVECTOR3(
m_fx + matPoint._41,
m_fy + matPoint._42,
m_fz + matPoint._43
)
)
);
}
}
//if (!BuildVertex())
// return;
}
bool CWeaponTrace::BuildVertex()
{
const int max_size = 300;
// calculate speed
float h[max_size];
float stk[max_size];
int sp=0;
D3DXVECTOR3 r[max_size];
if (m_LongTimePointList.size()<=1)
return false;
//Tracef("## %f %f %f\n", m_LongTimePointList[0].second.x, m_LongTimePointList[0].second.y, m_LongTimePointList[0].second.z);
/*m_LongTimePointList.clear();
m_LongTimePointList.push_back(TTimePoint(0.00,D3DXVECTOR3(0,0,0)));
m_LongTimePointList.push_back(TTimePoint(0.01,D3DXVECTOR3(0,1,0)));
m_LongTimePointList.push_back(TTimePoint(0.04,D3DXVECTOR3(0,1,0)));
m_LongTimePointList.push_back(TTimePoint(0.05,D3DXVECTOR3(0,0,0)));
m_ShortTimePointList = m_LongTimePointList;
*/
std::vector<TPDTVertex> m_ShortVertexVector, m_LongVertexVector;
float length = min(m_fLifeTime, m_LongTimePointList.back().first);
int n = m_LongTimePointList.size()-1;
assert(n<max_size-1);
// cubic spline
for(int loop = 0; loop<=1; ++loop)
{
TTimePointList & Input = (loop) ? m_LongTimePointList : m_ShortTimePointList;
std::vector<TPDTVertex> & Output = (loop) ? m_LongVertexVector : m_ShortVertexVector;
TTimePointList::iterator it;
int i;
for(i=0;i<n;++i)
{
h[i] = Input[i+1].first - Input[i].first;
r[i] = (Input[i+1].second - Input[i].second)*(3/h[i]);
}
r[n] = D3DXVECTOR3(0.0f,0.0f,0.0f);
for(i=n;i>0;i--)
{
r[i]+=r[i-1];
}
float rate = 0.5f;
r[0] *= 0.5f;
stk[sp++] = rate;
for(i=1;i<n;i++)
{
r[i]-=r[i-1];
rate = 1/(4-rate);
r[i] *= rate;
stk[sp++]=rate;
}
r[n]-=r[n-1];
rate = 1/(2-rate);
r[n]*=rate;
for(i=n-1;i>=0;i--)
{
r[i] -= stk[--sp] * r[i+1];
}
int base = 0;
D3DXVECTOR3 a,b,c,d;
D3DXVECTOR3 v3Tmp = Input[base+1].second-Input[base].second;
float timebase=0,timenext=h[base], dt=m_fSamplingTime;
a = Input[base].second;
b = r[base];
c = ( 3*v3Tmp - r[base+1]*h[base] - (2*h[base])*r[base] )
* (1/(h[base]*h[base]));
d = ( -2*v3Tmp + (r[base+1]+r[base])*h[base])
* (1/(h[base]*h[base]*h[base]));
for(float t = 0; t<=length; t+=dt)
{
while (t>timenext)
{
timebase = timenext;
base++;
if (base>=n) break;
D3DXVECTOR3 v3Tmp = Input[base+1].second-Input[base].second;
a = Input[base].second;
b = r[base];
c = ( 3*v3Tmp - r[base+1]*h[base] - (2*h[base])*r[base] )
* (1/(h[base]*h[base]));
d = ( -2*v3Tmp + (r[base+1]+r[base])*h[base])
* (1/(h[base]*h[base]*h[base]));
timenext+=h[base];
if (loop)
{
//Tracef("%f:%f %f %f\n",Input[base].first,Input[base].second.x,Input[base].second.y,Input[base].second.z);
}
}
if (base>n) break;
float cc = t - timebase;
TPDTVertex v;
//v.diffuse = D3DXCOLOR(0.3f,0.8f,1.0f, (loop)?max(1.0f-(t/m_fLifeTime),0.0f)/2:0.0f );
float ttt = min(max((t+Input[0].first)/m_fLifeTime,0.0f),1.0f);
v.diffuse = D3DXCOLOR(0.3f,0.8f,1.0f, (loop)?min(max((1.0f-ttt)*(1.0f-ttt)/2.5-0.1f,0.0f),1.0f):0.0f );
//v.diffuse = D3DXCOLOR(0.0f,0.0f,0.0f, (loop)?min(max((1.0f-ttt)*(1.0f-ttt)-0.1f,0.0f),1.0f):0.0f );
//v.diffuse = 0xffffffff;
v.position = a+cc*(b+cc*(c+cc*d)); // next position
v.texCoord.x = t/m_fLifeTime;
v.texCoord.y = loop ? 0 : 1;
Output.push_back(v);
if (loop)
{
// Tracef("%f %f %f\n", timebase,t,timenext);
//Tracef("a:%f %f %f\nb:%f %f %f \nc:%f %f %f \nd:%f %f %f, \n",,a.x,a.y,a.z,b.x,b.y,b.z,c.x,c.y,c.z,d.x,d.y,d.z);
//Tracef("%f %f %f\n",v.position.x,v.position.y,v.position.z);
/*D3DXMATRIX * pBoneMat;
m_pInstance->GetBoneMatrix(m_dwModelInstanceIndex, 55, &pBoneMat);
D3DXVECTOR3 vbone(m_fx+pBoneMat->_41,m_fy+pBoneMat->_42,m_fz+pBoneMat->_43);
float len = D3DXVec3Length(&(v.position-vbone));*/
}
}
}
// build vertex
m_PDTVertexVector.clear();
/*
TTimePointList::iterator lit1,lit2, sit1,sit2;
lit2 = lit1 = m_LongTimePointList.begin();
++lit2;
sit2 = sit1 = m_ShortTimePointList.begin();
++sit2;
*/
std::vector<TPDTVertex>::iterator lit,sit;
for(lit = m_LongVertexVector.begin(), sit = m_ShortVertexVector.begin();
lit != m_LongVertexVector.end();
++lit,++sit)
{
m_PDTVertexVector.push_back(*lit);
m_PDTVertexVector.push_back(*sit);
/*float len = D3DXVec3Length(&(lit->position - sit->position));
if (len>160)
Tracef("dist:%f\n",len);*/
}
return true;
}
void CWeaponTrace::Render()
{
//if (!m_isPlaying)
// return;
//if (m_CurvingTraceVector.size() < 4)
// return;
if (!BuildVertex())
return;
if (m_PDTVertexVector.size()<4)
return;
LPDIRECT3DTEXTURE8 lpTexture=NULL;
// Have to optimize
D3DXMATRIX matWorld;
D3DXMatrixIdentity(&matWorld);
STATEMANAGER.SaveTransform(D3DTS_WORLD, &matWorld);
STATEMANAGER.SaveVertexShader(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000011);
STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, (m_bUseTexture)?D3DTOP_SELECTARG2:D3DTOP_SELECTARG1);
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
//STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, (m_bUseTexture)?D3DTOP_SELECTARG2:D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
STATEMANAGER.SetTexture(0, lpTexture);
STATEMANAGER.SetTexture(1, NULL);
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,
int(m_PDTVertexVector.size() - 2),
&m_PDTVertexVector[0],
sizeof(TPDTVertex));
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE);
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_ZFUNC);
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
STATEMANAGER.RestoreTransform(D3DTS_WORLD);
STATEMANAGER.RestoreVertexShader();
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
}
void CWeaponTrace::UseAlpha()
{
m_bUseTexture = false;
}
void CWeaponTrace::UseTexture()
{
m_bUseTexture = true;
}
void CWeaponTrace::SetTexture(const char * c_szFileName)
{
CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("lot_ade10-2.tga");
m_ImageInstance.SetImagePointer(pImage);
//CGraphicTexture * pTexture = m_ImageInstance.GetTexturePointer();
//m_lpTexture = pTexture->GetD3DTexture();
}
bool CWeaponTrace::SetWeaponInstance(CGraphicThingInstance * pInstance, DWORD dwModelIndex, const char * c_szBoneName)
{
pInstance->Update();
pInstance->DeformNoSkin();
D3DXVECTOR3 v3Min;
D3DXVECTOR3 v3Max;
if (!pInstance->GetBoundBox(dwModelIndex, &v3Min, &v3Max))
return false;
m_iBoneIndex = 0;
m_dwModelInstanceIndex = dwModelIndex;
m_pInstance = pInstance;
D3DXMATRIX * pmat;
pInstance->GetBoneMatrix(dwModelIndex, 0, &pmat);
D3DXVECTOR3 v3Bone(pmat->_41,pmat->_42,pmat->_43);
const auto vv1 = (v3Bone - v3Min);
const auto vv2 = (v3Bone - v3Max);
m_fLength =
sqrtf(
fMAX(
D3DXVec3LengthSq(&vv1),
D3DXVec3LengthSq(&vv2)
)
);
return true;
}
void CWeaponTrace::SetPosition(float fx, float fy, float fz)
{
m_fx = fx;
m_fy = fy;
m_fz = fz;
}
void CWeaponTrace::SetRotation(float fRotation)
{
m_fRotation = fRotation;
}
void CWeaponTrace::SetLifeTime(float fLifeTime)
{
m_fLifeTime = fLifeTime;
}
void CWeaponTrace::SetSamplingTime(float fSamplingTime)
{
m_fSamplingTime = fSamplingTime;
}
void CWeaponTrace::TurnOn()
{
m_isPlaying = TRUE;
}
void CWeaponTrace::TurnOff()
{
m_isPlaying = FALSE;
//Clear();
}
void CWeaponTrace::Clear()
{
//m_PDTVertexVector.clear();
//m_CurvingTraceVector.clear();
m_ShortTimePointList.clear();
m_LongTimePointList.clear();
Initialize();
}
void CWeaponTrace::Initialize()
{
m_pInstance = NULL;
m_dwModelInstanceIndex = 0;
m_fx = 0.0f;
m_fy = 0.0f;
m_fz = 0.0f;
m_fRotation = 0.0f;
m_fLifeTime = 0.18f;
//m_fLifeTime = 3.0f;
m_fSamplingTime = 0.003f;
//m_fLifeTime = 3.0f;
//m_fSamplingTime = 0.003f;
m_isPlaying = FALSE;
m_bUseTexture = false;
m_iBoneIndex = 0;
m_fLastUpdate = CTimer::Instance().GetCurrentSecond();
///////////////////////////////////////////////////////////////////////
//const int c_iSplineCount = 8;
//m_SplineValueVector.clear();
//m_SplineValueVector.resize(c_iSplineCount);
//for (int i = 0; i < c_iSplineCount; ++i)
//{
// float fValue = float(i) / float(c_iSplineCount);
// m_SplineValueVector[i].fValue1 = fValue;
// m_SplineValueVector[i].fValue2 = fValue * fValue;
// m_SplineValueVector[i].fValue3 = fValue * fValue * fValue;
//}
}
CWeaponTrace::CWeaponTrace()
{
Initialize();
}
CWeaponTrace::~CWeaponTrace()
{
}
+86
View File
@@ -0,0 +1,86 @@
#pragma once
// change CatMull to cubic spline
#include "../EterGrnLib/ThingInstance.h"
class CWeaponTrace
{
/*
public:
typedef struct SSplineValue
{
float fValue1;
float fValue2;
float fValue3;
} TSplineValue;
*/
public:
static void DestroySystem();
static void Delete(CWeaponTrace* pkWTDel);
static CWeaponTrace* New();
public:
CWeaponTrace();
virtual ~CWeaponTrace();
void Clear();
void TurnOn();
void TurnOff();
void UseAlpha();
void UseTexture();
void SetTexture(const char * c_szFileName);
bool SetWeaponInstance(CGraphicThingInstance * pInstance, DWORD dwModelIndex, const char * c_szBoneName);
void SetPosition(float fx, float fy, float fz);
void SetRotation(float fRotation);
void SetLifeTime(float fLifeTime);
void SetSamplingTime(float fSamplingTime);
void Update(float fReachScale);
void Render();
void Initialize();
protected:
bool BuildVertex();
protected:
float m_fLastUpdate;
typedef std::pair<float, D3DXVECTOR3> TTimePoint;
typedef std::deque<TTimePoint> TTimePointList;
TTimePointList m_ShortTimePointList;
TTimePointList m_LongTimePointList;
std::vector<TPDTVertex> m_PDTVertexVector;
float m_fLifeTime;
float m_fSamplingTime;
//std::vector<TPDTVertex> m_PDTVertexVector;
//std::vector<TPDTVertex> m_CurvingTraceVector;
//std::vector<TSplineValue> m_SplineValueVector;
CGraphicThingInstance * m_pInstance;
DWORD m_dwModelInstanceIndex;
CGraphicImageInstance m_ImageInstance;
float m_fx;
float m_fy;
float m_fz;
float m_fRotation;
float m_fLength;
BOOL m_isPlaying;
bool m_bUseTexture;
int m_iBoneIndex;
protected:
static CDynamicPool<CWeaponTrace> ms_kPool;
};
@@ -0,0 +1,719 @@
#include "StdAfx.h"
#include "InstanceBase.h"
#include "PythonBackground.h"
#include "PythonCharacterManager.h"
#include "../PRTerrainLib/Terrain.h"
float NEW_UnsignedDegreeToSignedDegree(float fUD)
{
float fSD;
if (fUD>180.0f)
fSD=-(360.0f-fUD);
else if (fUD<-180.0f)
fSD=+(360.0f+fUD);
else
fSD=fUD;
return fSD;
}
float NEW_GetSignedDegreeFromDirPixelPosition(const TPixelPosition& kPPosDir)
{
D3DXVECTOR3 vtDir(kPPosDir.x, -kPPosDir.y, kPPosDir.z);
D3DXVECTOR3 vtDirNormal;
D3DXVec3Normalize(&vtDirNormal, &vtDir);
D3DXVECTOR3 vtDirNormalStan(0, -1, 0);
float fDirRot = D3DXToDegree(acosf(D3DXVec3Dot(&vtDirNormal, &vtDirNormalStan)));
if (vtDirNormal.x<0.0f)
fDirRot=-fDirRot;
return fDirRot;
}
bool CInstanceBase::IsFlyTargetObject()
{
return m_GraphicThingInstance.IsFlyTargetObject();
}
float CInstanceBase::GetFlyTargetDistance()
{
return m_GraphicThingInstance.GetFlyTargetDistance();
}
void CInstanceBase::ClearFlyTargetInstance()
{
m_GraphicThingInstance.ClearFlyTarget();
}
void CInstanceBase::SetFlyTargetInstance(CInstanceBase& rkInstDst)
{
// NOTE : NEW_Attack 때 Target을 바꿀때 여기서 리턴 되어버림 - [levites]
// if (isLock())
// return;
m_GraphicThingInstance.SetFlyTarget(rkInstDst.GetGraphicThingInstancePtr());
}
void CInstanceBase::AddFlyTargetPosition(const TPixelPosition& c_rkPPosDst)
{
m_GraphicThingInstance.AddFlyTarget(c_rkPPosDst);
}
void CInstanceBase::AddFlyTargetInstance(CInstanceBase& rkInstDst)
{
m_GraphicThingInstance.AddFlyTarget(rkInstDst.GetGraphicThingInstancePtr());
}
float CInstanceBase::NEW_GetDistanceFromDestInstance(CInstanceBase& rkInstDst)
{
TPixelPosition kPPosDst;
rkInstDst.NEW_GetPixelPosition(&kPPosDst);
return NEW_GetDistanceFromDestPixelPosition(kPPosDst);
}
float CInstanceBase::NEW_GetDistanceFromDestPixelPosition(const TPixelPosition& c_rkPPosDst)
{
TPixelPosition kPPosCur;
NEW_GetPixelPosition(&kPPosCur);
TPixelPosition kPPosDir;
kPPosDir=c_rkPPosDst-kPPosCur;
return NEW_GetDistanceFromDirPixelPosition(kPPosDir);
}
float CInstanceBase::NEW_GetDistanceFromDirPixelPosition(const TPixelPosition& c_rkPPosDir)
{
return sqrtf(c_rkPPosDir.x*c_rkPPosDir.x+c_rkPPosDir.y*c_rkPPosDir.y);
}
float CInstanceBase::NEW_GetRotation()
{
float fCurRot=GetRotation();
return NEW_UnsignedDegreeToSignedDegree(fCurRot);
}
float CInstanceBase::NEW_GetRotationFromDirPixelPosition(const TPixelPosition& c_rkPPosDir)
{
return NEW_GetSignedDegreeFromDirPixelPosition(c_rkPPosDir);
}
float CInstanceBase::NEW_GetRotationFromDestPixelPosition(const TPixelPosition& c_rkPPosDst)
{
TPixelPosition kPPosCur;
NEW_GetPixelPosition(&kPPosCur);
TPixelPosition kPPosDir;
kPPosDir=c_rkPPosDst-kPPosCur;
return NEW_GetRotationFromDirPixelPosition(kPPosDir);
}
float CInstanceBase::NEW_GetRotationFromDestInstance(CInstanceBase& rkInstDst)
{
TPixelPosition kPPosDst;
rkInstDst.NEW_GetPixelPosition(&kPPosDst);
return NEW_GetRotationFromDestPixelPosition(kPPosDst);
}
void CInstanceBase::NEW_GetRandomPositionInFanRange(CInstanceBase& rkInstTarget, TPixelPosition* pkPPosDst)
{
float fDstDirRot=NEW_GetRotationFromDestInstance(rkInstTarget);
float fRot=frandom(fDstDirRot-10.0f, fDstDirRot+10.0f);
D3DXMATRIX kMatRot;
D3DXMatrixRotationZ(&kMatRot, D3DXToRadian(-fRot));
D3DXVECTOR3 v3Src(0.0f, 8000.0f, 0.0f);
D3DXVECTOR3 v3Pos;
D3DXVec3TransformCoord(&v3Pos, &v3Src, &kMatRot);
const TPixelPosition& c_rkPPosCur=NEW_GetCurPixelPositionRef();
//const TPixelPosition& c_rkPPosFront=rkInstTarget.NEW_GetCurPixelPositionRef();
pkPPosDst->x=c_rkPPosCur.x+v3Pos.x;
pkPPosDst->y=c_rkPPosCur.y+v3Pos.y;
pkPPosDst->z=__GetBackgroundHeight(c_rkPPosCur.x, c_rkPPosCur.y);
}
bool CInstanceBase::NEW_GetFrontInstance(CInstanceBase ** ppoutTargetInstance, float fDistance)
{
const float HALF_FAN_ROT_MIN = 10.0f;
const float HALF_FAN_ROT_MAX = 50.0f;
const float HALF_FAN_ROT_MIN_DISTANCE = 1000.0f;
const float RPM = (HALF_FAN_ROT_MAX-HALF_FAN_ROT_MIN)/HALF_FAN_ROT_MIN_DISTANCE;
float fDstRot=NEW_GetRotation();
std::multimap<float, CInstanceBase*> kMap_pkInstNear;
{
CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance();
CPythonCharacterManager::CharacterIterator i;
for(i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd(); ++i)
{
CInstanceBase* pkInstEach=*i;
if (pkInstEach==this)
continue;
if (!IsAttackableInstance(*pkInstEach))
continue;
if (NEW_GetDistanceFromDestInstance(*pkInstEach) > fDistance)
continue;
float fEachInstDistance=min(NEW_GetDistanceFromDestInstance(*pkInstEach), HALF_FAN_ROT_MIN_DISTANCE);
float fEachInstDirRot=NEW_GetRotationFromDestInstance(*pkInstEach);
float fHalfFanRot=(HALF_FAN_ROT_MAX-HALF_FAN_ROT_MIN)-RPM*fEachInstDistance+HALF_FAN_ROT_MIN;
float fMinDstDirRot=fDstRot-fHalfFanRot;
float fMaxDstDirRot=fDstRot+fHalfFanRot;
if (fEachInstDirRot>=fMinDstDirRot && fEachInstDirRot<=fMaxDstDirRot)
kMap_pkInstNear.insert(std::multimap<float, CInstanceBase*>::value_type(fEachInstDistance, pkInstEach));
}
}
if (kMap_pkInstNear.empty())
return false;
*ppoutTargetInstance = kMap_pkInstNear.begin()->second;
return true;
}
// 2004.07.21.levites - 비파부 다중 타겟 지원
bool CInstanceBase::NEW_GetInstanceVectorInFanRange(float fSkillDistance, CInstanceBase& rkInstTarget, std::vector<CInstanceBase*>* pkVct_pkInst)
{
const float HALF_FAN_ROT_MIN = 20.0f;
const float HALF_FAN_ROT_MAX = 40.0f;
const float HALF_FAN_ROT_MIN_DISTANCE = 1000.0f;
const float RPM = (HALF_FAN_ROT_MAX-HALF_FAN_ROT_MIN)/HALF_FAN_ROT_MIN_DISTANCE;
float fDstDirRot=NEW_GetRotationFromDestInstance(rkInstTarget);
// 2004.07.24.myevan - 비파부 가까이 있는 적부터 공격
std::multimap<float, CInstanceBase*> kMap_pkInstNear;
{
CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance();
CPythonCharacterManager::CharacterIterator i;
for(i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd(); ++i)
{
CInstanceBase* pkInstEach=*i;
if (pkInstEach==this)
continue;
// 2004.07.25.myevan - 적인 경우만 추가한다
if (!IsAttackableInstance(*pkInstEach))
continue;
// 2004.07.21.levites - 비파부 다중 타겟 지원
if (m_GraphicThingInstance.IsClickableDistanceDestInstance(pkInstEach->m_GraphicThingInstance, fSkillDistance))
{
float fEachInstDistance=min(NEW_GetDistanceFromDestInstance(*pkInstEach), HALF_FAN_ROT_MIN_DISTANCE);
float fEachInstDirRot=NEW_GetRotationFromDestInstance(*pkInstEach);
float fHalfFanRot=(HALF_FAN_ROT_MAX-HALF_FAN_ROT_MIN)-RPM*fEachInstDistance+HALF_FAN_ROT_MIN;
float fMinDstDirRot=fDstDirRot-fHalfFanRot;
float fMaxDstDirRot=fDstDirRot+fHalfFanRot;
if (fEachInstDirRot>=fMinDstDirRot && fEachInstDirRot<=fMaxDstDirRot)
kMap_pkInstNear.insert(std::multimap<float, CInstanceBase*>::value_type(fEachInstDistance, pkInstEach));
}
}
}
{
std::multimap<float, CInstanceBase*>::iterator i=kMap_pkInstNear.begin();
for (i=kMap_pkInstNear.begin(); i!=kMap_pkInstNear.end(); ++i)
pkVct_pkInst->push_back(i->second);
}
if (pkVct_pkInst->empty())
return false;
return true;
}
bool CInstanceBase::NEW_GetInstanceVectorInCircleRange(float fSkillDistance, std::vector<CInstanceBase*>* pkVct_pkInst)
{
std::multimap<float, CInstanceBase*> kMap_pkInstNear;
{
CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance();
CPythonCharacterManager::CharacterIterator i;
for(i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd(); ++i)
{
CInstanceBase* pkInstEach=*i;
// 자신인 경우 추가하지 않는다
if (pkInstEach==this)
continue;
// 적인 경우만 추가한다
if (!IsAttackableInstance(*pkInstEach))
continue;
if (m_GraphicThingInstance.IsClickableDistanceDestInstance(pkInstEach->m_GraphicThingInstance, fSkillDistance))
{
float fEachInstDistance=NEW_GetDistanceFromDestInstance(*pkInstEach);
kMap_pkInstNear.insert(std::make_pair(fEachInstDistance, pkInstEach));
}
}
}
{
std::multimap<float, CInstanceBase*>::iterator i=kMap_pkInstNear.begin();
for (i=kMap_pkInstNear.begin(); i!=kMap_pkInstNear.end(); ++i)
pkVct_pkInst->push_back(i->second);
}
if (pkVct_pkInst->empty())
return false;
return true;
}
BOOL CInstanceBase::NEW_IsClickableDistanceDestPixelPosition(const TPixelPosition& c_rkPPosDst)
{
float fDistance=NEW_GetDistanceFromDestPixelPosition(c_rkPPosDst);
if (fDistance>150.0f)
return FALSE;
return TRUE;
}
BOOL CInstanceBase::NEW_IsClickableDistanceDestInstance(CInstanceBase& rkInstDst)
{
float fDistance = 150.0f;
if (IsBowMode())
fDistance = __GetBowRange();
if (rkInstDst.IsNPC())
fDistance = 500.0f;
if (rkInstDst.IsResource())
fDistance = 100.0f;
return m_GraphicThingInstance.IsClickableDistanceDestInstance(rkInstDst.m_GraphicThingInstance, fDistance);
}
bool CInstanceBase::NEW_UseSkill(UINT uSkill, UINT uMot, UINT uMotLoopCount, bool isMovingSkill)
{
if (IsDead())
return false;
if (IsStun())
return false;
if (IsKnockDown())
return false;
if (isMovingSkill)
{
if (!IsWalking())
StartWalking();
m_isGoing = TRUE;
}
else
{
if (IsWalking())
EndWalking();
m_isGoing = FALSE;
}
float fCurRot=m_GraphicThingInstance.GetTargetRotation();
SetAdvancingRotation(fCurRot);
m_GraphicThingInstance.InterceptOnceMotion(CRaceMotionData::NAME_SKILL + uMot, 0.1f, uSkill, 1.0f);
m_GraphicThingInstance.__OnUseSkill(uMot, uMotLoopCount, isMovingSkill);
if (uMotLoopCount > 0)
m_GraphicThingInstance.SetMotionLoopCount(uMotLoopCount);
return true;
}
void CInstanceBase::NEW_Attack()
{
float fDirRot=GetRotation();
NEW_Attack(fDirRot);
}
void CInstanceBase::NEW_Attack(float fDirRot)
{
if (IsDead())
return;
if (IsStun())
return;
if (IsKnockDown())
return;
if (IsUsingSkill())
return;
if (IsWalking())
EndWalking();
m_isGoing = FALSE;
if (IsPoly())
{
InputNormalAttack(fDirRot);
}
else
{
if (m_kHorse.IsMounting())
{
InputComboAttack(fDirRot);
}
else
{
InputComboAttack(fDirRot);
}
}
}
void CInstanceBase::NEW_AttackToDestPixelPositionDirection(const TPixelPosition& c_rkPPosDst)
{
float fDirRot=NEW_GetRotationFromDestPixelPosition(c_rkPPosDst);
NEW_Attack(fDirRot);
}
bool CInstanceBase::NEW_AttackToDestInstanceDirection(CInstanceBase& rkInstDst, IFlyEventHandler* pkFlyHandler)
{
return NEW_AttackToDestInstanceDirection(rkInstDst);
}
bool CInstanceBase::NEW_AttackToDestInstanceDirection(CInstanceBase& rkInstDst)
{
TPixelPosition kPPosDst;
rkInstDst.NEW_GetPixelPosition(&kPPosDst);
NEW_AttackToDestPixelPositionDirection(kPPosDst);
return true;
}
void CInstanceBase::AttackProcess()
{
if (!m_GraphicThingInstance.CanCheckAttacking())
return;
CInstanceBase * pkInstLast = NULL;
CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance();
CPythonCharacterManager::CharacterIterator i = rkChrMgr.CharacterInstanceBegin();
while (rkChrMgr.CharacterInstanceEnd()!=i)
{
CInstanceBase* pkInstEach=*i;
++i;
// 서로간의 InstanceType 비교
if (!IsAttackableInstance(*pkInstEach))
continue;
if (pkInstEach!=this)
{
if (CheckAttacking(*pkInstEach))
{
pkInstLast=pkInstEach;
}
}
}
if (pkInstLast)
{
m_dwLastDmgActorVID=pkInstLast->GetVirtualID();
}
}
void CInstanceBase::InputNormalAttack(float fAtkDirRot)
{
m_GraphicThingInstance.InputNormalAttackCommand(fAtkDirRot);
}
void CInstanceBase::InputComboAttack(float fAtkDirRot)
{
m_GraphicThingInstance.InputComboAttackCommand(fAtkDirRot);
__ComboProcess();
}
void CInstanceBase::RunNormalAttack(float fAtkDirRot)
{
EndGoing();
m_GraphicThingInstance.NormalAttack(fAtkDirRot);
}
void CInstanceBase::RunComboAttack(float fAtkDirRot, DWORD wMotionIndex)
{
EndGoing();
m_GraphicThingInstance.ComboAttack(wMotionIndex, fAtkDirRot);
}
// 리턴값 TRUE가 무엇인가가 있다
BOOL CInstanceBase::CheckAdvancing()
{
#ifdef __MOVIE_MODE__
if (IsMovieMode())
return FALSE;
#endif
if (!__IsMainInstance() && !IsAttacking())
{
if (IsPC() && IsWalking())
{
CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance();
for(CPythonCharacterManager::CharacterIterator i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd();++i)
{
CInstanceBase* pkInstEach=*i;
if (pkInstEach==this)
continue;
if (!pkInstEach->IsDoor())
continue;
if (m_GraphicThingInstance.TestActorCollision(pkInstEach->GetGraphicThingInstanceRef()))
{
BlockMovement();
return true;
}
}
}
return FALSE;
}
if (m_GraphicThingInstance.CanSkipCollision())
{
//Tracenf("%x VID %d 충돌 스킵", ELTimer_GetMSec(), GetVirtualID());
return FALSE;
}
BOOL bUsingSkill = m_GraphicThingInstance.IsUsingSkill();
m_dwAdvActorVID = 0;
UINT uCollisionCount=0;
CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance();
for(CPythonCharacterManager::CharacterIterator i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd();++i)
{
CInstanceBase* pkInstEach=*i;
if (pkInstEach==this)
continue;
CActorInstance& rkActorSelf=m_GraphicThingInstance;
CActorInstance& rkActorEach=pkInstEach->GetGraphicThingInstanceRef();
//NOTE : Skil을 쓰더라도 Door Type과는 Collision체크 한다.
if( bUsingSkill && !rkActorEach.IsDoor() )
continue;
// 앞으로 전진할수 있는가?
if (rkActorSelf.TestActorCollision(rkActorEach))
{
uCollisionCount++;
if (uCollisionCount==2)
{
rkActorSelf.BlockMovement();
return TRUE;
}
rkActorSelf.AdjustDynamicCollisionMovement(&rkActorEach);
if (rkActorSelf.TestActorCollision(rkActorEach))
{
rkActorSelf.BlockMovement();
return TRUE;
}
else
{
NEW_MoveToDestPixelPositionDirection(NEW_GetDstPixelPositionRef());
}
}
}
// 맵속성 체크
CPythonBackground& rkBG=CPythonBackground::Instance();
const D3DXVECTOR3 & rv3Position = m_GraphicThingInstance.GetPosition();
const D3DXVECTOR3 & rv3MoveDirection = m_GraphicThingInstance.GetMovementVectorRef();
// NOTE : 만약 이동 거리가 크다면 쪼개서 구간 별로 속성을 체크해 본다
// 현재 설정해 놓은 10.0f는 임의의 거리 - [levites]
int iStep = int(D3DXVec3Length(&rv3MoveDirection) / 10.0f);
D3DXVECTOR3 v3CheckStep = rv3MoveDirection / float(iStep);
D3DXVECTOR3 v3CheckPosition = rv3Position;
for (int j = 0; j < iStep; ++j)
{
v3CheckPosition += v3CheckStep;
// Check
if (rkBG.isAttrOn(v3CheckPosition.x, -v3CheckPosition.y, CTerrainImpl::ATTRIBUTE_BLOCK))
{
BlockMovement();
//return TRUE;
}
}
// Check
D3DXVECTOR3 v3NextPosition = rv3Position + rv3MoveDirection;
if (rkBG.isAttrOn(v3NextPosition.x, -v3NextPosition.y, CTerrainImpl::ATTRIBUTE_BLOCK))
{
BlockMovement();
return TRUE;
}
return FALSE;
}
BOOL CInstanceBase::CheckAttacking(CInstanceBase& rkInstVictim)
{
if (IsInSafe())
return FALSE;
if (rkInstVictim.IsInSafe())
return FALSE;
#ifdef __MOVIE_MODE__
return FALSE;
#endif
if (!m_GraphicThingInstance.AttackingProcess(rkInstVictim.m_GraphicThingInstance))
return FALSE;
return TRUE;
}
BOOL CInstanceBase::isNormalAttacking()
{
return m_GraphicThingInstance.isNormalAttacking();
}
BOOL CInstanceBase::isComboAttacking()
{
return m_GraphicThingInstance.isComboAttacking();
}
BOOL CInstanceBase::IsUsingSkill()
{
return m_GraphicThingInstance.IsUsingSkill();
}
BOOL CInstanceBase::IsUsingMovingSkill()
{
return m_GraphicThingInstance.IsUsingMovingSkill();
}
BOOL CInstanceBase::CanCancelSkill()
{
return m_GraphicThingInstance.CanCancelSkill();
}
BOOL CInstanceBase::CanAttackHorseLevel()
{
if (!IsMountingHorse())
return FALSE;
return m_kHorse.CanAttack();
}
bool CInstanceBase::IsAffect(UINT uAffect)
{
return m_kAffectFlagContainer.IsSet(uAffect);
}
MOTION_KEY CInstanceBase::GetNormalAttackIndex()
{
return m_GraphicThingInstance.GetNormalAttackIndex();
}
DWORD CInstanceBase::GetComboIndex()
{
return m_GraphicThingInstance.GetComboIndex();
}
float CInstanceBase::GetAttackingElapsedTime()
{
return m_GraphicThingInstance.GetAttackingElapsedTime();
}
void CInstanceBase::ProcessHitting(DWORD dwMotionKey, CInstanceBase * pVictimInstance)
{
assert(!"-_-" && "CInstanceBase::ProcessHitting");
//m_GraphicThingInstance.ProcessSucceedingAttacking(dwMotionKey, pVictimInstance->m_GraphicThingInstance);
}
void CInstanceBase::ProcessHitting(DWORD dwMotionKey, BYTE byEventIndex, CInstanceBase * pVictimInstance)
{
assert(!"-_-" && "CInstanceBase::ProcessHitting");
//m_GraphicThingInstance.ProcessSucceedingAttacking(dwMotionKey, byEventIndex, pVictimInstance->m_GraphicThingInstance);
}
void CInstanceBase::GetBlendingPosition(TPixelPosition * pPixelPosition)
{
m_GraphicThingInstance.GetBlendingPosition(pPixelPosition);
}
void CInstanceBase::SetBlendingPosition(const TPixelPosition & c_rPixelPosition)
{
m_GraphicThingInstance.SetBlendingPosition(c_rPixelPosition);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void CInstanceBase::Revive()
{
m_isGoing=FALSE;
m_GraphicThingInstance.Revive();
__AttachHorseSaddle();
}
void CInstanceBase::Stun()
{
NEW_Stop();
m_GraphicThingInstance.Stun();
__AttachEffect(EFFECT_STUN);
}
void CInstanceBase::Die()
{
__DetachHorseSaddle();
if (IsAffect(AFFECT_SPAWN))
__AttachEffect(EFFECT_SPAWN_DISAPPEAR);
// 2004.07.25.이펙트 안붙는 문제해결
////////////////////////////////////////
__ClearAffects();
////////////////////////////////////////
OnUnselected();
OnUntargeted();
m_GraphicThingInstance.Die();
}
void CInstanceBase::Hide()
{
m_GraphicThingInstance.SetAlphaValue(0.0f);
m_GraphicThingInstance.BlendAlphaValue(0.0f, 0.1f);
}
void CInstanceBase::Show()
{
m_GraphicThingInstance.SetAlphaValue(1.0f);
m_GraphicThingInstance.BlendAlphaValue(1.0f, 0.1f);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,17 @@
#include "StdAfx.h"
#include "InstanceBase.h"
CActorInstance::IEventHandler& CInstanceBase::GetEventHandlerRef()
{
return m_GraphicThingInstance.__GetEventHandlerRef();
}
CActorInstance::IEventHandler* CInstanceBase::GetEventHandlerPtr()
{
return m_GraphicThingInstance.__GetEventHandlerPtr();
}
void CInstanceBase::SetEventHandler(CActorInstance::IEventHandler* pkEventHandler)
{
m_GraphicThingInstance.SetEventHandler(pkEventHandler);
}
@@ -0,0 +1,165 @@
#include "StdAfx.h"
#include "InstanceBase.h"
#include "AbstractPlayer.h"
#include "../GameLib/ActorInstance.h"
const int c_iFishingRotStep = 8;
const float c_fFishingDistance = 600.0f;
void CInstanceBase::SetMotionMode(int iMotionMode)
{
m_GraphicThingInstance.SetMotionMode(iMotionMode);
}
int CInstanceBase::GetMotionMode(DWORD dwMotionIndex)
{
return m_GraphicThingInstance.GetMotionMode();
}
void CInstanceBase::SetLoopMotion(WORD wMotion, float fBlendTime/* =0.1f */, float fSpeedRatio)
{
m_GraphicThingInstance.SetLoopMotion(wMotion, fBlendTime, fSpeedRatio);
}
void CInstanceBase::PushOnceMotion(WORD wMotion, float fBlendTime, float fSpeedRatio)
{
m_GraphicThingInstance.PushOnceMotion(wMotion, fBlendTime, fSpeedRatio);
}
void CInstanceBase::PushLoopMotion(WORD wMotion, float fBlendTime, float fSpeedRatio)
{
m_GraphicThingInstance.PushLoopMotion(wMotion, fBlendTime, fSpeedRatio);
}
void CInstanceBase::ResetLocalTime()
{
m_GraphicThingInstance.ResetLocalTime();
}
void CInstanceBase::SetEndStopMotion()
{
m_GraphicThingInstance.SetEndStopMotion();
}
BOOL CInstanceBase::isLock()
{
return m_GraphicThingInstance.isLock();
}
void CInstanceBase::StartFishing(float frot)
{
BlendRotation(frot);
const TPixelPosition& c_rkPPosCur=m_GraphicThingInstance.NEW_GetCurPixelPositionRef();
float fRot = m_GraphicThingInstance.GetTargetRotation();
//float fPlainCoordRot=ELRightCoord_ConvertToPlainCoordDegree(fRightCoordRot);
TPixelPosition kPPosFishing;
ELPlainCoord_GetRotatedPixelPosition(c_rkPPosCur.x, c_rkPPosCur.y, c_fFishingDistance, fRot, &kPPosFishing.x, &kPPosFishing.y);
if (!__Background_GetWaterHeight(kPPosFishing, &kPPosFishing.z))
kPPosFishing.z=c_rkPPosCur.z;
D3DXVECTOR3 v3Fishing;
PixelPositionToD3DXVECTOR3(kPPosFishing, &v3Fishing);
m_GraphicThingInstance.SetFishingPosition(v3Fishing);
PushOnceMotion(CRaceMotionData::NAME_FISHING_THROW);
PushLoopMotion(CRaceMotionData::NAME_FISHING_WAIT);
}
void CInstanceBase::StopFishing()
{
m_GraphicThingInstance.InterceptOnceMotion(CRaceMotionData::NAME_FISHING_STOP);
PushLoopMotion(CRaceMotionData::NAME_WAIT);
}
void CInstanceBase::ReactFishing()
{
PushOnceMotion(CRaceMotionData::NAME_FISHING_REACT);
PushLoopMotion(CRaceMotionData::NAME_FISHING_WAIT);
}
void CInstanceBase::CatchSuccess()
{
m_GraphicThingInstance.InterceptOnceMotion(CRaceMotionData::NAME_FISHING_CATCH);
PushLoopMotion(CRaceMotionData::NAME_WAIT);
}
void CInstanceBase::CatchFail()
{
m_GraphicThingInstance.InterceptOnceMotion(CRaceMotionData::NAME_FISHING_FAIL);
PushLoopMotion(CRaceMotionData::NAME_WAIT);
}
BOOL CInstanceBase::GetFishingRot(int * pirot)
{
const TPixelPosition& c_rkPPosCur=m_GraphicThingInstance.NEW_GetCurPixelPositionRef();
float fCharacterRot = m_GraphicThingInstance.GetRotation();
//float frot = fCharacterRot;
for (float fRot=0.0f; fRot<=180.0f; fRot+=10.0f)
{
TPixelPosition kPPosFishingRight;
ELPlainCoord_GetRotatedPixelPosition(c_rkPPosCur.x, c_rkPPosCur.y, c_fFishingDistance, fCharacterRot+fRot, &kPPosFishingRight.x, &kPPosFishingRight.y);
if (__Background_IsWaterPixelPosition(kPPosFishingRight))
{
*pirot = fCharacterRot+fRot;
return TRUE;
}
TPixelPosition kPPosFishingLeft;
ELPlainCoord_GetRotatedPixelPosition(c_rkPPosCur.x, c_rkPPosCur.y, c_fFishingDistance, fCharacterRot-fRot, &kPPosFishingLeft.x, &kPPosFishingLeft.y);
if (__Background_IsWaterPixelPosition(kPPosFishingLeft))
{
*pirot = fCharacterRot-fRot;
return TRUE;
}
}
return FALSE;
}
void CInstanceBase::__EnableChangingTCPState()
{
m_bEnableTCPState = TRUE;
}
void CInstanceBase::__DisableChangingTCPState()
{
m_bEnableTCPState = FALSE;
}
void CInstanceBase::ActDualEmotion(CInstanceBase & rkDstInst, WORD wMotionNumber1, WORD wMotionNumber2)
{
if (!IsWaiting())
{
m_GraphicThingInstance.SetLoopMotion(CRaceMotionData::NAME_WAIT, 0.05f);
}
if (!rkDstInst.IsWaiting())
{
rkDstInst.m_GraphicThingInstance.SetLoopMotion(CRaceMotionData::NAME_WAIT, 0.05f);
}
const float c_fEmotionDistance = 100.0f;
const TPixelPosition & c_rMainPosition = NEW_GetCurPixelPositionRef();
const TPixelPosition & c_rTargetPosition = rkDstInst.NEW_GetCurPixelPositionRef();
TPixelPosition kDirection = c_rMainPosition - c_rTargetPosition;
float fDistance = sqrtf((kDirection.x*kDirection.x) + (kDirection.y*kDirection.y));
TPixelPosition kDstPosition;
kDstPosition.x = c_rTargetPosition.x + (kDirection.x/fDistance)*c_fEmotionDistance;
kDstPosition.y = c_rTargetPosition.y + (kDirection.y/fDistance)*c_fEmotionDistance;
DWORD dwCurTime = ELTimer_GetServerMSec() + 500;
PushTCPStateExpanded(dwCurTime, kDstPosition, 0.0f, FUNC_EMOTION, MAKELONG(wMotionNumber1, wMotionNumber2), rkDstInst.GetVirtualID());
__DisableChangingTCPState();
rkDstInst.__DisableChangingTCPState();
if (__IsMainInstance() || rkDstInst.__IsMainInstance())
{
IAbstractPlayer & rPlayer=IAbstractPlayer::GetSingleton();
rPlayer.StartEmotionProcess();
}
}
void CInstanceBase::ActEmotion(DWORD dwMotionNumber)
{
PushOnceMotion(dwMotionNumber);
}
@@ -0,0 +1,93 @@
#include "StdAfx.h"
#include "InstanceBase.h"
#include "PythonBackground.h"
void CInstanceBase::SCRIPT_SetPixelPosition(float fx, float fy)
{
float fz = __GetBackgroundHeight(fx, fy);
NEW_SetPixelPosition(TPixelPosition(fx, fy, fz));
}
void CInstanceBase::NEW_SetPixelPosition(const TPixelPosition & c_rPixelPosition)
{
m_GraphicThingInstance.SetCurPixelPosition(c_rPixelPosition);
}
void CInstanceBase::NEW_GetPixelPosition(TPixelPosition * pPixelPosition)
{
*pPixelPosition=m_GraphicThingInstance.NEW_GetCurPixelPositionRef();
}
void CInstanceBase::SetRotation(float fRotation)
{
m_GraphicThingInstance.SetRotation(fRotation);
}
void CInstanceBase::BlendRotation(float fRotation, float fBlendTime)
{
m_GraphicThingInstance.BlendRotation(fRotation, fBlendTime);
}
void CInstanceBase::NEW_LookAtFlyTarget()
{
m_GraphicThingInstance.LookAtFlyTarget();
}
void CInstanceBase::NEW_LookAtDestPixelPosition(const TPixelPosition& c_rkPPosDst)
{
m_GraphicThingInstance.LookAt(c_rkPPosDst.x, -c_rkPPosDst.y);
}
void CInstanceBase::NEW_LookAtDestInstance(CInstanceBase& rkInstDst)
{
m_GraphicThingInstance.LookAt(&rkInstDst.m_GraphicThingInstance);
// Tracenf("LookAt %f", m_GraphicThingInstance.GetTargetRotation());
}
float CInstanceBase::GetRotation()
{
return m_GraphicThingInstance.GetRotation();
}
float CInstanceBase::GetAdvancingRotation()
{
return m_GraphicThingInstance.GetAdvancingRotation();
}
void CInstanceBase::SetDirection(int dir)
{
float fDegree = GetDegreeFromDirection(dir);
SetRotation(fDegree);
SetAdvancingRotation(fDegree);
}
void CInstanceBase::BlendDirection(int dir, float blendTime)
{
m_GraphicThingInstance.BlendRotation(GetDegreeFromDirection(dir), blendTime);
}
float CInstanceBase::GetDegreeFromDirection(int dir)
{
if (dir < 0)
return 0.0f;
if (dir >= DIR_MAX_NUM)
return 0.0f;
static float s_dirRot[DIR_MAX_NUM]=
{
+45.0f * 4,
+45.0f * 3,
+45.0f * 2,
+45.0f,
+0.0f,
360.0f-45.0f,
360.0f-45.0f * 2,
360.0f-45.0f * 3,
};
return s_dirRot[dir];
}
+2 -1
View File
@@ -2050,7 +2050,7 @@ typedef struct SPlayerSkill
{
BYTE bMasterType;
BYTE bLevel;
time_t tNextRead;
LONG tNextRead; // PORT: time_t is 32-bit under 40250's _USE_32BIT_TIME_T; 64-bit on LP64 hosts
} TPlayerSkill;
typedef struct packet_skill_level_new
@@ -2058,6 +2058,7 @@ typedef struct packet_skill_level_new
BYTE bHeader;
TPlayerSkill skills[SKILL_MAX_NUM];
} TPacketGCSkillLevelNew;
static_assert(sizeof(TPacketGCSkillLevelNew) == 1 + SKILL_MAX_NUM * 6);
// fly
typedef struct packet_fly
+74 -5
View File
@@ -302,15 +302,84 @@ typedef enum _D3DTEXTURESTAGESTATETYPE
D3DTSS_FORCE_DWORD = 0x7fffffff,
} D3DTEXTURESTAGESTATETYPE;
// D3D8 texture-stage arguments and operations used by the character renderer.
// D3D8 texture-stage arguments (d3d8types.h D3DTA_*).
enum : DWORD {
D3DTA_DIFFUSE = 0,
D3DTA_CURRENT = 1,
D3DTA_TEXTURE = 2,
D3DTA_SELECTMASK = 0x0000000f,
D3DTA_DIFFUSE = 0x00000000,
D3DTA_CURRENT = 0x00000001,
D3DTA_TEXTURE = 0x00000002,
D3DTA_TFACTOR = 0x00000003,
D3DTA_SPECULAR = 0x00000004,
D3DTA_TEMP = 0x00000005,
D3DTA_COMPLEMENT = 0x00000010,
D3DTA_ALPHAREPLICATE = 0x00000020,
};
typedef enum _D3DTEXTUREOP {
D3DTOP_DISABLE = 1,
D3DTOP_SELECTARG1 = 2,
D3DTOP_SELECTARG2 = 3,
D3DTOP_MODULATE = 4,
};
D3DTOP_MODULATE2X = 5,
D3DTOP_MODULATE4X = 6,
D3DTOP_ADD = 7,
D3DTOP_ADDSIGNED = 8,
D3DTOP_ADDSIGNED2X = 9,
D3DTOP_SUBTRACT = 10,
D3DTOP_ADDSMOOTH = 11,
D3DTOP_BLENDDIFFUSEALPHA = 12,
D3DTOP_BLENDTEXTUREALPHA = 13,
D3DTOP_BLENDFACTORALPHA = 14,
D3DTOP_BLENDTEXTUREALPHAPM = 15,
D3DTOP_BLENDCURRENTALPHA = 16,
D3DTOP_PREMODULATE = 17,
D3DTOP_MODULATEALPHA_ADDCOLOR = 18,
D3DTOP_MODULATECOLOR_ADDALPHA = 19,
D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20,
D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21,
D3DTOP_BUMPENVMAP = 22,
D3DTOP_BUMPENVMAPLUMINANCE = 23,
D3DTOP_DOTPRODUCT3 = 24,
D3DTOP_MULTIPLYADD = 25,
D3DTOP_LERP = 26,
D3DTOP_FORCE_DWORD = 0x7fffffff,
} D3DTEXTUREOP;
typedef enum _D3DCMPFUNC {
D3DCMP_NEVER = 1,
D3DCMP_LESS = 2,
D3DCMP_EQUAL = 3,
D3DCMP_LESSEQUAL = 4,
D3DCMP_GREATER = 5,
D3DCMP_NOTEQUAL = 6,
D3DCMP_GREATEREQUAL = 7,
D3DCMP_ALWAYS = 8,
D3DCMP_FORCE_DWORD = 0x7fffffff,
} D3DCMPFUNC;
typedef enum _D3DBLEND {
D3DBLEND_ZERO = 1,
D3DBLEND_ONE = 2,
D3DBLEND_SRCCOLOR = 3,
D3DBLEND_INVSRCCOLOR = 4,
D3DBLEND_SRCALPHA = 5,
D3DBLEND_INVSRCALPHA = 6,
D3DBLEND_DESTALPHA = 7,
D3DBLEND_INVDESTALPHA = 8,
D3DBLEND_DESTCOLOR = 9,
D3DBLEND_INVDESTCOLOR = 10,
D3DBLEND_SRCALPHASAT = 11,
D3DBLEND_BOTHSRCALPHA = 12,
D3DBLEND_BOTHINVSRCALPHA = 13,
D3DBLEND_FORCE_DWORD = 0x7fffffff,
} D3DBLEND;
typedef enum _D3DCULL {
D3DCULL_NONE = 1,
D3DCULL_CW = 2,
D3DCULL_CCW = 3,
D3DCULL_FORCE_DWORD = 0x7fffffff,
} D3DCULL;
#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256)
#define D3DTS_WORLD D3DTS_WORLDMATRIX(0)