diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 8eba5b25..9565e2f4 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -94756,27 +94756,28 @@ 0x0000007101280294,sub_7101280294,56, 0x00000071012802cc,sub_71012802CC,132, 0x0000007101280350,j__ZdlPv_1279,4, -0x0000007101280354,Bphysics::CharacterController::ctor,3140, -0x0000007101280f98,sub_7101280F98,452, -0x000000710128115c,sub_710128115C,36, -0x0000007101281180,Bphysics::CharacterController::applyObjAndLists,408, -0x0000007101281318,sub_7101281318,420, +0x0000007101280354,Bphysics::CharacterController::ctor,3140,_ZN4ksys4phys24CharacterControllerParamC1Ev +0x0000007101280f98,sub_7101280F98,452,_ZN4ksys4phys24CharacterControllerParamD1Ev +0x000000710128115c,sub_710128115C,36,_ZN4ksys4phys24CharacterControllerParamD0Ev +0x0000007101281180,Bphysics::CharacterController::applyObjAndLists,408,_ZN4ksys4phys24CharacterControllerParam5parseEN3agl3utl16ResParameterListEPN4sead4HeapE +0x0000007101281318,sub_7101281318,420,_ZN4ksys4phys24CharacterControllerParam4Form5parseEN3agl3utl16ResParameterListEPN4sead4HeapE 0x00000071012814bc,sub_71012814BC,112, 0x000000710128152c,sub_710128152C,732, -0x0000007101281808,sub_7101281808,2244, -0x00000071012820cc,sub_71012820CC,120, -0x0000007101282144,sub_7101282144,544, -0x0000007101282364,sub_7101282364,168, -0x000000710128240c,sub_710128240C,112, +0x0000007101281808,sub_7101281808,0x74,_ZN4ksys4phys24CharacterControllerParam10createFormEiPN4sead4HeapE +0x000000710128187c,sub_710128187c,0x850, +0x00000071012820cc,sub_71012820CC,120,_ZThn72_N4ksys4phys24CharacterControllerParam10createFormEiPN4sead4HeapE +0x0000007101282144,sub_7101282144,544,_ZN4ksys4phys24CharacterControllerParam4FormC1Ev +0x0000007101282364,sub_7101282364,168,_ZN4ksys4phys24CharacterControllerParam4FormD1Ev +0x000000710128240c,sub_710128240C,112,_ZN4ksys4phys24CharacterControllerParam4FormD0Ev 0x000000710128247c,sub_710128247C,584, -0x00000071012826c4,sub_71012826C4,332, -0x0000007101282810,sub_7101282810,8, -0x0000007101282818,sub_7101282818,8, -0x0000007101282820,sub_7101282820,428, -0x00000071012829cc,j__ZdlPv_1280,4, -0x00000071012829d0,_ZN4sead15FixedSafeStringILi87EEaSERKNS_14SafeStringBaseIcEE,240, -0x0000007101282ac0,j__ZdlPv_1281,4, -0x0000007101282ac4,_ZN4sead19FixedSafeStringBaseIcLi87EEaSERKNS_14SafeStringBaseIcEE,240, +0x00000071012826c4,sub_71012826C4,332,_ZNK4ksys4phys24CharacterControllerParam11findFormIdxERKN4sead14SafeStringBaseIcEE +0x0000007101282810,sub_7101282810,8,_ZN4ksys4phys24CharacterControllerParam11getNumFormsEv +0x0000007101282818,sub_7101282818,8,_ZThn72_N4ksys4phys24CharacterControllerParam11getNumFormsEv +0x0000007101282820,sub_7101282820,428,_ZN4ksys4phys20NavMeshCharacterType5text_Ei +0x00000071012829cc,j__ZdlPv_1280,4,_ZN4sead15FixedSafeStringILi223EED0Ev +0x00000071012829d0,_ZN4sead15FixedSafeStringILi223EEaSERKNS_14SafeStringBaseIcEE,240,_ZN4sead15FixedSafeStringILi223EEaSERKNS_14SafeStringBaseIcEE +0x0000007101282ac0,j__ZdlPv_1281,4,_ZN4sead19FixedSafeStringBaseIcLi223EED0Ev +0x0000007101282ac4,_ZN4sead19FixedSafeStringBaseIcLi223EEaSERKNS_14SafeStringBaseIcEE,240,_ZN4sead19FixedSafeStringBaseIcLi223EEaSERKNS_14SafeStringBaseIcEE 0x0000007101282bb4,sub_7101282BB4,268,_ZN4ksys4phys16ContactInfoParamC1Ev 0x0000007101282cc0,sub_7101282CC0,276,_ZN4ksys4phys16ContactInfoParamD1Ev 0x0000007101282dd4,sub_7101282DD4,220,_ZN4ksys4phys16ContactInfoParamD0Ev diff --git a/src/KingSystem/Physics/CMakeLists.txt b/src/KingSystem/Physics/CMakeLists.txt index e6f1c01b..969495fe 100644 --- a/src/KingSystem/Physics/CMakeLists.txt +++ b/src/KingSystem/Physics/CMakeLists.txt @@ -9,6 +9,8 @@ target_sources(uking PRIVATE RigidBody/physEdgeRigidBodyParam.h SupportBone/physSupportBoneParam.cpp SupportBone/physSupportBoneParam.h + System/physCharacterControllerParam.cpp + System/physCharacterControllerParam.h System/physContactInfoParam.cpp System/physContactInfoParam.h System/physDefines.cpp diff --git a/src/KingSystem/Physics/System/physCharacterControllerParam.cpp b/src/KingSystem/Physics/System/physCharacterControllerParam.cpp new file mode 100644 index 00000000..cb5311d8 --- /dev/null +++ b/src/KingSystem/Physics/System/physCharacterControllerParam.cpp @@ -0,0 +1,113 @@ +#include "KingSystem/Physics/System/physCharacterControllerParam.h" +#include "KingSystem/Physics/System/physShapeParam.h" + +namespace ksys::phys { + +bool navMeshCharacterTypeFromText(NavMeshCharacterType& value, const sead::SafeString& text) { + for (auto type : NavMeshCharacterType()) { + if (sead::SafeString(type.text()) == text) { + value = type; + return true; + } + } + return false; +} + +CharacterControllerParam::CharacterControllerParam() + : mass(100.0, "mass", &obj), volume(1.0, "volume", &obj), max_force(20.0, "max_force", &obj), + form_num(0, "form_num", &obj), layer({"EntityNPC"}, "layer", &obj), + groundhit({"HitAll"}, "groundhit", &obj), initial_state({"Default"}, "initial_state", &obj), + initial_form({"Standing"}, "initial_form", &obj), max_impulse(-1.0, "max_impulse", &obj), + contact_point_info(sead::SafeString::cEmptyString, "contact_point_info", &obj), + collision_info(sead::SafeString::cEmptyString, "collision_info", &obj), + use_nav_mesh_character(false, "use_nav_mesh_character", &obj), + nav_mesh_character_radius(0.0, "nav_mesh_character_radius", &obj), + nav_mesh_character_height(0.0, "nav_mesh_character_height", &obj), + nav_mesh_character_avoidance_priority(0, "nav_mesh_character_avoidance_priority", &obj), + nav_mesh_character_max_speed(0.0, "nav_mesh_character_max_speed", &obj), + nav_mesh_character_max_acceleration(0.0, "nav_mesh_character_max_acceleration", &obj), + nav_mesh_character_max_angular_velocity(0.0, "nav_mesh_character_max_angular_velocity", &obj), + nav_mesh_character_type(sead::SafeString::cEmptyString, "nav_mesh_character_type", &obj), + enable_water_effect(false, "enable_water_effect", &obj), + enable_force_fall_cliff_edge(false, "enable_force_fall_cliff_edge", &obj), + water_effective_height(1.0, "water_effective_height", &obj), + water_flow_effective_rate(0.0, "water_flow_effective_rate", &obj), + water_attn_effective_rate(0.0, "water_attn_effective_rate", &obj), + max_force_scale_NPC(100.0, "max_force_scale_NPC", &obj), + water_buoyancy_scale(1.0, "water_buoyancy_scale", &obj), + magne_mass_scaling_factor(1.0, "magne_mass_scaling_factor", &obj), + height_enable_hitting_wall(0.1, "height_enable_hitting_wall", &obj) {} + +CharacterControllerParam::~CharacterControllerParam() { + forms.freeBuffer(); +} + +bool CharacterControllerParam::parse(agl::utl::ResParameterList res_list, sead::Heap* heap) { + if (!res_list || res_list.getResParameterObjNum() < 1) + return false; + + obj.applyResParameterObj(res_list.getResParameterObj(0), nullptr); + + const int num_forms = *form_num; + if (num_forms < 0) + return false; + + if (num_forms == 0) + return true; + + forms.allocBufferAssert(num_forms, heap); + for (int i = 0; i < num_forms; ++i) { + if (!forms[i].parse(res_list.getResParameterList(i), heap)) + return false; + + addList(&forms[i], sead::FormatFixedSafeString<32>("Form_%d", i)); + } + + return true; +} + +void* CharacterControllerParam::createForm(int form_idx, sead::Heap* heap) { + if (form_idx >= getNumForms() || form_idx < 0) + return nullptr; + return forms[form_idx].createForm(heap); +} + +CharacterControllerParam::Form::Form() + : shape_num(0, "shape_num", &form_header_obj), + form_type(sead::SafeString::cEmptyString, "form_type", &form_header_obj) { + addObj(&form_header_obj, "FormHeader"); +} + +CharacterControllerParam::Form::~Form() { + shape_params.freeBuffer(); +} + +bool CharacterControllerParam::Form::parse(agl::utl::ResParameterList res_list, sead::Heap* heap) { + if (!res_list || res_list.getResParameterObjNum() < 2) + return false; + + form_header_obj.applyResParameterObj(res_list.getResParameterObj(0), nullptr); + + const int num_shapes = *shape_num; + if (num_shapes < 1) + return true; + + shape_params.allocBufferAssert(num_shapes, heap); + for (int i = 0; i < num_shapes; ++i) { + if (!shape_params[i].parse(res_list.getResParameterObj(i + 1), heap)) + return false; + addObj(&shape_params[i], sead::FormatFixedSafeString<32>("ShapeParam_%d", i)); + } + + return true; +} + +int CharacterControllerParam::findFormIdx(const sead::SafeString& form_type) const { + for (int i = 0, n = forms.size(); i < n; ++i) { + if (form_type == *forms[i].form_type) + return i; + } + return -1; +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physCharacterControllerParam.h b/src/KingSystem/Physics/System/physCharacterControllerParam.h new file mode 100644 index 00000000..b2d05add --- /dev/null +++ b/src/KingSystem/Physics/System/physCharacterControllerParam.h @@ -0,0 +1,115 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace ksys::phys { + +struct ShapeParam; + +SEAD_ENUM(NavMeshCharacterType, +Player, +Horse, +Enemy, +Guardian, +NPC, +NPCGoron, +NPCSwimmer, +NPCGerudoPassable, +Fish, +Animal, +SmallAnimal, +DomesticAnimal, +PoorSwimmer, +GoodSwimmer, +IceSwimmer, +FireEnemy, +WolfLink, +GiantEnemy, +GiantSwimmer, +TallEnemy, +Lynel) + +bool navMeshCharacterTypeFromText(NavMeshCharacterType& value, const sead::SafeString& text); + +struct ICharacterControllerParam { + virtual int getNumForms() = 0; + // TODO: return type + virtual void* createForm(int form_idx, sead::Heap* heap) = 0; +}; + +// TODO: more functions +struct CharacterControllerParam : agl::utl::ParameterList, ICharacterControllerParam { + struct Form : agl::utl::ParameterList { + Form(); + ~Form() override; + Form(const Form&) = delete; + auto operator=(const Form&) = delete; + + bool parse(agl::utl::ResParameterList res_list, sead::Heap* heap); + + // TODO: return type + void* createForm(sead::Heap* heap); + + agl::utl::ParameterObj form_header_obj; + agl::utl::Parameter shape_num; + agl::utl::Parameter> form_type; + sead::Buffer shape_params; + }; + + CharacterControllerParam(); + ~CharacterControllerParam() override; + CharacterControllerParam(const CharacterControllerParam&) = delete; + auto operator=(const CharacterControllerParam&) = delete; + + int getNumForms() override { return forms.size(); } + void* createForm(int form_idx, sead::Heap* heap) override; + + // TODO: return type + void* createController(sead::Heap* heap); + // TODO: types + void* createControllerState(const sead::SafeString& name, void* ctrl, void* x, bool y, + sead::Heap* heap); + // TODO: return type + void* createNavMeshCharacter(const sead::SafeString& name, sead::Heap* heap, + const sead::Vector3f& scale); + + int findFormIdx(const sead::SafeString& form_type) const; + bool parse(agl::utl::ResParameterList res_list, sead::Heap* heap); + + agl::utl::ParameterObj obj; + agl::utl::Parameter mass; + agl::utl::Parameter volume; + agl::utl::Parameter max_force; + agl::utl::Parameter form_num; + agl::utl::Parameter> layer; + agl::utl::Parameter> groundhit; + agl::utl::Parameter> initial_state; + agl::utl::Parameter> initial_form; + agl::utl::Parameter max_impulse; + agl::utl::Parameter> contact_point_info; + agl::utl::Parameter> collision_info; + agl::utl::Parameter use_nav_mesh_character; + agl::utl::Parameter nav_mesh_character_radius; + agl::utl::Parameter nav_mesh_character_height; + agl::utl::Parameter nav_mesh_character_avoidance_priority; + agl::utl::Parameter nav_mesh_character_max_speed; + agl::utl::Parameter nav_mesh_character_max_acceleration; + agl::utl::Parameter nav_mesh_character_max_angular_velocity; + agl::utl::Parameter nav_mesh_character_type; + agl::utl::Parameter enable_water_effect; + agl::utl::Parameter enable_force_fall_cliff_edge; + agl::utl::Parameter water_effective_height; + agl::utl::Parameter water_flow_effective_rate; + agl::utl::Parameter water_attn_effective_rate; + agl::utl::Parameter max_force_scale_NPC; + agl::utl::Parameter water_buoyancy_scale; + agl::utl::Parameter magne_mass_scaling_factor; + agl::utl::Parameter height_enable_hitting_wall; + sead::Buffer
forms; +}; + +} // namespace ksys::phys