diff --git a/audit/history.jsonl b/audit/history.jsonl index ef0f3029..fa688206 100644 --- a/audit/history.jsonl +++ b/audit/history.jsonl @@ -527,3 +527,4 @@ {"time": "2026-09-23T14:45:00Z", "event": "port_round", "unit": "PORT-PLAN 2V3-a: player/input/event handler chain and Granny root motion", "ported": ["UserInterface/PythonPlayer.cpp", "UserInterface/PythonPlayerInput.cpp", "UserInterface/PythonPlayerInputKeyboard.cpp", "UserInterface/PythonPlayerInputMouse.cpp", "UserInterface/PythonPlayerEventHandler.cpp", "UserInterface/PythonPlayerSkill.cpp", "UserInterface/PythonPlayerModule.cpp", "UserInterface/GameType.cpp"], "adapted": ["GrannyUpdateModelMatrix constant-extraction root motion from TrackGroups[0] AccumulationFlags/LoopTranslation (libgr2)"], "divergent": ["VDA accumulation not implemented", "CPythonSkill/CItemData/CItemManager/CPythonItem callees remain pending stubs"], "needs_live": [], "tests": ["port.login_flow: DIK_UP walked 108 cm; fake server got CG_MOVE FUNC_MOVE then FUNC_WAIT at moved y", "port.login_live 192.168.21.203: PASS, walked 132 cm", "ctest all: PASS (login_live skipped without MT_LIVE_*)", "port_map.py check: 0 errors"], "todo": ["mouse click-to-move and attack", "CheckAdvancing/map attribute stubs", "delete legacy movement when default route switches to port"]} {"time": "2026-09-23T15:00:00Z", "event": "port_round", "unit": "PORT-PLAN 2V3-b: click-to-move, terrain picking and attribute map", "ported": [], "adapted": ["CScreen::SetCursorPosition / CPythonGraphic::SetCursorPosition verbatim in platform layer", "CPythonBackground::GetPickingPoint* terrain half via CMapOutdoor::__PickTerrainHeight over native height", "CMapManager::isAttrOn via CMapOutdoor/CTerrain::isAttrOn over packed attr.atr", "CPythonBackground::CheckAdvancing + collision checkers verbatim (no map objects registered yet)"], "divergent": ["object picking and object collision wait for CMapOutdoor"], "needs_live": [], "tests": ["port.login_flow: click walked 334 cm, FUNC_MOVE..FUNC_WAIT; 17814 blocked cells", "port.login_live 192.168.21.203: PASS (key 133 cm, click 296 cm, 11406 blocked cells)", "script/python_game_render_test.sh offline: PASS", "ctest all: 19/19 (login_live skipped without env)", "port_map.py check: 0 errors"], "todo": ["switch client_main default to the port route and delete the legacy GDScript client"]} {"time": "2026-09-24T02:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P0: UserInterface/PythonCharacterManager.cpp + InstanceBaseMovement.cpp", "ported": ["UserInterface/PythonCharacterManager.cpp (54)", "UserInterface/InstanceBaseMovement.cpp (32)"], "adapted": [], "divergent": [], "needs_live": [], "tests": ["diff vs 40250: include case, comment encoding, 2 PORT edits only", "ctest all: 19/19 incl. port.login_live 192.168.21.203", "port_map.py check: 0 errors"], "todo": ["P1 queue: FlyingInstance, ActorInstanceData, FlyingObjectManager, FlyTrace"]} +{"time": "2026-09-24T03:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P1: flying objects + effect/fly Python modules", "ported": ["GameLib/FlyingData.cpp (12)", "GameLib/FlyingInstance.cpp (20)", "GameLib/FlyingObjectManager.cpp (12)", "GameLib/FlyTrace.cpp (11)", "GameLib/ActorInstanceData.cpp (12)", "UserInterface/PythonEffectModule.cpp (8)", "UserInterface/PythonFlyModule.cpp (3)"], "adapted": ["CMapManager::GetTerrainHeight over native height tiles; GetHeight forwards to it"], "divergent": [], "needs_live": [], "tests": ["port.login_flow: indexed fly .msf registered by playersettingmodule and parses", "ctest all: 19/19 incl. port.login_live 192.168.21.203", "script/python_game_render_test.sh offline: PASS", "port_map.py check: 0 errors"], "todo": ["CEffectManager is a platform stub: fly effects are not rendered", "P2 network units already copied into port/ need verification and marking"]} diff --git a/audit/port-map/GameLib/ActorInstanceData.cpp.json b/audit/port-map/GameLib/ActorInstanceData.cpp.json index 10409da5..2c2023b0 100644 --- a/audit/port-map/GameLib/ActorInstanceData.cpp.json +++ b/audit/port-map/GameLib/ActorInstanceData.cpp.json @@ -5,40 +5,76 @@ "contracts": [], "functions": { "CActorInstance::GetVirtualID": { - "status": "TODO" + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::GetVirtualID" + ] }, "CActorInstance::SetVirtualID": { - "status": "TODO" + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::SetVirtualID" + ] }, "CActorInstance::UpdateAttribute": { - "status": "TODO" + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::UpdateAttribute" + ] }, "CActorInstance::__CreateAttributeInstance": { - "status": "TODO" + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::__CreateAttributeInstance" + ] }, "CActorInstance::GetRace": { - "status": "TODO" + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::GetRace" + ] }, "CActorInstance::SetRace": { - "status": "TODO" + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::SetRace" + ] }, "CActorInstance::SetHair": { - "status": "TODO" + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::SetHair" + ] }, "CActorInstance::SetShape": { - "status": "TODO" + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::SetShape" + ] }, "CActorInstance::ChangeMaterial": { - "status": "TODO" + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::ChangeMaterial" + ] }, "CActorInstance::GetPartItemID": { - "status": "TODO" + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::GetPartItemID" + ] }, "CActorInstance::SetSpecularInfo": { - "status": "TODO" + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::SetSpecularInfo" + ] }, "CActorInstance::SetSpecularInfoForce": { - "status": "TODO" + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::SetSpecularInfoForce" + ] } } } diff --git a/audit/port-map/GameLib/FlyTrace.cpp.json b/audit/port-map/GameLib/FlyTrace.cpp.json new file mode 100644 index 00000000..577ccb24 --- /dev/null +++ b/audit/port-map/GameLib/FlyTrace.cpp.json @@ -0,0 +1,74 @@ +{ + "reference": "GameLib/FlyTrace.cpp", + "reference_sha256": "4ab3192d471aa6db4f96db5df73a0598e9f273fd9712ed1df6fa37f74517ffb4", + "priority": "P1", + "contracts": [], + "functions": { + "CFlyTrace::DestroySystem": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyTrace.cpp:CFlyTrace::DestroySystem" + ] + }, + "CFlyTrace::New": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyTrace.cpp:CFlyTrace::New" + ] + }, + "CFlyTrace::Delete": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyTrace.cpp:CFlyTrace::Delete" + ] + }, + "CFlyTrace::CFlyTrace": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyTrace.cpp:CFlyTrace::CFlyTrace" + ] + }, + "CFlyTrace::~CFlyTrace": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyTrace.cpp:CFlyTrace::~CFlyTrace" + ] + }, + "CFlyTrace::__Initialize": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyTrace.cpp:CFlyTrace::__Initialize" + ] + }, + "CFlyTrace::Destroy": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyTrace.cpp:CFlyTrace::Destroy" + ] + }, + "CFlyTrace::UpdateNewPosition": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyTrace.cpp:CFlyTrace::UpdateNewPosition" + ] + }, + "CFlyTrace::Create": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyTrace.cpp:CFlyTrace::Create" + ] + }, + "CFlyTrace::Update": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyTrace.cpp:CFlyTrace::Update" + ] + }, + "CFlyTrace::Render": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyTrace.cpp:CFlyTrace::Render" + ] + } + } +} diff --git a/audit/port-map/GameLib/FlyingData.cpp.json b/audit/port-map/GameLib/FlyingData.cpp.json new file mode 100644 index 00000000..829a4ad9 --- /dev/null +++ b/audit/port-map/GameLib/FlyingData.cpp.json @@ -0,0 +1,80 @@ +{ + "reference": "GameLib/FlyingData.cpp", + "reference_sha256": "2486eff11e613a658e4d5f3a1b212fe9933f1c092d3bc12f561923f181b81512", + "priority": "P4", + "contracts": [], + "functions": { + "CFlyingData::CFlyingData": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingData.cpp:CFlyingData::CFlyingData" + ] + }, + "CFlyingData::__Initialize": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingData.cpp:CFlyingData::__Initialize" + ] + }, + "CFlyingData::Destroy": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingData.cpp:CFlyingData::Destroy" + ] + }, + "CFlyingData::~CFlyingData": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingData.cpp:CFlyingData::~CFlyingData" + ] + }, + "CFlyingData::SetBombEffect": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingData.cpp:CFlyingData::SetBombEffect" + ] + }, + "CFlyingData::GetAttachDataReference": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingData.cpp:CFlyingData::GetAttachDataReference" + ] + }, + "CFlyingData::AttachFlyEffect": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingData.cpp:CFlyingData::AttachFlyEffect" + ] + }, + "CFlyingData::RemoveAttach": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingData.cpp:CFlyingData::RemoveAttach" + ] + }, + "CFlyingData::RemoveAllAttach": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingData.cpp:CFlyingData::RemoveAllAttach" + ] + }, + "CFlyingData::DuplicateAttach": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingData.cpp:CFlyingData::DuplicateAttach" + ] + }, + "CFlyingData::LoadScriptFile": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingData.cpp:CFlyingData::LoadScriptFile" + ] + }, + "CFlyingData::SaveScriptFile": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingData.cpp:CFlyingData::SaveScriptFile" + ] + } + } +} diff --git a/audit/port-map/GameLib/FlyingInstance.cpp.json b/audit/port-map/GameLib/FlyingInstance.cpp.json new file mode 100644 index 00000000..fff3759c --- /dev/null +++ b/audit/port-map/GameLib/FlyingInstance.cpp.json @@ -0,0 +1,128 @@ +{ + "reference": "GameLib/FlyingInstance.cpp", + "reference_sha256": "b58a421b74fa57b56710e5666728e7e8b16a2e2b073eeb2b349b3c20b8d00bff", + "priority": "P1", + "contracts": [], + "functions": { + "CFlyingInstance::CFlyingInstance": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::CFlyingInstance" + ] + }, + "CFlyingInstance::~CFlyingInstance": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::~CFlyingInstance" + ] + }, + "CFlyingInstance::__Initialize": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::__Initialize" + ] + }, + "CFlyingInstance::Clear": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::Clear" + ] + }, + "CFlyingInstance::Destroy": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::Destroy" + ] + }, + "CFlyingInstance::BuildAttachInstance": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::BuildAttachInstance" + ] + }, + "CFlyingInstance::Create": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::Create" + ] + }, + "CFlyingInstance::__SetTargetDirection": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::__SetTargetDirection" + ] + }, + "CFlyingInstance::__SetTargetNormalizedDirection": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::__SetTargetNormalizedDirection" + ] + }, + "CFlyingInstance::SetFlyTarget": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::SetFlyTarget" + ] + }, + "CFlyingInstance::AdjustDirectionForHoming": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::AdjustDirectionForHoming" + ] + }, + "CFlyingInstance::UpdateAttachInstance": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::UpdateAttachInstance" + ] + }, + "CFlyingInstance::Update": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::Update" + ] + }, + "CFlyingInstance::ClearAttachInstance": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::ClearAttachInstance" + ] + }, + "CFlyingInstance::__Explode": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::__Explode" + ] + }, + "CFlyingInstance::__Bomb": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::__Bomb" + ] + }, + "CFlyingInstance::Render": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::Render" + ] + }, + "CFlyingInstance::RenderAttachInstance": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::RenderAttachInstance" + ] + }, + "CFlyingInstance::SetDataPointer": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::SetDataPointer" + ] + }, + "CFlyingInstance::__SetDataPointer": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingInstance.cpp:CFlyingInstance::__SetDataPointer" + ] + } + } +} diff --git a/audit/port-map/GameLib/FlyingObjectManager.cpp.json b/audit/port-map/GameLib/FlyingObjectManager.cpp.json new file mode 100644 index 00000000..879db520 --- /dev/null +++ b/audit/port-map/GameLib/FlyingObjectManager.cpp.json @@ -0,0 +1,80 @@ +{ + "reference": "GameLib/FlyingObjectManager.cpp", + "reference_sha256": "9b6ce94579bd3b536d12bf163175c171214250e4f88abbd03f5ebe076416b4e6", + "priority": "P1", + "contracts": [], + "functions": { + "CFlyingManager::CFlyingManager": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingObjectManager.cpp:CFlyingManager::CFlyingManager" + ] + }, + "CFlyingManager::~CFlyingManager": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingObjectManager.cpp:CFlyingManager::~CFlyingManager" + ] + }, + "CFlyingManager::__DestroyFlyingInstanceList": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingObjectManager.cpp:CFlyingManager::__DestroyFlyingInstanceList" + ] + }, + "CFlyingManager::__DestroyFlyingDataMap": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingObjectManager.cpp:CFlyingManager::__DestroyFlyingDataMap" + ] + }, + "CFlyingManager::DeleteAllInstances": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingObjectManager.cpp:CFlyingManager::DeleteAllInstances" + ] + }, + "CFlyingManager::Destroy": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingObjectManager.cpp:CFlyingManager::Destroy" + ] + }, + "CFlyingManager::RegisterFlyingData": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingObjectManager.cpp:CFlyingManager::RegisterFlyingData" + ] + }, + "CFlyingManager::CreateFlyingInstanceFlyTarget": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingObjectManager.cpp:CFlyingManager::CreateFlyingInstanceFlyTarget" + ] + }, + "CFlyingManager::Update": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingObjectManager.cpp:CFlyingManager::Update" + ] + }, + "CFlyingManager::Render": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingObjectManager.cpp:CFlyingManager::Render" + ] + }, + "CFlyingManager::RegisterIndexedFlyData": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingObjectManager.cpp:CFlyingManager::RegisterIndexedFlyData" + ] + }, + "CFlyingManager::CreateIndexedFly": { + "status": "PORTED", + "impl": [ + "extension/src/port/GameLib/FlyingObjectManager.cpp:CFlyingManager::CreateIndexedFly" + ] + } + } +} diff --git a/audit/port-map/GameLib/MapManager.cpp.json b/audit/port-map/GameLib/MapManager.cpp.json index ce138c27..dbdca8b0 100644 --- a/audit/port-map/GameLib/MapManager.cpp.json +++ b/audit/port-map/GameLib/MapManager.cpp.json @@ -104,7 +104,12 @@ "test": "project/python_game_render_test.gd" }, "CMapManager::GetTerrainHeight": { - "status": "TODO" + "status": "ADAPTED", + "impl": [ + "extension/src/platform/pending/GameLib/MapManager.cpp:CMapManager::GetTerrainHeight" + ], + "note": "CMapOutdoor::GetTerrainHeight: 40250 terrain triangle interpolation on packed height.raw. GetHeight forwards here until map objects are registered (CMapOutdoor::GetHeight's object half).", + "test": "extension/tests/port_login_flow_test.cpp" }, "CMapManager::GetWaterHeight": { "status": "TODO" diff --git a/audit/port-map/UserInterface/PythonEffectModule.cpp.json b/audit/port-map/UserInterface/PythonEffectModule.cpp.json new file mode 100644 index 00000000..66b31713 --- /dev/null +++ b/audit/port-map/UserInterface/PythonEffectModule.cpp.json @@ -0,0 +1,56 @@ +{ + "reference": "UserInterface/PythonEffectModule.cpp", + "reference_sha256": "303f2a312bede11c7258f8d61b79e19643e62f7aa7afb057d566315536b88a1b", + "priority": "P4", + "contracts": [], + "functions": { + "effectRegisterEffect": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonEffectModule.cpp:effectRegisterEffect" + ] + }, + "effectUpdate": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonEffectModule.cpp:effectUpdate" + ] + }, + "effectRender": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonEffectModule.cpp:effectRender" + ] + }, + "effectCreateEffect": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonEffectModule.cpp:effectCreateEffect" + ] + }, + "effectDeleteEffect": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonEffectModule.cpp:effectDeleteEffect" + ] + }, + "effectSetPosition": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonEffectModule.cpp:effectSetPosition" + ] + }, + "effectRegisterIndexedFlyData": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonEffectModule.cpp:effectRegisterIndexedFlyData" + ] + }, + "initeffect": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonEffectModule.cpp:initeffect" + ] + } + } +} diff --git a/audit/port-map/UserInterface/PythonFlyModule.cpp.json b/audit/port-map/UserInterface/PythonFlyModule.cpp.json new file mode 100644 index 00000000..9fd220ea --- /dev/null +++ b/audit/port-map/UserInterface/PythonFlyModule.cpp.json @@ -0,0 +1,26 @@ +{ + "reference": "UserInterface/PythonFlyModule.cpp", + "reference_sha256": "3afa92192ab630875c922b1901f1c3ea2aa9e82390121c426a74079a455841f7", + "priority": "P4", + "contracts": [], + "functions": { + "flyUpdate": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonFlyModule.cpp:flyUpdate" + ] + }, + "flyRender": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonFlyModule.cpp:flyRender" + ] + }, + "initfly": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonFlyModule.cpp:initfly" + ] + } + } +} diff --git a/docs/PORT-PLAN.md b/docs/PORT-PLAN.md index 593c2540..701f4374 100644 --- a/docs/PORT-PLAN.md +++ b/docs/PORT-PLAN.md @@ -431,7 +431,7 @@ extension/third_party/cpython-2.7.18/ # 静态库(2P 批次 改变位置/朝向、发送与 40250 相同的移动封包,并在离线边界测试和真服 smoke 中通过。接通时删除对应 legacy 玩法逻辑。 2V3-a(2026-09-23):`PythonPlayer`、`PythonPlayerInput`/`InputKeyboard`/`InputMouse`、`PythonPlayerEventHandler`、`PythonPlayerSkill`、`PythonPlayerModule`、`GameType` 原样移植(port-map 标 PORTED),`GameplayModules.cpp` 的 `player` 桩删除,`initPlayer()` 按 40250 顺序在 `initchrmgr()` 后调用;`pending/UserInterface/{PythonPlayer,GameType}.cpp` 替身删除,其余被调方(`CPythonSkill`、`CItemData`、`CItemManager`、`CPythonItem` 等)进 `pending`。64 位修正:`playerGetEmotionIconImage` 用 `Py_BuildPointer`,`PyDict_Next` 用 `Py_ssize_t`。根运动:Granny 运行时的 `GrannyUpdateModelMatrix` 原为直通,按 TrackGroups[0] 的 `AccumulationFlags`(AccumulationExtracted)/`LoopTranslation`(libgr2 新读出,战士 run = (0,-300,0),同 .msa `Accumulation`)按控制器本地时钟推进与权重累加位移(Delta × ModelMatrix);VDA 抽取未实现。`port.login_flow` 按 DIK_UP 经 `game.GameWindow` → `player.SetSingleDIKKeyState` 行走 >100 cm,假服解析 CG 包,收到 `CG_MOVE` FUNC_MOVE 后 FUNC_WAIT 且坐标变化;`port.login_live` 2026-09-23 对 192.168.21.203 走 132 cm 通过。(2V3-a 的待办见 2V3-b。) 2V3-b(2026-09-23):鼠标点地移动。`CScreen::SetCursorPosition`(GrpScreen.cpp:487)与 `CPythonGraphic::SetCursorPosition` 原样实现,`RenderGame` 每帧用光标建拾取射线;`CPythonBackground::GetPickingPoint`/`GetPickingPointWithRay`/`GetPickingPointWithRayOnlyTerrain` 按 `CMapOutdoor::__PickTerrainHeight` 原样沿射线步进,地形高度取 native `CMapManager::GetHeight`(`PR_FLOAT_TO_INT` 的 x87 取整按 floor),物件拾取随 `CMapOutdoor` 移植再接。`CMapManager::isAttrOn` 按 `CMapOutdoor::isAttrOn`+`CTerrain::isAttrOn` 读包内 `//attr.atr`(阻挡/水/禁 PK),`CheckAdvancing` 及两个碰撞检查器原样(地图物件未注册到 `CCullingManager` 前不会阻挡)。以上在 pending/platform 层,port-map 标 ADAPTED。`port.login_flow` 在按键行走后左键点击角色下方地面:`game.GameWindow.OnMouseLeftButtonDown` → `player.SetMouseState` → 角色走到拾取点(离线 334 cm),假服收到 FUNC_MOVE … FUNC_WAIT;另断言角色所在格不阻挡、所在地形块有阻挡格(离线 17814 格)。`port.login_live` 2026-09-23 对 192.168.21.203 通过(按键 133 cm、点地 296 cm、11406 阻挡格),`python_game_render_test.sh` 离线通过。`client_main` 的 `MT_TEST_MODE=python_ui` 加上 `python_3d_surface.gd`,新路径可手动登录进游戏走动。待办:默认路由切到 `port`(当前 `client_main` 默认仍走 GDScript `AppFlow`)后整体删除 legacy;攻击/拾取物品等 P1 战斗交互属批次 2 之后。 - 批次 2 P0 收尾(2026-09-24):`UserInterface/PythonCharacterManager.cpp`(54 函数)与 `InstanceBaseMovement.cpp`(32 函数)在 2V2-b 已原样拷入 `port/`,2V3 起即是运行路径(行走、点地移动、远程角色同步都经它们),本轮逐行比对 40250(仅 include 大小写、注释编码和两处 `// PORT:` 修正:`CreateInstance` 的 TraceError 传 `m_dwVID`,`NEW_SyncPixelPosition` 用 32 位 `LONG &`),确认 pending/platform 无重复定义后标 PORTED。P0 队列已清空;下一步按队列做 P1(`FlyingInstance`、`ActorInstanceData`、`FlyingObjectManager`、`FlyTrace`)。 + 批次 2 P0 收尾(2026-09-24):`UserInterface/PythonCharacterManager.cpp`(54 函数)与 `InstanceBaseMovement.cpp`(32 函数)在 2V2-b 已原样拷入 `port/`,2V3 起即是运行路径(行走、点地移动、远程角色同步都经它们),本轮逐行比对 40250(仅 include 大小写、注释编码和两处 `// PORT:` 修正:`CreateInstance` 的 TraceError 传 `m_dwVID`,`NEW_SyncPixelPosition` 用 32 位 `LONG &`),确认 pending/platform 无重复定义后标 PORTED。P0 队列已清空;P1 飞行物(同日):`GameLib/FlyingData`、`FlyingInstance`、`FlyingObjectManager`、`FlyTrace` 与 Python 模块 `PythonEffectModule`(`effect`)、`PythonFlyModule`(`fly`)原样移植,删除 `pending/GameLib/FlyingObjectManager.cpp` 替身和两个模块的桩,`initeffect()`/`initfly()` 按 40250 顺序在 `initnet()` 后调用;`CFlyingManager::SetMapManagerPtr(&CPythonBackground)` 按 40250 构造函数接上;`FlyTrace.h` 加 `// PORT:` include 以过头文件门禁。`CMapManager::GetTerrainHeight`(飞行物落地判断用)在 pending 层按 native 地形高度实现,`GetHeight` 转发到它(地图物件高度待 `CMapOutdoor`)。`ActorInstanceData.cpp` 早已原样在 port/,一并标 PORTED。`port.login_flow` 断言 `playersettingmodule.py` 已经 `effect.RegisterIndexedFlyData` 注册并能解析 `.msf`。特效本体(`CEffectManager`)仍是平台桩,飞行物不可见;队列里 P0/P1 已清空,剩下 P2 网络单元(多数已在 2V1 原样拷入 port/,待逐个核对后标记)。 每个切片都必须同时跑 legacy/port 双路回归;只有 2V3 稳定并把默认路由切到 `port` 后,才能删除总开关和剩余 legacy 宿主。 diff --git a/extension/src/platform/ScriptLib/GameplayModuleConstants.cpp b/extension/src/platform/ScriptLib/GameplayModuleConstants.cpp index 1c9f71c0..e7c2b02c 100644 --- a/extension/src/platform/ScriptLib/GameplayModuleConstants.cpp +++ b/extension/src/platform/ScriptLib/GameplayModuleConstants.cpp @@ -73,54 +73,6 @@ void AddStubConstants_background(PyObject* poModule) PyModule_AddIntConstant(poModule, "TEXTURE_SORT", CMapOutdoor::TEXTURE_SORT); } -// 40250 UserInterface/PythonEffectModule.cpp - enum -{ - FLY_NONE, - FLY_EXP, - FLY_HP_MEDIUM, - FLY_HP_BIG, - FLY_SP_SMALL, - FLY_SP_MEDIUM, - FLY_SP_BIG, - FLY_FIREWORK1, - FLY_FIREWORK2, - FLY_FIREWORK3, - FLY_FIREWORK4, - FLY_FIREWORK5, - FLY_FIREWORK6, - FLY_FIREWORK_XMAS, - FLY_CHAIN_LIGHTNING, - FLY_HP_SMALL, - FLY_SKILL_MUYEONG, -}; - -// 40250 UserInterface/PythonEffectModule.cpp -void AddStubConstants_effect(PyObject* poModule) -{ - (void) poModule; - PyModule_AddIntConstant(poModule, "INDEX_FLY_TYPE_NORMAL", CFlyingManager::INDEX_FLY_TYPE_NORMAL); - PyModule_AddIntConstant(poModule, "INDEX_FLY_TYPE_FIRE_CRACKER", CFlyingManager::INDEX_FLY_TYPE_FIRE_CRACKER); - PyModule_AddIntConstant(poModule, "INDEX_FLY_TYPE_AUTO_FIRE", CFlyingManager::INDEX_FLY_TYPE_AUTO_FIRE); - PyModule_AddIntConstant(poModule, "FLY_NONE", FLY_NONE); - PyModule_AddIntConstant(poModule, "FLY_EXP", FLY_EXP); - PyModule_AddIntConstant(poModule, "FLY_HP_MEDIUM", FLY_HP_MEDIUM); - PyModule_AddIntConstant(poModule, "FLY_HP_BIG", FLY_HP_BIG); - PyModule_AddIntConstant(poModule, "FLY_SP_SMALL", FLY_SP_SMALL); - PyModule_AddIntConstant(poModule, "FLY_SP_MEDIUM", FLY_SP_MEDIUM); - PyModule_AddIntConstant(poModule, "FLY_SP_BIG", FLY_SP_BIG); - PyModule_AddIntConstant(poModule, "FLY_FIREWORK1", FLY_FIREWORK1); - PyModule_AddIntConstant(poModule, "FLY_FIREWORK2", FLY_FIREWORK2); - PyModule_AddIntConstant(poModule, "FLY_FIREWORK3", FLY_FIREWORK3); - PyModule_AddIntConstant(poModule, "FLY_FIREWORK4", FLY_FIREWORK4); - PyModule_AddIntConstant(poModule, "FLY_FIREWORK5", FLY_FIREWORK5); - PyModule_AddIntConstant(poModule, "FLY_FIREWORK6", FLY_FIREWORK6); - PyModule_AddIntConstant(poModule, "FLY_FIREWORK_XMAS", FLY_FIREWORK_XMAS); - PyModule_AddIntConstant(poModule, "FLY_CHAIN_LIGHTNING", FLY_CHAIN_LIGHTNING); - PyModule_AddIntConstant(poModule, "FLY_HP_SMALL", FLY_HP_SMALL); - PyModule_AddIntConstant(poModule, "FLY_SKILL_MUYEONG", FLY_SKILL_MUYEONG); -} - // 40250 UserInterface/PythonEventManagerMoudle.cpp void AddStubConstants_event(PyObject* poModule) { @@ -144,12 +96,6 @@ void AddStubConstants_exchange(PyObject* poModule) PyModule_AddIntConstant(poModule, "EXCHANGE_ITEM_MAX_NUM", CPythonExchange::EXCHANGE_ITEM_MAX_NUM); } -// 40250 UserInterface/PythonFlyModule.cpp -void AddStubConstants_fly(PyObject* poModule) -{ - (void) poModule; -} - // 40250 UserInterface/PythonGuild.cpp void AddStubConstants_guild(PyObject* poModule) { diff --git a/extension/src/platform/ScriptLib/GameplayModules.cpp b/extension/src/platform/ScriptLib/GameplayModules.cpp index 19629516..2d075584 100644 --- a/extension/src/platform/ScriptLib/GameplayModules.cpp +++ b/extension/src/platform/ScriptLib/GameplayModules.cpp @@ -7,11 +7,9 @@ // GameplayModuleConstants.cpp: each module's 40250 constants. void AddStubConstants_ServerStateChecker(PyObject* poModule); void AddStubConstants_background(PyObject* poModule); -void AddStubConstants_effect(PyObject* poModule); void AddStubConstants_event(PyObject* poModule); void AddStubConstants_eventMgr(PyObject* poModule); void AddStubConstants_exchange(PyObject* poModule); -void AddStubConstants_fly(PyObject* poModule); void AddStubConstants_guild(PyObject* poModule); void AddStubConstants_ime(PyObject* poModule); void AddStubConstants_item(PyObject* poModule); @@ -150,24 +148,6 @@ PyMethodDef methods_background[] = { { "WarpTest", stub_background_WarpTest, METH_VARARGS }, { NULL, NULL } }; -// 40250 UserInterface/PythonEffectModule.cpp: effect export names. -PyObject* stub_effect_RegisterEffect(PyObject*, PyObject*) { return stub_call_named("effect.RegisterEffect", Py_BuildNone()); } -PyObject* stub_effect_CreateEffect(PyObject*, PyObject*) { return stub_call_named("effect.CreateEffect", Py_BuildValue("i", 0)); } -PyObject* stub_effect_DeleteEffect(PyObject*, PyObject*) { return stub_call_named("effect.DeleteEffect", Py_BuildNone()); } -PyObject* stub_effect_SetPosition(PyObject*, PyObject*) { return stub_call_named("effect.SetPosition", Py_BuildNone()); } -PyObject* stub_effect_RegisterIndexedFlyData(PyObject*, PyObject*) { return stub_call_named("effect.RegisterIndexedFlyData", Py_BuildNone()); } -PyObject* stub_effect_Update(PyObject*, PyObject*) { return stub_call_named("effect.Update", Py_BuildNone()); } -PyObject* stub_effect_Render(PyObject*, PyObject*) { return stub_call_named("effect.Render", Py_BuildNone()); } -PyMethodDef methods_effect[] = { - { "RegisterEffect", stub_effect_RegisterEffect, METH_VARARGS }, - { "CreateEffect", stub_effect_CreateEffect, METH_VARARGS }, - { "DeleteEffect", stub_effect_DeleteEffect, METH_VARARGS }, - { "SetPosition", stub_effect_SetPosition, METH_VARARGS }, - { "RegisterIndexedFlyData", stub_effect_RegisterIndexedFlyData, METH_VARARGS }, - { "Update", stub_effect_Update, METH_VARARGS }, - { "Render", stub_effect_Render, METH_VARARGS }, - { NULL, NULL } -}; // 40250 UserInterface/PythonEventManagerMoudle.cpp: event export names. PyObject* stub_event_RegisterEventSet(PyObject*, PyObject*) { return stub_call_named("event.RegisterEventSet", Py_BuildValue("i", 0)); } PyObject* stub_event_RegisterEventSetFromString(PyObject*, PyObject*) { return stub_call_named("event.RegisterEventSetFromString", Py_BuildValue("i", 0)); } @@ -264,14 +244,6 @@ PyMethodDef methods_exchange[] = { { "SetElkMode", stub_exchange_SetElkMode, METH_VARARGS }, { NULL, NULL } }; -// 40250 UserInterface/PythonFlyModule.cpp: fly export names. -PyObject* stub_fly_Update(PyObject*, PyObject*) { return stub_call_named("fly.Update", Py_BuildNone()); } -PyObject* stub_fly_Render(PyObject*, PyObject*) { return stub_call_named("fly.Render", Py_BuildNone()); } -PyMethodDef methods_fly[] = { - { "Update", stub_fly_Update, METH_VARARGS }, - { "Render", stub_fly_Render, METH_VARARGS }, - { NULL, NULL } -}; // 40250 UserInterface/PythonGuild.cpp: guild export names. PyObject* stub_guild_IsGuildEnable(PyObject*, PyObject*) { return stub_call_named("guild.IsGuildEnable", Py_BuildValue("i", 0)); } PyObject* stub_guild_GuildIDToMarkID(PyObject*, PyObject*) { return stub_call_named("guild.GuildIDToMarkID", Py_BuildValue("i", 0)); } @@ -930,11 +902,6 @@ void init_2v0_gameplay_stubs() { PyModule_AddIntConstant(module, "__port_stub__", 1); AddStubConstants_background(module); } - { - PyObject* module = Py_InitModule("effect", methods_effect); - PyModule_AddIntConstant(module, "__port_stub__", 1); - AddStubConstants_effect(module); - } { PyObject* module = Py_InitModule("event", methods_event); PyModule_AddIntConstant(module, "__port_stub__", 1); @@ -950,11 +917,6 @@ void init_2v0_gameplay_stubs() { PyModule_AddIntConstant(module, "__port_stub__", 1); AddStubConstants_exchange(module); } - { - PyObject* module = Py_InitModule("fly", methods_fly); - PyModule_AddIntConstant(module, "__port_stub__", 1); - AddStubConstants_fly(module); - } { PyObject* module = Py_InitModule("guild", methods_guild); PyModule_AddIntConstant(module, "__port_stub__", 1); diff --git a/extension/src/platform/ScriptLib/PythonBoot.cpp b/extension/src/platform/ScriptLib/PythonBoot.cpp index e68ee5e4..1f277bdd 100644 --- a/extension/src/platform/ScriptLib/PythonBoot.cpp +++ b/extension/src/platform/ScriptLib/PythonBoot.cpp @@ -319,6 +319,7 @@ bool Start(const char* stdlib_path, std::string* error) g_effect_manager = std::make_unique(); g_game_application = std::make_unique(); g_game_singletons = std::make_unique(); + g_flying_manager->SetMapManagerPtr(&g_game_singletons->pyBackground); // 40250 CPythonApplication ctor (PythonApplication.cpp:82) return true; } @@ -344,6 +345,8 @@ bool run_main_script_body(const char* lpCmdLine, std::string* error) initPlayer(); initChat(); initnet(); + initeffect(); + initfly(); init_2v0_gameplay_stubs(); ClearLogBoxMessage(); diff --git a/extension/src/platform/pending/GameLib/FlyingObjectManager.cpp b/extension/src/platform/pending/GameLib/FlyingObjectManager.cpp deleted file mode 100644 index ebd02f29..00000000 --- a/extension/src/platform/pending/GameLib/FlyingObjectManager.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// Stand-in for the 40250 logic unit GameLib/FlyingObjectManager.cpp, not ported yet: the platform_stub.py skeleton of its -// header, so the units that call it (批次 2V1, the network slice) link. Delete this file in the commit -// that ports the unit into port/ (docs/PORT-PLAN.md 2V1). -#include "GameLib/StdAfx.h" -#include "GameLib/FlyingObjectManager.h" - -#include "../../PlatformStub.h" - -CFlyingManager::CFlyingManager() -{ - MT_PLATFORM_STUB(); -} - -CFlyingManager::~CFlyingManager() -{ - MT_PLATFORM_STUB(); -} - -auto CFlyingManager::Destroy() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CFlyingManager::DeleteAllInstances() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CFlyingManager::RegisterFlyingData(const char *) -> bool -{ - MT_PLATFORM_STUB(); - return mt_platform_stub_return(); -} - -auto CFlyingManager::RegisterFlyingData(const char *, DWORD &) -> bool -{ - MT_PLATFORM_STUB(); - return mt_platform_stub_return(); -} - -auto CFlyingManager::CreateFlyingInstanceFlyTarget(const DWORD, const D3DXVECTOR3 &, const CFlyTarget &, bool) -> CFlyingInstance * -{ - MT_PLATFORM_STUB(); - return mt_platform_stub_return(); -} - -auto CFlyingManager::Update() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CFlyingManager::Render() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CFlyingManager::RegisterIndexedFlyData(DWORD, BYTE, const char *) -> bool -{ - MT_PLATFORM_STUB(); - return mt_platform_stub_return(); -} - -auto CFlyingManager::CreateIndexedFly(DWORD, CActorInstance *, CActorInstance *) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CFlyingManager::__DestroyFlyingInstanceList() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CFlyingManager::__DestroyFlyingDataMap() -> void -{ - MT_PLATFORM_STUB(); -} diff --git a/extension/src/platform/pending/GameLib/MapManager.cpp b/extension/src/platform/pending/GameLib/MapManager.cpp index 4ac59be4..b808ab21 100644 --- a/extension/src/platform/pending/GameLib/MapManager.cpp +++ b/extension/src/platform/pending/GameLib/MapManager.cpp @@ -86,7 +86,15 @@ const std::vector *attr_tile(NativeMapState &state, int tx, int ty) } } +// CMapOutdoor::GetHeight is max(terrain, object height under CCullingManager); no map objects are registered +// until CMapOutdoor is ported, so it is the terrain height. auto CMapManager::GetHeight(float fx, float fy) -> float +{ + return GetTerrainHeight(fx, fy); +} + +// CMapOutdoor::GetTerrainHeight over the native height tiles. +auto CMapManager::GetTerrainHeight(float fx, float fy) -> float { auto found = s_native_maps.find(this); if (found == s_native_maps.end() || !found->second.ready) diff --git a/extension/src/port/GameLib/FlyTrace.cpp b/extension/src/port/GameLib/FlyTrace.cpp new file mode 100644 index 00000000..88713e82 --- /dev/null +++ b/extension/src/port/GameLib/FlyTrace.cpp @@ -0,0 +1,291 @@ +#include "StdAfx.h" +#include "../EterLib/StateManager.h" +#include "../EterLib/Camera.h" + +#include "FlyingData.h" +#include "FlyTrace.h" + +CDynamicPool CFlyTrace::ms_kPool; + +void CFlyTrace::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CFlyTrace* CFlyTrace::New() +{ + return ms_kPool.Alloc(); +} + +void CFlyTrace::Delete(CFlyTrace* pkInst) +{ + pkInst->Destroy(); + ms_kPool.Free(pkInst); +} + +CFlyTrace::CFlyTrace() +{ + __Initialize(); + + /* + // Code for texture + CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ray.jpg"); + m_ImageInstance.SetImagePointer(pImage); + + CGraphicTexture * pTexture = m_ImageInstance.GetTexturePointer(); + m_lpTexture = pTexture->GetD3DTexture(); + */ +} + +CFlyTrace::~CFlyTrace() +{ + Destroy(); +} + + +void CFlyTrace::__Initialize() +{ + m_bRectShape=false; + m_dwColor=0; + m_fSize=0.0f; + m_fTailLength=0.0f; +} + +void CFlyTrace::Destroy() +{ + m_TimePositionDeque.clear(); + + __Initialize(); +} + +void CFlyTrace::UpdateNewPosition(const D3DXVECTOR3 & v3Position) +{ + m_TimePositionDeque.push_front(TTimePosition(CTimer::Instance().GetCurrentSecond(),v3Position)); + //Tracenf("%f %f",m_TimePositionDeque.back().first, CTimer::Instance().GetCurrentSecond()); + while(!m_TimePositionDeque.empty() && m_TimePositionDeque.back().first+m_fTailLength > TFlyVertexSetVector; + +void CFlyTrace::Render() +{ + if (m_TimePositionDeque.size()<=1) + return; + TFlyVertexSetVector VSVector; + + //STATEMANAGER.SaveRenderState(D3DRS_ZFUNC,D3DCMP_LESS); + STATEMANAGER.SaveRenderState(D3DRS_ZFUNC,D3DCMP_LESS); + //STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE,FALSE); + + 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_ONE); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000000); + + STATEMANAGER.SaveRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD ); + //STATEMANAGER.SaveRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD ); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); + //STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, /*(m_bUseTexture)?D3DTOP_SELECTARG2:*/D3DTOP_SELECTARG2); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + + 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, NULL); + STATEMANAGER.SetTexture(1, NULL); + + + D3DXMATRIX m; + CScreen s;s.UpdateViewMatrix(); + CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!pCurrentCamera) + return; + + const D3DXMATRIX & M = pCurrentCamera->GetViewMatrix(); + D3DXMatrixIdentity(&m); + D3DXVECTOR3 F(pCurrentCamera->GetView()); + m._31 = F.x; + m._32 = F.y; + m._33 = F.z; + + Frustum & frustum = s.GetFrustum(); + //frustum.BuildViewFrustum(ms_matView * ms_matProj); + + TTimePositionDeque::iterator it1, it2; + it2 = it1 = m_TimePositionDeque.begin(); + ++it2; + for(;it2!=m_TimePositionDeque.end();++it2,++it1) + { + const D3DXVECTOR3& rkOld=it1->second; + const D3DXVECTOR3& rkNew=it2->second; + D3DXVECTOR3 B = rkNew - rkOld; + + float radius = max(fabs(B.x),max(fabs(B.y),fabs(B.z)))/2; + Vector3d c(it1->second.x+B.x*0.5f, + it1->second.y+B.y*0.5f, + it1->second.z+B.z*0.5f + ); + if (frustum.ViewVolumeTest(c, radius)==VS_OUTSIDE) + continue; + + float rate1 = (1-(CTimer::Instance().GetCurrentSecond()-it1->first)/m_fTailLength); + float rate2 = (1-(CTimer::Instance().GetCurrentSecond()-it2->first)/m_fTailLength); + float size1 = m_fSize; + float size2 = m_fSize; + if (!m_bRectShape) + { + size1 *= rate1; + size2 *= rate2; + } + TFlyVertex v[6] = + { + TFlyVertex(D3DXVECTOR3(0.0f,size1,0.0f), m_dwColor,D3DXVECTOR2(0.0f,0.0f)), + TFlyVertex(D3DXVECTOR3(-size1,0.0f,0.0f),m_dwColor,D3DXVECTOR2(0.0f,0.5f)), + TFlyVertex(D3DXVECTOR3(size1,0.0f,0.0f), m_dwColor,D3DXVECTOR2(0.5f,0.0f)), + TFlyVertex(D3DXVECTOR3(-size2,0.0f,0.0f),m_dwColor,D3DXVECTOR2(0.5f,1.0f)), + TFlyVertex(D3DXVECTOR3(size2,0.0f,0.0f), m_dwColor,D3DXVECTOR2(1.0f,0.5f)), + TFlyVertex(D3DXVECTOR3(0.0f,-size2,0.0f),m_dwColor,D3DXVECTOR2(1.0f,1.0f)), + + /*TVertex(D3DXVECTOR3(0.0f,size1,0.0f), ((DWORD)(0x40*rate1)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(-size1,0.0f,0.0f),((DWORD)(0x40*rate1)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(size1,0.0f,0.0f), ((DWORD)(0x40*rate1)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(-size2,0.0f,0.0f),((DWORD)(0x40*rate2)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(size2,0.0f,0.0f), ((DWORD)(0x40*rate2)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(0.0f,-size2,0.0f),((DWORD)(0x40*rate2)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)),*/ + + /*TVertex(D3DXVECTOR3(0.0f,size1,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(-size1,0.0f,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(size1,0.0f,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(-size2,0.0f,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(size2,0.0f,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(0.0f,-size2,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)),*/ + + /*TVertex(D3DXVECTOR3(0.0f,size1,0.0f),0xffff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(-size1,0.0f,0.0f),0xffff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(size1,0.0f,0.0f),0xffff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(-size2,0.0f,0.0f),0xff0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(size2,0.0f,0.0f),0xff0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(0.0f,-size2,0.0f),0xff0000ff,D3DXVECTOR2(0.0f,0.0f)),*/ + }; + + + D3DXVECTOR3 E(M._41,M._42,M._43); + E = pCurrentCamera->GetEye(); + E-=it1->second; + + D3DXVECTOR3 P; + D3DXVec3Cross(&P, &B,&E); + + D3DXVECTOR3 U; + D3DXVec3Cross(&U,&F,&P); + D3DXVec3Normalize(&U,&U); + D3DXVECTOR3 R; + D3DXVec3Cross(&R,&F,&U); + //D3DXMatrixIdentity(&m); + m._21 = U.x; + m._22 = U.y; + m._23 = U.z; + m._11 = R.x; + m._12 = R.y; + m._13 = R.z; + int i; + for(i=0;i<6;i++) + D3DXVec3TransformNormal(&v[i].p,&v[i].p,&m); + for(i=0;i<3;i++) + v[i].p += it1->second; + for(;i<6;i++) + v[i].p += it2->second; + //for(i=0;i<6;i++) + // Tracenf("#%d:%f %f %f", i, v[i].p.x,v[i].p.y,v[i].p.z); + + VSVector.push_back(std::make_pair(-D3DXVec3Dot(&E,&pCurrentCamera->GetView()),TFlyVertexSet(v))); + //OLD: STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 4, v, sizeof(TVertex)); + //OLD: STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v+1, sizeof(TVertex)); + } + + std::sort(VSVector.begin(),VSVector.end()); + + for(TFlyVertexSetVector::iterator it = VSVector.begin();it!=VSVector.end();++it) + { + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 4, it->second.v, sizeof(TVertex)); + } + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); + STATEMANAGER.RestoreVertexShader(); + STATEMANAGER.RestoreTransform(D3DTS_WORLD); + //STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ZFUNC); + STATEMANAGER.RestoreRenderState(D3DRS_BLENDOP); + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF); + +} \ No newline at end of file diff --git a/extension/src/port/GameLib/FlyTrace.h b/extension/src/port/GameLib/FlyTrace.h new file mode 100644 index 00000000..45615817 --- /dev/null +++ b/extension/src/port/GameLib/FlyTrace.h @@ -0,0 +1,44 @@ +#pragma once + +#include "FlyingData.h" // PORT: CFlyingData::TFlyingAttachData below; 40250 includers bring it first, the header gate compiles this alone + +class CFlyTrace : public CScreen +{ + public: + CFlyTrace(); + virtual ~CFlyTrace(); + + void Destroy(); + + void Create(const CFlyingData::TFlyingAttachData & rFlyingAttachData); + + void UpdateNewPosition(const D3DXVECTOR3 & v3Position); + + void Update(); + void Render(); + + protected: + void __Initialize(); + + protected: + typedef std::pair TTimePosition; + typedef std::deque TTimePositionDeque; + + //CGraphicImageInstance m_ImageInstance; + //LPDIRECT3DTEXTURE8 m_lpTexture; + + bool m_bRectShape; + DWORD m_dwColor; + float m_fSize; + float m_fTailLength; + + TTimePositionDeque m_TimePositionDeque; + + public: + static void DestroySystem(); + + static CFlyTrace* New(); + static void Delete(CFlyTrace* pkInst); + + static CDynamicPool ms_kPool; +}; \ No newline at end of file diff --git a/extension/src/port/GameLib/FlyingData.cpp b/extension/src/port/GameLib/FlyingData.cpp new file mode 100644 index 00000000..a7fc7001 --- /dev/null +++ b/extension/src/port/GameLib/FlyingData.cpp @@ -0,0 +1,353 @@ +#include "StdAfx.h" +#include "../EffectLib/EffectManager.h" + +#include "FlyingData.h" + +CDynamicPool CFlyingData::ms_kPool; + +CFlyingData::CFlyingData() +{ + __Initialize(); +} + +void CFlyingData::__Initialize() +{ + m_v3AngVel = D3DXVECTOR3(0.0f,0.0f,0.0f); + m_bIsHoming = false; + m_fInitVel = 200.0f; + m_fConeAngle = (0.0f); + m_fRollAngle = 0.0f; + m_fRange = 500.0f; + m_v3Accel = D3DXVECTOR3(0,0,0.0f);// gravity direction :-z + m_fHomingMaxAngle = 3.0f; + m_fHomingStartTime = 0.0f; + m_fGravity = 0; + m_bSpreading = false; + m_bMaintainParallel = false; + + m_bHitOnBackground = false; + m_bHitOnAnotherMonster = false; + m_iPierceCount = 0; + m_fCollisionSphereRadius = 0.0f; + + m_fBombRange = 10.0f; + SetBombEffect(""); +} + +void CFlyingData::Destroy() +{ + m_AttachDataVector.clear(); + + __Initialize(); +} + +CFlyingData::~CFlyingData() +{ + Destroy(); +} + +void CFlyingData::SetBombEffect(const char* szEffectName) +{ + m_strBombEffectName = szEffectName; + if (m_strBombEffectName.empty()) + { + m_dwBombEffectID = 0; + return; + } + StringPath(m_strBombEffectName); + if (CEffectManager::Instance().RegisterEffect(m_strBombEffectName.c_str()),true) + { + m_dwBombEffectID = GetCaseCRC32(m_strBombEffectName.c_str(),m_strBombEffectName.size()); + } + else + { + m_dwBombEffectID = 0; + } + +} + +CFlyingData::TFlyingAttachData & CFlyingData::GetAttachDataReference(int iIndex) +{ + return m_AttachDataVector[iIndex]; +} + +DWORD CFlyingData::AttachFlyEffect(int iType, const std::string & strFilename, float fRoll, float fArg1, float fArg2) +{ + TFlyingAttachData fad; + memset(&fad,0, sizeof(fad)); + fad.iType = FLY_ATTACH_EFFECT; + fad.iFlyType = iType; + fad.fPeriod = 1.0f; + fad.strFilename = strFilename; + fad.fRoll = fRoll; + fad.dwTailColor = 0xffffffff; + fad.fTailLength = 1.0f; + fad.fTailSize = 10.0f; + + switch(iType) + { + case FLY_ATTACH_TYPE_MULTI_LINE: + fad.fDistance = fArg1; + break; + case FLY_ATTACH_TYPE_SINE: + case FLY_ATTACH_TYPE_EXP: + fad.fPeriod=fArg1; + fad.fAmplitude=fArg2; + break; + case FLY_ATTACH_TYPE_NONE: + case FLY_ATTACH_TYPE_LINE: + default: + // Do nothing + break; + } + + m_AttachDataVector.push_back(fad); + return m_AttachDataVector.size()-1; +} + +void CFlyingData::RemoveAttach(int iIndex) +{ + assert(0<=iIndex && iIndex<(int)m_AttachDataVector.size()); + m_AttachDataVector.erase(m_AttachDataVector.begin()+iIndex); +} + +void CFlyingData::RemoveAllAttach() +{ + m_AttachDataVector.clear(); +} + +void CFlyingData::DuplicateAttach(int iIndex) +{ + assert(0<=iIndex && iIndex<(int)m_AttachDataVector.size()); + m_AttachDataVector.push_back(m_AttachDataVector[iIndex]); +} + +bool CFlyingData::LoadScriptFile(const char* c_szFilename) +{ + NANOBEGIN + Destroy(); + + m_strFilename = c_szFilename; + StringPath(m_strFilename); + CTextFileLoader TextFileLoader; + if (!TextFileLoader.Load(m_strFilename.c_str())) + return false; + + TextFileLoader.SetTop(); + int temp; + + if (!TextFileLoader.GetTokenInteger("spreadingflag",&temp)) + { + m_bSpreading = false; + } + else + { + m_bSpreading = temp?true:false; + } + + if (!TextFileLoader.GetTokenInteger("maintainparallelflag", &temp)) + { + m_bMaintainParallel = false; + } + else + { + m_bMaintainParallel = temp?true:false; + } + + if (!TextFileLoader.GetTokenFloat("initialvelocity",&m_fInitVel)) + { + return false; + } + + TextFileLoader.GetTokenFloat("coneangle", &m_fConeAngle); + //if (!TextFileLoader.GetTokenFloat("coneangle", &m_fConeAngle)) + // m_fConeAngle = 0.0f; + + TextFileLoader.GetTokenFloat("rollangle", &m_fRollAngle); + //if (!TextFileLoader.GetTokenFloat("rollangle", &m_fRollAngle)) + // m_fRollAngle = 0.0f; + + TextFileLoader.GetTokenVector3("angularvelocity",&m_v3AngVel); + //if (!TextFileLoader.GetTokenVector3("angularvelocity",&m_v3AngVel)) + // m_v3AngVel = D3DXVECTOR3(0.0f,0.0f,0.0f); + + TextFileLoader.GetTokenFloat("gravity",&m_fGravity); + //if (!TextFileLoader.GetTokenFloat("gravity",&m_fGravity)) + //m_fGravity = 0.0f; + + if (TextFileLoader.GetTokenInteger("hitonbackground",&temp)) + m_bHitOnBackground = temp?true:false; + else + m_bHitOnBackground = false; + + if (TextFileLoader.GetTokenInteger("hitonanothermonster",&temp)) + m_bHitOnAnotherMonster = temp?true:false; + else + m_bHitOnAnotherMonster = false; + + if (!TextFileLoader.GetTokenInteger("piercecount",&m_iPierceCount)) + m_iPierceCount = 0; + +// if (!TextFileLoader.GetTokenFloat("collisionsphereradius",&m_fCollisionSphereRadius)) +// m_fCollisionSphereRadius = 0.0f; + + TextFileLoader.GetTokenFloat("bombrange",&m_fBombRange); + //if (!TextFileLoader.GetTokenFloat("bombrange",&m_fBombRange)) + // m_fBombRange = 10.0f; + + if (!TextFileLoader.GetTokenString("bombeffect",&m_strBombEffectName)) + { + m_strBombEffectName = ""; + } + else if (!m_strBombEffectName.empty()) + { + if (!IsGlobalFileName(m_strBombEffectName.c_str())) + m_strBombEffectName = GetOnlyPathName(TextFileLoader.GetFileName()) + m_strBombEffectName; + CEffectManager::Instance().RegisterEffect2(m_strBombEffectName.c_str(),&m_dwBombEffectID); + } + + if (!TextFileLoader.GetTokenInteger("homingflag", &temp)) + m_bIsHoming = false; + else + m_bIsHoming = temp?true:false; + + if (!TextFileLoader.GetTokenFloat("homingstarttime",&m_fHomingStartTime)) + m_fHomingStartTime = 0.0f; + + if (!TextFileLoader.GetTokenFloat("homingmaxangle",&m_fHomingMaxAngle)) + m_fHomingMaxAngle = 0.0f; + + if (!TextFileLoader.GetTokenFloat("range",&m_fRange)) + return false; + + if (!TextFileLoader.GetTokenVector3("acceleration",&m_v3Accel)) + m_v3Accel = D3DXVECTOR3(0.0f,0.0f,0.0f); + + DWORD i; + for(i=0;i::iterator it; + for(it = m_AttachDataVector.begin();it!=m_AttachDataVector.end();++it) + { + PrintfTabs(fp, 0, "Group AttachData\n"); + PrintfTabs(fp, 0, "{\n"); + PrintfTabs(fp, 1, "Type %d\n", it->iType); + PrintfTabs(fp, 1, "FlyType %d\n", it->iFlyType); + if (GetLocalFileName(strGlobalPathName.c_str(), it->strFilename.c_str(), &strLocalFileName)) + PrintfTabs(fp, 1, "AttachFile \"%s\"\n", strLocalFileName.c_str()); + else + PrintfTabs(fp, 1, "AttachFile \"%s\"\n", it->strFilename.c_str()); + //PrintfTabs(fp, 1, "AttachFile \"%s\"\n", it->strFilename); + + PrintfTabs(fp, 1, "TailFlag %d\n", it->bHasTail?1:0); + if (it->bHasTail) + { + PrintfTabs(fp, 1, "TailColor %ud\n", it->dwTailColor); + PrintfTabs(fp, 1, "TailLength %f\n", it->fTailLength); + PrintfTabs(fp, 1, "TailSize %f\n", it->fTailSize); + PrintfTabs(fp, 1, "TailShapeRect %d\n", it->bRectShape?1:0); + } + + PrintfTabs(fp, 1, "Roll %f\n",it->fRoll ); + PrintfTabs(fp, 1, "Distance %f\n",it->fDistance ); + PrintfTabs(fp, 1, "Period %f\n",it->fPeriod ); + PrintfTabs(fp, 1, "Amplitude %f\n",it->fAmplitude ); + + PrintfTabs(fp, 0, "}\n"); + } + + fclose(fp); + return true; +} \ No newline at end of file diff --git a/extension/src/port/GameLib/FlyingData.h b/extension/src/port/GameLib/FlyingData.h new file mode 100644 index 00000000..6e3c6382 --- /dev/null +++ b/extension/src/port/GameLib/FlyingData.h @@ -0,0 +1,111 @@ +#pragma once + +class CFlyingData //: public CPooledObject +{ +public: + + enum + { + FLY_ATTACH_NONE, + FLY_ATTACH_EFFECT, + FLY_ATTACH_OBJECT, // NOT IMPLEMENTED + }; + + enum + { + FLY_ATTACH_TYPE_NONE, + FLY_ATTACH_TYPE_LINE, + FLY_ATTACH_TYPE_MULTI_LINE, + FLY_ATTACH_TYPE_SINE, + FLY_ATTACH_TYPE_EXP, + }; + + struct TFlyingAttachData + { + int iType; + int iFlyType; + std::string strFilename; + + bool bHasTail; + DWORD dwTailColor; + float fTailLength; + float fTailSize; + bool bRectShape; + + float fRoll; + // nothing for LINE + // for MULTI_LINE + float fDistance; + // for SINE, EXP + float fPeriod; + float fAmplitude; + }; + + friend class CFlyingInstance; + + friend class CSceneFly; + friend class CFlyTabPage; + + CFlyingData(); + virtual ~CFlyingData(); + + void Destroy(); + + bool LoadScriptFile(const char* c_szFilename); + bool SaveScriptFile(const char* c_szFilename); + + const D3DXVECTOR3 & GetAcceleration() { return m_v3Accel; } + + void SetBombEffect(const char* szEffectName); + + DWORD AttachFlyEffect(int iType, const std::string & strFilename, float fRoll, float fArg1, float fArg2); + + TFlyingAttachData & GetAttachDataReference(int iIndex); + int GetAttachDataCount() { return m_AttachDataVector.size(); } + + void DuplicateAttach(int iIndex); + void RemoveAttach(int iIndex); + void RemoveAllAttach(); + +protected: + void __Initialize(); + + std::string m_strFilename; + + bool m_bSpreading; + bool m_bMaintainParallel; + + float m_fInitVel; + float m_fConeAngle; + float m_fRollAngle; + + D3DXVECTOR3 m_v3AngVel; + + float m_fGravity; + + float m_fBombRange; + std::string m_strBombEffectName; + DWORD m_dwBombEffectID; + + bool m_bIsHoming; + float m_fHomingMaxAngle; + float m_fHomingStartTime; + + bool m_bHitOnBackground; + bool m_bHitOnAnotherMonster; + int m_iPierceCount; + float m_fCollisionSphereRadius; + + float m_fRange; + D3DXVECTOR3 m_v3Accel; + + std::vector m_AttachDataVector; + +public: + static CFlyingData * New() { return ms_kPool.Alloc(); } + static void Delete(CFlyingData * pData) { pData->Destroy(); ms_kPool.Free(pData); } + + static void DestroySystem() { ms_kPool.Destroy(); } + + static CDynamicPool ms_kPool; +}; \ No newline at end of file diff --git a/extension/src/port/GameLib/FlyingInstance.cpp b/extension/src/port/GameLib/FlyingInstance.cpp new file mode 100644 index 00000000..10a594c3 --- /dev/null +++ b/extension/src/port/GameLib/FlyingInstance.cpp @@ -0,0 +1,598 @@ +#include "StdAfx.h" +#include "../EterLib/GrpMath.h" +#include "../EffectLib/EffectManager.h" + +#include "MapManager.h" + +#include "FlyingData.h" +#include "FlyTrace.h" +#include "FlyingInstance.h" +#include "FlyingObjectManager.h" +#include "FlyTarget.h" +#include "FlyHandler.h" + +CDynamicPool CFlyingInstance::ms_kPool; + +CFlyingInstance::CFlyingInstance() +{ + __Initialize(); +} + +CFlyingInstance::~CFlyingInstance() +{ + Destroy(); +} + +void CFlyingInstance::__Initialize() +{ + m_qAttachRotation=m_qRot=D3DXQUATERNION(0.0f, 0.0f, 0.0f, 0.0f); + m_v3Accel=m_v3LocalVelocity=m_v3Velocity=m_v3Position=D3DXVECTOR3(0.0f, 0.0f, 0.0f); + + m_pHandler=NULL; + m_pData=NULL; + m_pOwner=NULL; + + m_bAlive=false; + m_canAttack=false; + + m_dwSkillIndex = 0; + + m_iPierceCount=0; + + m_fStartTime=0.0f; + m_fRemainRange=0.0f; + + m_bTargetHitted = FALSE; + m_HittedObjectSet.clear(); +} + +void CFlyingInstance::Clear() +{ + Destroy(); +} + +void CFlyingInstance::Destroy() +{ + m_FlyTarget.Clear(); + + ClearAttachInstance(); + + __Initialize(); +} + + +void CFlyingInstance::BuildAttachInstance() +{ + for(int i=0;iGetAttachDataCount();i++) + { + CFlyingData::TFlyingAttachData & rfad = m_pData->GetAttachDataReference(i); + + switch(rfad.iType) + { + case CFlyingData::FLY_ATTACH_OBJECT: + // NOT Implemented + assert(!"FlyingInstance.cpp:BuildAttachInstance Not implemented FLY_ATTACH_OBJECT"); + break; + case CFlyingData::FLY_ATTACH_EFFECT: + { + CEffectManager & rem = CEffectManager::Instance(); + TAttachEffectInstance aei; + + DWORD dwCRC = GetCaseCRC32(rfad.strFilename.c_str(),rfad.strFilename.size()); + + aei.iAttachIndex = i; + aei.dwEffectInstanceIndex = rem.GetEmptyIndex(); + + aei.pFlyTrace = NULL; + if (rfad.bHasTail) + { + aei.pFlyTrace = CFlyTrace::New(); + aei.pFlyTrace->Create(rfad); + } + rem.CreateEffectInstance(aei.dwEffectInstanceIndex,dwCRC); + + m_vecAttachEffectInstance.push_back(aei); + } + break; + } + } +} + +void CFlyingInstance::Create(CFlyingData* pData, const D3DXVECTOR3& c_rv3StartPos, const CFlyTarget & c_rkTarget, bool canAttack) +{ + m_FlyTarget = c_rkTarget; + m_canAttack = canAttack; + + __SetDataPointer(pData, c_rv3StartPos); + __SetTargetDirection(m_FlyTarget); +} + +void CFlyingInstance::__SetTargetDirection(const CFlyTarget& c_rkTarget) +{ + D3DXVECTOR3 v3TargetPos=c_rkTarget.GetFlyTargetPosition(); + + // 임시 코드 + if (m_pData->m_bMaintainParallel) + { + v3TargetPos.z += 50.0f; + } + + D3DXVECTOR3 v3TargetDir=v3TargetPos-m_v3Position; + + D3DXVec3Normalize(&v3TargetDir, &v3TargetDir); + __SetTargetNormalizedDirection(v3TargetDir); +} + +void CFlyingInstance::__SetTargetNormalizedDirection(const D3DXVECTOR3 & v3NomalizedDirection) +{ + D3DXQUATERNION q = SafeRotationNormalizedArc(D3DXVECTOR3(0.0f,-1.0f,0.0f),v3NomalizedDirection); + D3DXQuaternionMultiply(&m_qRot,&m_qRot,&q); + Vec3TransformQuaternion(&m_v3Velocity,&m_v3LocalVelocity,&m_qRot); + Vec3TransformQuaternion(&m_v3Accel, &m_pData->m_v3Accel, &m_qRot); +} + +// 2004. 3. 26. myevan. 기능을 몰라 일단 주석 처리. 적절한 네이밍이 필요. 게임에서 사용하지 않는다면 툴에서 툴 전용으로 상속받아 만들도록 하자 +void CFlyingInstance::SetFlyTarget(const CFlyTarget & cr_Target) +{ + //m_pFlyTarget = pTarget; + m_FlyTarget = cr_Target; + //SetStartTargetPosition(m_FlyTarget.GetFlyTargetPosition()); + + __SetTargetDirection(m_FlyTarget); +} + +void CFlyingInstance::AdjustDirectionForHoming(const D3DXVECTOR3 & v3TargetPosition) +{ + D3DXVECTOR3 vTargetDir(v3TargetPosition); + vTargetDir -= m_v3Position; + D3DXVec3Normalize(&vTargetDir,&vTargetDir); + D3DXVECTOR3 vVel; + D3DXVec3Normalize(&vVel, &m_v3Velocity); + + const auto vv1 = (vVel - vTargetDir); + if (D3DXVec3LengthSq(&vv1) < 0.001f) + return; + + D3DXQUATERNION q = SafeRotationNormalizedArc(vVel,vTargetDir); + + if (m_pData->m_fHomingMaxAngle > 180) + { + Vec3TransformQuaternionSafe(&m_v3Velocity, &m_v3Velocity, &q); + Vec3TransformQuaternionSafe(&m_v3Accel, &m_v3Accel, &q); + D3DXQuaternionMultiply(&m_qRot, &q, &m_qRot); + return; + } + + float c = cosf(D3DXToRadian(m_pData->m_fHomingMaxAngle)); + float s = sinf(D3DXToRadian(m_pData->m_fHomingMaxAngle)); + + if (q.w <= -1.0f + 0.0001f) + { + q.x = 0; + q.y = 0; + q.z = s; + q.w = c; + } + else if (q.w <= c && q.w <= 1.0f - 0.0001f) + { + float factor = s / sqrtf(1.0f - q.w * q.w); + q.x *= factor; + q.y *= factor; + q.z *= factor; + q.w = c; + } + /*else + { + }*/ + Vec3TransformQuaternionSafe(&m_v3Velocity, &m_v3Velocity, &q); + Vec3TransformQuaternionSafe(&m_v3Accel, &m_v3Accel, &q); + D3DXQuaternionMultiply(&m_qRot, &m_qRot, &q); +} + +void CFlyingInstance::UpdateAttachInstance() +{ + // Update Attach Rotation + D3DXQUATERNION q; + D3DXQuaternionRotationYawPitchRoll(&q, + D3DXToRadian(m_pData->m_v3AngVel.y)*CTimer::Instance().GetElapsedSecond(), + D3DXToRadian(m_pData->m_v3AngVel.x)*CTimer::Instance().GetElapsedSecond(), + D3DXToRadian(m_pData->m_v3AngVel.z)*CTimer::Instance().GetElapsedSecond()); + + D3DXQuaternionMultiply(&m_qAttachRotation, &m_qAttachRotation, &q); + D3DXQuaternionMultiply(&q, &m_qAttachRotation, &m_qRot); + + CEffectManager & rem = CEffectManager::Instance(); + TAttachEffectInstanceVector::iterator it; + for(it = m_vecAttachEffectInstance.begin();it!=m_vecAttachEffectInstance.end();++it) + { + CFlyingData::TFlyingAttachData & rfad = m_pData->GetAttachDataReference(it->iAttachIndex); + assert(rfad.iType == CFlyingData::FLY_ATTACH_EFFECT); + rem.SelectEffectInstance(it->dwEffectInstanceIndex); + D3DXMATRIX m; + switch(rfad.iFlyType) + { + case CFlyingData::FLY_ATTACH_TYPE_LINE: + D3DXMatrixRotationQuaternion(&m,&m_qRot); + //D3DXMatrixRotationQuaternion(&m,&q); + m._41=m_v3Position.x; + m._42=m_v3Position.y; + m._43=m_v3Position.z; + break; + case CFlyingData::FLY_ATTACH_TYPE_MULTI_LINE: + { + D3DXVECTOR3 p( + -sinf(D3DXToRadian(rfad.fRoll))*rfad.fDistance, + 0.0f, + -cosf(D3DXToRadian(rfad.fRoll))*rfad.fDistance); + //Vec3TransformQuaternionSafe(&p,&p,&m_qRot); + Vec3TransformQuaternionSafe(&p,&p,&q); + p+=m_v3Position; + //D3DXMatrixRotationQuaternion(&m,&m_qRot); + D3DXMatrixRotationQuaternion(&m,&q); + m._41=p.x; + m._42=p.y; + m._43=p.z; + } + break; + case CFlyingData::FLY_ATTACH_TYPE_SINE: + { + //Tracenf("%f",CTimer::Instance().GetCurrentSecond()); + float angle = (CTimer::Instance().GetCurrentSecond() - m_fStartTime)*2*3.1415926535897931f/rfad.fPeriod; + D3DXVECTOR3 p( + -sinf(D3DXToRadian(rfad.fRoll))*rfad.fAmplitude*sinf(angle), + 0.0f, + -cosf(D3DXToRadian(rfad.fRoll))*rfad.fAmplitude*sinf(angle)); + Vec3TransformQuaternionSafe(&p,&p,&q); + //Vec3TransformQuaternionSafe(&p,&p,&m_qRot); + p+=m_v3Position; + D3DXMatrixRotationQuaternion(&m,&q); + //D3DXMatrixRotationQuaternion(&m,&m_qRot); + m._41=p.x; + m._42=p.y; + m._43=p.z; + //assert(!"NOT IMPLEMENTED"); + } + break; + case CFlyingData::FLY_ATTACH_TYPE_EXP: + { + float dt = CTimer::Instance().GetCurrentSecond() - m_fStartTime; + float angle = dt/rfad.fPeriod; + D3DXVECTOR3 p( + -sinf(D3DXToRadian(rfad.fRoll))*rfad.fAmplitude*exp(-angle)*angle, + 0.0f, + -cosf(D3DXToRadian(rfad.fRoll))*rfad.fAmplitude*exp(-angle)*angle); + //Vec3TransformQuaternionSafe(&p,&p,&m_qRot); + Vec3TransformQuaternionSafe(&p,&p,&q); + p+=m_v3Position; + D3DXMatrixRotationQuaternion(&m,&q); + //D3DXMatrixRotationQuaternion(&m,&m_qRot); + m._41=p.x; + m._42=p.y; + m._43=p.z; + //assert(!"NOT IMPLEMENTED"); + } + break; + } + rem.SetEffectInstanceGlobalMatrix(m); + if (it->pFlyTrace) + it->pFlyTrace->UpdateNewPosition(D3DXVECTOR3(m._41,m._42,m._43)); + } +} +struct FCheckBackgroundDuringFlying { + CDynamicSphereInstance s; + bool bHit; + FCheckBackgroundDuringFlying(const D3DXVECTOR3 & v1, const D3DXVECTOR3 & v2) + { + s.fRadius = 1.0f; + s.v3LastPosition = v1; + s.v3Position = v2; + bHit = false; + } + void operator () (CGraphicObjectInstance * p) + { + if (!p) + return; + + if (!bHit && p->GetType() != ACTOR_OBJECT) + { + if (p->CollisionDynamicSphere(s)) + { + bHit = true; + } + } + } + bool IsHitted() + { + return bHit; + } +}; + +struct FCheckAnotherMonsterDuringFlying { + CDynamicSphereInstance s; + CGraphicObjectInstance * pInst; + const IActorInstance * pOwner; + FCheckAnotherMonsterDuringFlying(const IActorInstance * pOwner, const D3DXVECTOR3 & v1, const D3DXVECTOR3 & v2) + : pOwner(pOwner) + { + s.fRadius = 10.0f; + s.v3LastPosition = v1; + s.v3Position = v2; + pInst = 0; + } + void operator () (CGraphicObjectInstance * p) + { + if (!p) + return; + + if (!pInst && p->GetType() == ACTOR_OBJECT) + { + IActorInstance * pa = (IActorInstance*) p; + if (pa != pOwner && pa->TestCollisionWithDynamicSphere(s)) + { + pInst = p; + } + } + } + bool IsHitted() + { + return pInst!=0; + } + CGraphicObjectInstance * GetHittedObject() + { + return pInst; + } +}; + + +bool CFlyingInstance::Update() +{ + if (!m_bAlive) + return false; + + if (m_pData->m_bIsHoming && + m_pData->m_fHomingStartTime + m_fStartTime < CTimer::Instance().GetCurrentSecond()) + { + if (m_FlyTarget.IsObject()) + AdjustDirectionForHoming(m_FlyTarget.GetFlyTargetPosition()); + } + + D3DXVECTOR3 v3LastPosition = m_v3Position; + + m_v3Velocity += m_v3Accel*CTimer::Instance().GetElapsedSecond(); + m_v3Velocity.z+=m_pData->m_fGravity * CTimer::Instance().GetElapsedSecond(); + D3DXVECTOR3 v3Movement = m_v3Velocity * CTimer::Instance().GetElapsedSecond(); + float _fMoveDistance = D3DXVec3Length(&v3Movement); + float fCollisionSphereRadius = max(_fMoveDistance*2, m_pData->m_fCollisionSphereRadius); + m_fRemainRange -= _fMoveDistance; + m_v3Position += v3Movement; + + UpdateAttachInstance(); + + if (m_fRemainRange<0) + { + if (m_pHandler) + m_pHandler->OnExplodingOutOfRange(); + + __Explode(false); + return false; + } + + if (m_FlyTarget.IsObject()) + { + if (!m_bTargetHitted) + { + if (square_distance_between_linesegment_and_point(m_v3Position,v3LastPosition,m_FlyTarget.GetFlyTargetPosition())m_fBombRange*m_pData->m_fBombRange) + { + m_bTargetHitted = TRUE; + + if (m_canAttack) + { + IFlyTargetableObject* pVictim=m_FlyTarget.GetFlyTarget(); + if (pVictim) + { + pVictim->OnShootDamage(); + } + } + + if (m_pHandler) + { + m_pHandler->OnExplodingAtTarget(m_dwSkillIndex); + } + + if (m_iPierceCount) + { + m_iPierceCount--; + __Bomb(); + } + else + { + __Explode(); + return false; + } + + return true; + } + } + } + else if (m_FlyTarget.IsPosition()) + { + if (square_distance_between_linesegment_and_point(m_v3Position,v3LastPosition,m_FlyTarget.GetFlyTargetPosition())m_fBombRange*m_pData->m_fBombRange) + { + __Explode(); + return false; + } + } + + Vector3d vecStart, vecDir; + vecStart.Set(v3LastPosition.x,v3LastPosition.y,v3LastPosition.z); + vecDir.Set(v3Movement.x,v3Movement.y,v3Movement.z); + + CCullingManager & rkCullingMgr = CCullingManager::Instance(); + + if (m_pData->m_bHitOnAnotherMonster) + { + FCheckAnotherMonsterDuringFlying kCheckAnotherMonsterDuringFlying(m_pOwner, v3LastPosition,m_v3Position); + rkCullingMgr.ForInRange(vecStart,fCollisionSphereRadius, &kCheckAnotherMonsterDuringFlying); + if (kCheckAnotherMonsterDuringFlying.IsHitted()) + { + IActorInstance * pHittedInstance = (IActorInstance*)kCheckAnotherMonsterDuringFlying.GetHittedObject(); + if (m_HittedObjectSet.end() == m_HittedObjectSet.find(pHittedInstance)) + { + m_HittedObjectSet.insert(pHittedInstance); + + if (m_pHandler) + { + m_pHandler->OnExplodingAtAnotherTarget(m_dwSkillIndex, pHittedInstance->GetVirtualID()); + } + + if (m_iPierceCount) + { + m_iPierceCount--; + __Bomb(); + } + else + { + __Explode(); + return false; + } + + return true; + } + } + } + + if (m_pData->m_bHitOnBackground) + { + // 지형 충돌 + + if (CFlyingManager::Instance().GetMapManagerPtr()) + { + float fGroundHeight = CFlyingManager::Instance().GetMapManagerPtr()->GetTerrainHeight(m_v3Position.x,-m_v3Position.y); + if (fGroundHeight>m_v3Position.z) + { + if (m_pHandler) + m_pHandler->OnExplodingAtBackground(); + + __Explode(); + return false; + } + } + + // 건물+나무 충돌 + + FCheckBackgroundDuringFlying kCheckBackgroundDuringFlying(v3LastPosition,m_v3Position); + rkCullingMgr.ForInRange(vecStart,fCollisionSphereRadius, &kCheckBackgroundDuringFlying); + + if (kCheckBackgroundDuringFlying.IsHitted()) + { + if (m_pHandler) + m_pHandler->OnExplodingAtBackground(); + + __Explode(); + return false; + } + } + + return true; +} + +void CFlyingInstance::ClearAttachInstance() +{ + CEffectManager & rkEftMgr = CEffectManager::Instance(); + + TAttachEffectInstanceVector::iterator i; + for(i = m_vecAttachEffectInstance.begin();i!=m_vecAttachEffectInstance.end();++i) + { + rkEftMgr.DestroyEffectInstance(i->dwEffectInstanceIndex); + + if (i->pFlyTrace) + CFlyTrace::Delete(i->pFlyTrace); + + i->iAttachIndex=0; + i->dwEffectInstanceIndex=0; + i->pFlyTrace=NULL; + } + m_vecAttachEffectInstance.clear(); +} + +void CFlyingInstance::__Explode(bool bBomb) +{ + if (!m_bAlive) + return; + + m_bAlive = false; + + if (bBomb) + __Bomb(); +} + +void CFlyingInstance::__Bomb() +{ + CEffectManager & rkEftMgr = CEffectManager::Instance(); + if (!m_pData->m_dwBombEffectID) + return; + + DWORD dwEmptyIndex = rkEftMgr.GetEmptyIndex(); + rkEftMgr.CreateEffectInstance(dwEmptyIndex,m_pData->m_dwBombEffectID); + + D3DXMATRIX m; +// D3DXMatrixRotationQuaternion(&m,&m_qRot); + D3DXMatrixIdentity(&m); + m._41 = m_v3Position.x; + m._42 = m_v3Position.y; + m._43 = m_v3Position.z; + rkEftMgr.SelectEffectInstance(dwEmptyIndex); + rkEftMgr.SetEffectInstanceGlobalMatrix(m); +} + +void CFlyingInstance::Render() +{ + if (!m_bAlive) + return; + RenderAttachInstance(); +} + +void CFlyingInstance::RenderAttachInstance() +{ + TAttachEffectInstanceVector::iterator it; + for(it = m_vecAttachEffectInstance.begin();it!=m_vecAttachEffectInstance.end();++it) + { + if (it->pFlyTrace) + it->pFlyTrace->Render(); + } +} + +void CFlyingInstance::SetDataPointer(CFlyingData * pData, const D3DXVECTOR3 & v3StartPosition) +{ + __SetDataPointer(pData, v3StartPosition); +} + +void CFlyingInstance::__SetDataPointer(CFlyingData * pData, const D3DXVECTOR3 & v3StartPosition) +{ + m_pData = pData; + m_qRot = D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f), + m_v3Position = (v3StartPosition); + m_bAlive = (true); + + m_fStartTime = CTimer::Instance().GetCurrentSecond(); + + D3DXQuaternionRotationYawPitchRoll(&m_qRot,D3DXToRadian(pData->m_fRollAngle-90.0f),0.0f,D3DXToRadian(pData->m_fConeAngle)); + if (pData->m_bSpreading) + { + D3DXQUATERNION q1, q2; + const auto vv1 = D3DXVECTOR3(0.0f, 0.0f, 1.0f), vv2 = D3DXVECTOR3(0.0f, -1.0f, 0.0f); + D3DXQuaternionRotationAxis(&q2, &vv1,(frandom(-3.141592f/3,+3.141592f/3)+frandom(-3.141592f/3,+3.141592f/3))/2); + D3DXQuaternionRotationAxis(&q1, &vv2, frandom(0,2*3.1415926535897931f)); + D3DXQuaternionMultiply(&q1,&q2,&q1); + D3DXQuaternionMultiply(&m_qRot,&q1,&m_qRot); + } + m_v3Velocity = m_v3LocalVelocity = D3DXVECTOR3(0.0f,-pData->m_fInitVel,0.0f); + m_v3Accel = pData->m_v3Accel; + m_fRemainRange = pData->m_fRange; + m_qAttachRotation = D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f); + + BuildAttachInstance(); + UpdateAttachInstance(); + + m_iPierceCount = pData->m_iPierceCount; +} diff --git a/extension/src/port/GameLib/FlyingObjectManager.cpp b/extension/src/port/GameLib/FlyingObjectManager.cpp new file mode 100644 index 00000000..7c5e0a2a --- /dev/null +++ b/extension/src/port/GameLib/FlyingObjectManager.cpp @@ -0,0 +1,214 @@ +#include "StdAfx.h" + +#include "FlyingData.h" +#include "FlyingInstance.h" +#include "FlyingObjectManager.h" + +#include "ActorInstance.h" + +CFlyingManager::CFlyingManager() +{ + m_pMapManager = 0; +} + +CFlyingManager::~CFlyingManager() +{ + Destroy(); +} + +void CFlyingManager::__DestroyFlyingInstanceList() +{ + TFlyingInstanceList::iterator i; + for(i = m_kLst_pkFlyInst.begin(); i!=m_kLst_pkFlyInst.end(); ++i) + { + CFlyingInstance* pkFlyInst=*i; + CFlyingInstance::Delete(pkFlyInst); + } + m_kLst_pkFlyInst.clear(); +} + +void CFlyingManager::__DestroyFlyingDataMap() +{ + TFlyingDataMap::iterator i; + for(i = m_kMap_pkFlyData.begin(); i != m_kMap_pkFlyData.end(); ++i) + { + CFlyingData* pkFlyData=i->second; + CFlyingData::Delete(pkFlyData); + } + m_kMap_pkFlyData.clear(); +} + + +void CFlyingManager::DeleteAllInstances() +{ + __DestroyFlyingInstanceList(); +} + +void CFlyingManager::Destroy() +{ + __DestroyFlyingInstanceList(); + __DestroyFlyingDataMap(); + + m_pMapManager = 0; +} + +bool CFlyingManager::RegisterFlyingData(const char* c_szFilename) +{ + std::string s; + StringPath(c_szFilename,s); + DWORD dwRetCRC = GetCaseCRC32(s.c_str(),s.size()); + + if (m_kMap_pkFlyData.find(dwRetCRC) != m_kMap_pkFlyData.end()) + { + return false; + } + + CFlyingData * pFlyingData = CFlyingData::New(); + if (!pFlyingData->LoadScriptFile(c_szFilename)) + { + Tracenf("CEffectManager::RegisterFlyingData %s - Failed to load flying data file", c_szFilename); + CFlyingData::Delete(pFlyingData); + return false; + } + + m_kMap_pkFlyData.insert(std::make_pair(dwRetCRC,pFlyingData)); + return true; +} + +bool CFlyingManager::RegisterFlyingData(const char* c_szFilename, DWORD & r_dwRetCRC) +{ + std::string s; + StringPath(c_szFilename,s); + r_dwRetCRC = GetCaseCRC32(s.c_str(),s.size()); + + if (m_kMap_pkFlyData.find(r_dwRetCRC) != m_kMap_pkFlyData.end()) + { + TraceError("CFlyingManager::RegisterFlyingData - Already exists flying data named [%s]", c_szFilename); + return false; + } + + CFlyingData * pFlyingData = CFlyingData::New(); + if (!pFlyingData->LoadScriptFile(c_szFilename)) + { + TraceError("CEffectManager::RegisterFlyingData %s - Failed to load flying data file", c_szFilename); + CFlyingData::Delete(pFlyingData); + return false; + + } + + m_kMap_pkFlyData.insert(std::make_pair(r_dwRetCRC,pFlyingData)); + return true; +} + +CFlyingInstance * CFlyingManager::CreateFlyingInstanceFlyTarget(const DWORD dwID, + const D3DXVECTOR3 & v3StartPosition, + const CFlyTarget & cr_FlyTarget, + bool canAttack) +{ + if (m_kMap_pkFlyData.find(dwID) == m_kMap_pkFlyData.end()) + { + //TraceError("CFlyingManager::CreateFlyingInstanceFlyTarget - No data with CRC [%d]", dwID); + return NULL; + } + + CFlyingInstance * pFlyingInstance = CFlyingInstance::New(); + pFlyingInstance->Create(m_kMap_pkFlyData[dwID], v3StartPosition, cr_FlyTarget, canAttack); + + m_kLst_pkFlyInst.push_back(pFlyingInstance); + + pFlyingInstance->ID = m_IDCounter++; + return pFlyingInstance; +} + +void CFlyingManager::Update() +{ + TFlyingInstanceList::iterator i=m_kLst_pkFlyInst.begin(); + + while (i!=m_kLst_pkFlyInst.end()) + { + CFlyingInstance* pkFlyInst=*i; + if (!pkFlyInst->Update()) + { + CFlyingInstance::Delete(pkFlyInst); + i=m_kLst_pkFlyInst.erase(i); + } + else + { + ++i; + } + } +} + +void CFlyingManager::Render() +{ + std::for_each(m_kLst_pkFlyInst.begin(), m_kLst_pkFlyInst.end(), std::mem_fn(&CFlyingInstance::Render)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +bool CFlyingManager::RegisterIndexedFlyData(DWORD dwIndex, BYTE byType, const char * c_szFileName) +{ + DWORD dwCRC; + if (!RegisterFlyingData(c_szFileName, dwCRC)) + { + TraceError("CFlyingManager::RegisterIndexFlyData(dwIndex=%d, c_szFileName=%s) - Failed to load flying data file", dwIndex, c_szFileName); + return false; + } + + TIndexFlyData IndexFlyData; + IndexFlyData.byType = byType; + IndexFlyData.dwCRC = dwCRC; + m_kMap_dwIndexFlyData.insert(std::make_pair(dwIndex, IndexFlyData)); + + return true; +} + +void CFlyingManager::CreateIndexedFly(DWORD dwIndex, CActorInstance * pStartActor, CActorInstance * pEndActor) +{ + if (m_kMap_dwIndexFlyData.end() == m_kMap_dwIndexFlyData.find(dwIndex)) + { + TraceError("CFlyingManager::CreateIndexedFly(dwIndex=%d) - Not registered index", dwIndex); + return; + } + + TPixelPosition posStart; + pStartActor->GetPixelPosition(&posStart); + + TIndexFlyData & rIndexFlyData = m_kMap_dwIndexFlyData[dwIndex]; + switch (rIndexFlyData.byType) + { + case INDEX_FLY_TYPE_NORMAL: + { + CreateFlyingInstanceFlyTarget(rIndexFlyData.dwCRC, + D3DXVECTOR3(posStart.x, posStart.y, posStart.z), + pEndActor, + false); + break; + } + case INDEX_FLY_TYPE_FIRE_CRACKER: + { + float fRot = fmod(pStartActor->GetRotation() - 90.0f + 360.0f, 360.0f) + frandom(-30.0f, 30.0f); + + float fDistance = frandom(2000.0f, 5000.0f); + float fxRand = fDistance * cosf(D3DXToRadian(fRot)); + float fyRand = fDistance * sinf(D3DXToRadian(fRot)); + float fzRand = frandom(1000.0f, 2500.0f); + + CreateFlyingInstanceFlyTarget(rIndexFlyData.dwCRC, + D3DXVECTOR3(posStart.x, posStart.y, posStart.z+200), + D3DXVECTOR3(posStart.x + fxRand, posStart.y + fyRand, posStart.z + fzRand), + false); + break; + } + case INDEX_FLY_TYPE_AUTO_FIRE: + { + CreateFlyingInstanceFlyTarget(rIndexFlyData.dwCRC, + D3DXVECTOR3(posStart.x, posStart.y, posStart.z+100.0f), + pEndActor, + false); + break; + } + } +} diff --git a/extension/src/port/UserInterface/PythonEffectModule.cpp b/extension/src/port/UserInterface/PythonEffectModule.cpp new file mode 100644 index 00000000..9cab6ea2 --- /dev/null +++ b/extension/src/port/UserInterface/PythonEffectModule.cpp @@ -0,0 +1,150 @@ +#include "StdAfx.h" +#include "../EffectLib/EffectManager.h" +#include "PythonCharacterManager.h" + +PyObject * effectRegisterEffect(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + CEffectManager::Instance().RegisterEffect(szFileName); + return Py_BuildNone(); +} + +PyObject * effectUpdate(PyObject * poSelf, PyObject * poArgs) +{ + CEffectManager::Instance().Update(); + return Py_BuildNone(); +} + +PyObject * effectRender(PyObject * poSelf, PyObject * poArgs) +{ + CEffectManager::Instance().Render(); + return Py_BuildNone(); +} + +PyObject * effectCreateEffect(PyObject * poSelf, PyObject * poArgs) +{ + char * szEffectName; + if (!PyTuple_GetString(poArgs, 0, &szEffectName)) + return Py_BuildException(); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + TPixelPosition PixelPosition; + pInstance->NEW_GetPixelPosition(&PixelPosition); + int iIndex = CEffectManager::Instance().CreateEffect(szEffectName, PixelPosition, D3DXVECTOR3(0.0f, 0.0f, 0.0f)); + + return Py_BuildValue("i", iIndex); +} + +PyObject * effectDeleteEffect(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + CEffectManager::Instance().DestroyEffectInstance(iIndex); + + return Py_BuildNone(); +} + +PyObject * effectSetPosition(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + float fx; + if (!PyTuple_GetFloat(poArgs, 1, &fx)) + return Py_BuildException(); + float fy; + if (!PyTuple_GetFloat(poArgs, 2, &fy)) + return Py_BuildException(); + float fz; + if (!PyTuple_GetFloat(poArgs, 3, &fz)) + return Py_BuildException(); + + CEffectManager::Instance().SelectEffectInstance(iIndex); + CEffectManager::Instance().SetEffectInstancePosition(D3DXVECTOR3(fx, fy, fz)); + + return Py_BuildNone(); +} + +PyObject * effectRegisterIndexedFlyData(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + int iType; + if (!PyTuple_GetInteger(poArgs, 1, &iType)) + return Py_BuildException(); + char * szFlyDataName; + if (!PyTuple_GetString(poArgs, 2, &szFlyDataName)) + return Py_BuildException(); + + CFlyingManager::Instance().RegisterIndexedFlyData(iIndex, iType, szFlyDataName); + + return Py_BuildNone(); +} + +void initeffect() +{ + static PyMethodDef s_methods[] = + { + { "RegisterEffect", effectRegisterEffect, METH_VARARGS }, + { "CreateEffect", effectCreateEffect, METH_VARARGS }, + { "DeleteEffect", effectDeleteEffect, METH_VARARGS }, + { "SetPosition", effectSetPosition, METH_VARARGS }, + + { "RegisterIndexedFlyData", effectRegisterIndexedFlyData, METH_VARARGS }, + + { "Update", effectUpdate, METH_VARARGS }, + { "Render", effectRender, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("effect", s_methods); + PyModule_AddIntConstant(poModule, "INDEX_FLY_TYPE_NORMAL", CFlyingManager::INDEX_FLY_TYPE_NORMAL); + PyModule_AddIntConstant(poModule, "INDEX_FLY_TYPE_FIRE_CRACKER", CFlyingManager::INDEX_FLY_TYPE_FIRE_CRACKER); + PyModule_AddIntConstant(poModule, "INDEX_FLY_TYPE_AUTO_FIRE", CFlyingManager::INDEX_FLY_TYPE_AUTO_FIRE); + + enum + { + FLY_NONE, + FLY_EXP, + FLY_HP_MEDIUM, + FLY_HP_BIG, + FLY_SP_SMALL, + FLY_SP_MEDIUM, + FLY_SP_BIG, + FLY_FIREWORK1, + FLY_FIREWORK2, + FLY_FIREWORK3, + FLY_FIREWORK4, + FLY_FIREWORK5, + FLY_FIREWORK6, + FLY_FIREWORK_XMAS, + FLY_CHAIN_LIGHTNING, + FLY_HP_SMALL, + FLY_SKILL_MUYEONG, + }; + + PyModule_AddIntConstant(poModule, "FLY_NONE", FLY_NONE); + PyModule_AddIntConstant(poModule, "FLY_EXP", FLY_EXP); + PyModule_AddIntConstant(poModule, "FLY_HP_MEDIUM", FLY_HP_MEDIUM); + PyModule_AddIntConstant(poModule, "FLY_HP_BIG", FLY_HP_BIG); + PyModule_AddIntConstant(poModule, "FLY_SP_SMALL", FLY_SP_SMALL); + PyModule_AddIntConstant(poModule, "FLY_SP_MEDIUM", FLY_SP_MEDIUM); + PyModule_AddIntConstant(poModule, "FLY_SP_BIG", FLY_SP_BIG); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK1", FLY_FIREWORK1); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK2", FLY_FIREWORK2); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK3", FLY_FIREWORK3); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK4", FLY_FIREWORK4); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK5", FLY_FIREWORK5); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK6", FLY_FIREWORK6); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK_XMAS", FLY_FIREWORK_XMAS); + PyModule_AddIntConstant(poModule, "FLY_CHAIN_LIGHTNING", FLY_CHAIN_LIGHTNING); + PyModule_AddIntConstant(poModule, "FLY_HP_SMALL", FLY_HP_SMALL); + PyModule_AddIntConstant(poModule, "FLY_SKILL_MUYEONG", FLY_SKILL_MUYEONG); +} diff --git a/extension/src/port/UserInterface/PythonFlyModule.cpp b/extension/src/port/UserInterface/PythonFlyModule.cpp new file mode 100644 index 00000000..f927acb8 --- /dev/null +++ b/extension/src/port/UserInterface/PythonFlyModule.cpp @@ -0,0 +1,26 @@ +#include "StdAfx.h" +#include "../GameLib/FlyingObjectManager.h" +PyObject * flyUpdate(PyObject * poSelf, PyObject * poArgs) +{ + CFlyingManager::Instance().Update(); + return Py_BuildNone(); +} + +PyObject * flyRender(PyObject * poSelf, PyObject * poArgs) +{ + CFlyingManager::Instance().Render(); + return Py_BuildNone(); +} + +void initfly() +{ + static PyMethodDef s_methods[] = + { + { "Update", flyUpdate, METH_VARARGS }, + { "Render", flyRender, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + Py_InitModule("fly", s_methods); +} \ No newline at end of file diff --git a/extension/src/port/UserInterface/StdAfx.h b/extension/src/port/UserInterface/StdAfx.h index 0cc49975..50d5cb0b 100644 --- a/extension/src/port/UserInterface/StdAfx.h +++ b/extension/src/port/UserInterface/StdAfx.h @@ -49,3 +49,5 @@ void initchrmgr(); void initPlayer(); void initChat(); void initnet(); +void initeffect(); +void initfly(); diff --git a/extension/tests/port_login_flow_test.cpp b/extension/tests/port_login_flow_test.cpp index 7afbdceb..2a1bb307 100644 --- a/extension/tests/port_login_flow_test.cpp +++ b/extension/tests/port_login_flow_test.cpp @@ -45,6 +45,8 @@ #include "GameLib/RaceManager.h" #include "GameLib/RaceData.h" #include "GameLib/RaceMotionData.h" +#include "GameLib/FlyingData.h" +#include "GameLib/FlyingObjectManager.h" #include "UserInterface/StdAfx.h" #include "UserInterface/PythonCharacterManager.h" #include "UserInterface/InstanceBase.h" @@ -433,6 +435,16 @@ int main(int argc, char** argv) CHECK(blocked > 0); } + // playersettingmodule.py registered the indexed fly data (effect.RegisterIndexedFlyData → CFlyingManager → + // CFlyingData::LoadScriptFile): the .msf parses, and registering the name again finds it already present. + { + const char* msf = "d:/ymir work/effect/etc/gathering/ga_piece_yellow_small2.msf"; + CFlyingData* data = CFlyingData::New(); + CHECK(data->LoadScriptFile(msf)); + CFlyingData::Delete(data); + CHECK(!CFlyingManager::Instance().RegisterFlyingData(msf)); + } + // 8. (批次 2V3) Click-to-move: a left click on the ground below the actor reaches game.GameWindow's // OnMouseLeftButtonDown → player.SetMouseState(MBT_LEFT, MBS_PRESS); CPythonPlayer picks the ground // through the cursor ray (CScreen::SetCursorPosition → CPythonBackground::GetPickingPoint) and the