summaryrefslogtreecommitdiff
path: root/src/KingSystem
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-04-22 00:05:35 +0200
committerLéo Lam <leo@leolam.fr>2021-04-22 01:18:45 +0200
commitdd705aea99d9d1222c560df02a3a01d64a5c22dc (patch)
treead54aabbb50b32d1574769f2f630460b9226c2c7 /src/KingSystem
parent1631e2aae326499a1eba3ca88b54241db13efa97 (diff)
ksys/phys: Add CharacterControllerParam
Diffstat (limited to 'src/KingSystem')
-rw-r--r--src/KingSystem/Physics/CMakeLists.txt2
-rw-r--r--src/KingSystem/Physics/System/physCharacterControllerParam.cpp113
-rw-r--r--src/KingSystem/Physics/System/physCharacterControllerParam.h115
3 files changed, 230 insertions, 0 deletions
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 <agl/Utils/aglParameter.h>
+#include <agl/Utils/aglParameterList.h>
+#include <agl/Utils/aglParameterObj.h>
+#include <container/seadBuffer.h>
+#include <prim/seadEnum.h>
+
+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<int> shape_num;
+ agl::utl::Parameter<sead::FixedSafeString<32>> form_type;
+ sead::Buffer<ShapeParam> 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<float> mass;
+ agl::utl::Parameter<float> volume;
+ agl::utl::Parameter<float> max_force;
+ agl::utl::Parameter<int> form_num;
+ agl::utl::Parameter<sead::FixedSafeString<32>> layer;
+ agl::utl::Parameter<sead::FixedSafeString<32>> groundhit;
+ agl::utl::Parameter<sead::FixedSafeString<32>> initial_state;
+ agl::utl::Parameter<sead::FixedSafeString<32>> initial_form;
+ agl::utl::Parameter<float> max_impulse;
+ agl::utl::Parameter<sead::FixedSafeString<32>> contact_point_info;
+ agl::utl::Parameter<sead::FixedSafeString<32>> collision_info;
+ agl::utl::Parameter<bool> use_nav_mesh_character;
+ agl::utl::Parameter<float> nav_mesh_character_radius;
+ agl::utl::Parameter<float> nav_mesh_character_height;
+ agl::utl::Parameter<u32> nav_mesh_character_avoidance_priority;
+ agl::utl::Parameter<float> nav_mesh_character_max_speed;
+ agl::utl::Parameter<float> nav_mesh_character_max_acceleration;
+ agl::utl::Parameter<float> nav_mesh_character_max_angular_velocity;
+ agl::utl::Parameter<sead::SafeString> nav_mesh_character_type;
+ agl::utl::Parameter<bool> enable_water_effect;
+ agl::utl::Parameter<bool> enable_force_fall_cliff_edge;
+ agl::utl::Parameter<float> water_effective_height;
+ agl::utl::Parameter<float> water_flow_effective_rate;
+ agl::utl::Parameter<float> water_attn_effective_rate;
+ agl::utl::Parameter<float> max_force_scale_NPC;
+ agl::utl::Parameter<float> water_buoyancy_scale;
+ agl::utl::Parameter<float> magne_mass_scaling_factor;
+ agl::utl::Parameter<float> height_enable_hitting_wall;
+ sead::Buffer<Form> forms;
+};
+
+} // namespace ksys::phys