port: FlyingData/Instance/ObjectManager/FlyTrace + effect/fly modules (batch 2 P1)

Verbatim copies of the 40250 flying-object units and the effect/fly
Python modules replace the pending CFlyingManager stand-in and the two
module stubs; initeffect/initfly run after initnet as in 40250 and the
flying manager gets the background as its map manager.
CMapManager::GetTerrainHeight is added over the native height tiles.
login_flow checks playersettingmodule registered the indexed fly data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-24 00:12:19 +09:00
co-authored by Claude Opus 5.5
parent 05de621199
commit 9dcf34dffc
25 changed files with 2312 additions and 182 deletions
+1
View File
@@ -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-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-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-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"]}
@@ -5,40 +5,76 @@
"contracts": [], "contracts": [],
"functions": { "functions": {
"CActorInstance::GetVirtualID": { "CActorInstance::GetVirtualID": {
"status": "TODO" "status": "PORTED",
"impl": [
"extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::GetVirtualID"
]
}, },
"CActorInstance::SetVirtualID": { "CActorInstance::SetVirtualID": {
"status": "TODO" "status": "PORTED",
"impl": [
"extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::SetVirtualID"
]
}, },
"CActorInstance::UpdateAttribute": { "CActorInstance::UpdateAttribute": {
"status": "TODO" "status": "PORTED",
"impl": [
"extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::UpdateAttribute"
]
}, },
"CActorInstance::__CreateAttributeInstance": { "CActorInstance::__CreateAttributeInstance": {
"status": "TODO" "status": "PORTED",
"impl": [
"extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::__CreateAttributeInstance"
]
}, },
"CActorInstance::GetRace": { "CActorInstance::GetRace": {
"status": "TODO" "status": "PORTED",
"impl": [
"extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::GetRace"
]
}, },
"CActorInstance::SetRace": { "CActorInstance::SetRace": {
"status": "TODO" "status": "PORTED",
"impl": [
"extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::SetRace"
]
}, },
"CActorInstance::SetHair": { "CActorInstance::SetHair": {
"status": "TODO" "status": "PORTED",
"impl": [
"extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::SetHair"
]
}, },
"CActorInstance::SetShape": { "CActorInstance::SetShape": {
"status": "TODO" "status": "PORTED",
"impl": [
"extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::SetShape"
]
}, },
"CActorInstance::ChangeMaterial": { "CActorInstance::ChangeMaterial": {
"status": "TODO" "status": "PORTED",
"impl": [
"extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::ChangeMaterial"
]
}, },
"CActorInstance::GetPartItemID": { "CActorInstance::GetPartItemID": {
"status": "TODO" "status": "PORTED",
"impl": [
"extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::GetPartItemID"
]
}, },
"CActorInstance::SetSpecularInfo": { "CActorInstance::SetSpecularInfo": {
"status": "TODO" "status": "PORTED",
"impl": [
"extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::SetSpecularInfo"
]
}, },
"CActorInstance::SetSpecularInfoForce": { "CActorInstance::SetSpecularInfoForce": {
"status": "TODO" "status": "PORTED",
"impl": [
"extension/src/port/GameLib/ActorInstanceData.cpp:CActorInstance::SetSpecularInfoForce"
]
} }
} }
} }
+74
View File
@@ -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"
]
}
}
}
@@ -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"
]
}
}
}
@@ -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"
]
}
}
}
@@ -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"
]
}
}
}
+6 -1
View File
@@ -104,7 +104,12 @@
"test": "project/python_game_render_test.gd" "test": "project/python_game_render_test.gd"
}, },
"CMapManager::GetTerrainHeight": { "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": { "CMapManager::GetWaterHeight": {
"status": "TODO" "status": "TODO"
@@ -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"
]
}
}
}
@@ -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"
]
}
}
}
+1 -1
View File
@@ -431,7 +431,7 @@ extension/third_party/cpython-2.7.18/ # 静态库(2P 批次
改变位置/朝向、发送与 40250 相同的移动封包,并在离线边界测试和真服 smoke 中通过。接通时删除对应 legacy 玩法逻辑。 改变位置/朝向、发送与 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-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` 读包内 `<map>/<xxxyyy>/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 之后。 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` 读包内 `<map>/<xxxyyy>/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 宿主。 每个切片都必须同时跑 legacy/port 双路回归;只有 2V3 稳定并把默认路由切到 `port` 后,才能删除总开关和剩余 legacy 宿主。
@@ -73,54 +73,6 @@ void AddStubConstants_background(PyObject* poModule)
PyModule_AddIntConstant(poModule, "TEXTURE_SORT", CMapOutdoor::TEXTURE_SORT); 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 // 40250 UserInterface/PythonEventManagerMoudle.cpp
void AddStubConstants_event(PyObject* poModule) 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); 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 // 40250 UserInterface/PythonGuild.cpp
void AddStubConstants_guild(PyObject* poModule) void AddStubConstants_guild(PyObject* poModule)
{ {
@@ -7,11 +7,9 @@
// GameplayModuleConstants.cpp: each module's 40250 constants. // GameplayModuleConstants.cpp: each module's 40250 constants.
void AddStubConstants_ServerStateChecker(PyObject* poModule); void AddStubConstants_ServerStateChecker(PyObject* poModule);
void AddStubConstants_background(PyObject* poModule); void AddStubConstants_background(PyObject* poModule);
void AddStubConstants_effect(PyObject* poModule);
void AddStubConstants_event(PyObject* poModule); void AddStubConstants_event(PyObject* poModule);
void AddStubConstants_eventMgr(PyObject* poModule); void AddStubConstants_eventMgr(PyObject* poModule);
void AddStubConstants_exchange(PyObject* poModule); void AddStubConstants_exchange(PyObject* poModule);
void AddStubConstants_fly(PyObject* poModule);
void AddStubConstants_guild(PyObject* poModule); void AddStubConstants_guild(PyObject* poModule);
void AddStubConstants_ime(PyObject* poModule); void AddStubConstants_ime(PyObject* poModule);
void AddStubConstants_item(PyObject* poModule); void AddStubConstants_item(PyObject* poModule);
@@ -150,24 +148,6 @@ PyMethodDef methods_background[] = {
{ "WarpTest", stub_background_WarpTest, METH_VARARGS }, { "WarpTest", stub_background_WarpTest, METH_VARARGS },
{ NULL, NULL } { 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. // 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_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)); } 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 }, { "SetElkMode", stub_exchange_SetElkMode, METH_VARARGS },
{ NULL, NULL } { 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. // 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_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)); } 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); PyModule_AddIntConstant(module, "__port_stub__", 1);
AddStubConstants_background(module); 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); PyObject* module = Py_InitModule("event", methods_event);
PyModule_AddIntConstant(module, "__port_stub__", 1); PyModule_AddIntConstant(module, "__port_stub__", 1);
@@ -950,11 +917,6 @@ void init_2v0_gameplay_stubs() {
PyModule_AddIntConstant(module, "__port_stub__", 1); PyModule_AddIntConstant(module, "__port_stub__", 1);
AddStubConstants_exchange(module); 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); PyObject* module = Py_InitModule("guild", methods_guild);
PyModule_AddIntConstant(module, "__port_stub__", 1); PyModule_AddIntConstant(module, "__port_stub__", 1);
@@ -319,6 +319,7 @@ bool Start(const char* stdlib_path, std::string* error)
g_effect_manager = std::make_unique<CEffectManager>(); g_effect_manager = std::make_unique<CEffectManager>();
g_game_application = std::make_unique<GameApplicationAdapter>(); g_game_application = std::make_unique<GameApplicationAdapter>();
g_game_singletons = std::make_unique<GameSingletons>(); g_game_singletons = std::make_unique<GameSingletons>();
g_flying_manager->SetMapManagerPtr(&g_game_singletons->pyBackground); // 40250 CPythonApplication ctor (PythonApplication.cpp:82)
return true; return true;
} }
@@ -344,6 +345,8 @@ bool run_main_script_body(const char* lpCmdLine, std::string* error)
initPlayer(); initPlayer();
initChat(); initChat();
initnet(); initnet();
initeffect();
initfly();
init_2v0_gameplay_stubs(); init_2v0_gameplay_stubs();
ClearLogBoxMessage(); ClearLogBoxMessage();
@@ -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<bool>();
}
auto CFlyingManager::RegisterFlyingData(const char *, DWORD &) -> bool
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<bool>();
}
auto CFlyingManager::CreateFlyingInstanceFlyTarget(const DWORD, const D3DXVECTOR3 &, const CFlyTarget &, bool) -> CFlyingInstance *
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<CFlyingInstance *>();
}
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<bool>();
}
auto CFlyingManager::CreateIndexedFly(DWORD, CActorInstance *, CActorInstance *) -> void
{
MT_PLATFORM_STUB();
}
auto CFlyingManager::__DestroyFlyingInstanceList() -> void
{
MT_PLATFORM_STUB();
}
auto CFlyingManager::__DestroyFlyingDataMap() -> void
{
MT_PLATFORM_STUB();
}
@@ -86,7 +86,15 @@ const std::vector<BYTE> *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 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); auto found = s_native_maps.find(this);
if (found == s_native_maps.end() || !found->second.ready) if (found == s_native_maps.end() || !found->second.ready)
+291
View File
@@ -0,0 +1,291 @@
#include "StdAfx.h"
#include "../EterLib/StateManager.h"
#include "../EterLib/Camera.h"
#include "FlyingData.h"
#include "FlyTrace.h"
CDynamicPool<CFlyTrace> 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<CTimer::Instance().GetCurrentSecond())
{
m_TimePositionDeque.pop_back();
}
}
void CFlyTrace::Create(const CFlyingData::TFlyingAttachData & rFlyingAttachData)
{
//assert(rFlyingAttachData.bHasTail);
m_dwColor = rFlyingAttachData.dwTailColor;
m_fTailLength = rFlyingAttachData.fTailLength;
m_fSize = rFlyingAttachData.fTailSize;
m_bRectShape = rFlyingAttachData.bRectShape;
}
void CFlyTrace::Update()
{
}
//1. 알파를 쓰려면 색깔만 줄수있다.
//2. 텍스쳐를 쓰려면 알파 없다-_-
struct TFlyVertex
{
D3DXVECTOR3 p;
DWORD c;
D3DXVECTOR2 t;
TFlyVertex(){};
TFlyVertex(const D3DXVECTOR3& p, DWORD c, const D3DXVECTOR2 & t):p(p),c(c),t(t){}
};
struct TFlyVertexSet
{
TFlyVertex v[6];
TFlyVertexSet(TFlyVertex * pv)
{
memcpy(v,pv,sizeof(v));
}
bool operator < (const TFlyVertexSet& ) const
{
return false;
}
TFlyVertexSet & operator = ( const TFlyVertexSet& rhs )
{
memcpy(v,rhs.v,sizeof(v));
return *this;
}
};
typedef std::vector<std::pair<float, TFlyVertexSet> > 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);
}
+44
View File
@@ -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<float, D3DXVECTOR3> TTimePosition;
typedef std::deque<TTimePosition> 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<CFlyTrace> ms_kPool;
};
+353
View File
@@ -0,0 +1,353 @@
#include "StdAfx.h"
#include "../EffectLib/EffectManager.h"
#include "FlyingData.h"
CDynamicPool<CFlyingData> 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<TextFileLoader.GetChildNodeCount();i++)
{
CTextFileLoader::CGotoChild GotoChild(&TextFileLoader, i);
std::string strNodeName;
TextFileLoader.GetCurrentNodeName(&strNodeName);
if (strNodeName=="attachdata")
{
TFlyingAttachData fad;
if (!TextFileLoader.GetTokenInteger("type",&fad.iType))
continue;
TextFileLoader.GetTokenInteger("flytype",&fad.iFlyType);
if (!TextFileLoader.GetTokenString("attachfile",&fad.strFilename))
{
fad.strFilename = "";
}
else if (!fad.strFilename.empty())
{
if (!IsGlobalFileName(fad.strFilename.c_str()))
fad.strFilename = GetOnlyPathName(TextFileLoader.GetFileName()) + fad.strFilename;
CEffectManager::Instance().RegisterEffect(fad.strFilename.c_str());
}
TextFileLoader.GetTokenInteger("tailflag",&temp);
if (temp)
{
fad.bHasTail = true;
TextFileLoader.GetTokenDoubleWord("tailcolor",&fad.dwTailColor);
TextFileLoader.GetTokenFloat("taillength",&fad.fTailLength);
TextFileLoader.GetTokenFloat("tailsize",&fad.fTailSize);
TextFileLoader.GetTokenInteger("tailshaperect",&temp);
fad.bRectShape = temp?true:false;
}
else
{
fad.bHasTail = false;
}
TextFileLoader.GetTokenFloat("roll",&fad.fRoll);
TextFileLoader.GetTokenFloat("distance",&fad.fDistance);
TextFileLoader.GetTokenFloat("period",&fad.fPeriod);
TextFileLoader.GetTokenFloat("amplitude",&fad.fAmplitude);
m_AttachDataVector.push_back(fad);
}
else
{
TraceError("CFlyingData::LoadScriptFile Wrong Data : %s", m_strFilename.c_str());
}
}
NANOEND
return true;
}
bool CFlyingData::SaveScriptFile(const char* c_szFilename)
{
FILE* fp = fopen(c_szFilename,"w");
if (!fp) return false;
PrintfTabs(fp, 0, "SpreadingFlag %d\n", m_bSpreading?1:0);
PrintfTabs(fp, 0, "MaintainParallelFlag %d\n", m_bMaintainParallel?1:0);
PrintfTabs(fp, 0, "InitialVelocity %f\n", m_fInitVel);
PrintfTabs(fp, 0, "ConeAngle %f\n", m_fConeAngle);
PrintfTabs(fp, 0, "RollAngle %f\n", m_fRollAngle);
PrintfTabs(fp, 0, "AngularVelocity %f %f %f\n", m_v3AngVel.x, m_v3AngVel.y, m_v3AngVel.z);
PrintfTabs(fp, 0, "Gravity %f\n", m_fGravity);
PrintfTabs(fp, 0, "HitOnBackground %d\n",m_bHitOnBackground?1:0);
PrintfTabs(fp, 0, "HitOnAnotherMonster %d\n",m_bHitOnAnotherMonster?1:0);
PrintfTabs(fp, 0, "PierceCount %d\n",m_iPierceCount);
PrintfTabs(fp, 0, "CollisionSphereRadius %f\n",m_fCollisionSphereRadius);
PrintfTabs(fp, 0, "BombRange %f\n", m_fBombRange);
std::string strGlobalPathName;
StringPath(GetOnlyPathName(c_szFilename), strGlobalPathName);
std::string strLocalFileName;
if (GetLocalFileName(strGlobalPathName.c_str(), m_strBombEffectName.c_str(), &strLocalFileName))
PrintfTabs(fp, 0, "BombEffect \"%s\"\n", strLocalFileName.c_str());
else
PrintfTabs(fp, 0, "BombEffect \"%s\"\n", m_strBombEffectName.c_str());
PrintfTabs(fp, 0, "HomingFlag %d\n", m_bIsHoming?1:0);
PrintfTabs(fp, 0, "HomingStartTime %f\n", m_fHomingStartTime);
PrintfTabs(fp, 0, "HomingMaxAngle %f\n", m_fHomingMaxAngle);
PrintfTabs(fp, 0, "Range %f\n", m_fRange);
PrintfTabs(fp, 0, "Acceleration %f %f %f\n", m_v3Accel.x, m_v3Accel.y, m_v3Accel.z);
std::vector<TFlyingAttachData>::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;
}
+111
View File
@@ -0,0 +1,111 @@
#pragma once
class CFlyingData //: public CPooledObject<CFlyingData>
{
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<TFlyingAttachData> 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<CFlyingData> ms_kPool;
};
@@ -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> 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;i<m_pData->GetAttachDataCount();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_pData->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_pData->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;
}
@@ -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;
}
}
}
@@ -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);
}
@@ -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);
}
@@ -49,3 +49,5 @@ void initchrmgr();
void initPlayer(); void initPlayer();
void initChat(); void initChat();
void initnet(); void initnet();
void initeffect();
void initfly();
+12
View File
@@ -45,6 +45,8 @@
#include "GameLib/RaceManager.h" #include "GameLib/RaceManager.h"
#include "GameLib/RaceData.h" #include "GameLib/RaceData.h"
#include "GameLib/RaceMotionData.h" #include "GameLib/RaceMotionData.h"
#include "GameLib/FlyingData.h"
#include "GameLib/FlyingObjectManager.h"
#include "UserInterface/StdAfx.h" #include "UserInterface/StdAfx.h"
#include "UserInterface/PythonCharacterManager.h" #include "UserInterface/PythonCharacterManager.h"
#include "UserInterface/InstanceBase.h" #include "UserInterface/InstanceBase.h"
@@ -433,6 +435,16 @@ int main(int argc, char** argv)
CHECK(blocked > 0); 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 // 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 // OnMouseLeftButtonDown → player.SetMouseState(MBT_LEFT, MBS_PRESS); CPythonPlayer picks the ground
// through the cursor ray (CScreen::SetCursorPosition → CPythonBackground::GetPickingPoint) and the // through the cursor ray (CScreen::SetCursorPosition → CPythonBackground::GetPickingPoint) and the