ksys/eco: Finish Ecosystem

This commit is contained in:
Léo Lam 2021-11-23 22:03:51 +01:00
parent b63c16c55f
commit 73e2b74045
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
3 changed files with 197 additions and 18 deletions

View File

@ -77855,17 +77855,17 @@ Address,Quality,Size,Name
0x0000007100e4167c,O,000100,_ZN4ksys3eco9Ecosystem18SingletonDisposer_D1Ev
0x0000007100e416e0,O,000108,_ZN4ksys3eco9Ecosystem18SingletonDisposer_D0Ev
0x0000007100e4174c,O,000208,_ZN4ksys3eco9Ecosystem14createInstanceEPN4sead4HeapE
0x0000007100e4181c,U,001056,Ecosystem::init
0x0000007100e4181c,O,001056,_ZN4ksys3eco9Ecosystem4initEPN4sead4HeapE
0x0000007100e41c3c,O,000004,_ZN4ksys3eco9Ecosystem4calcEv
0x0000007100e41c40,M,000292,_ZNK4ksys3eco9Ecosystem10getMapAreaERKNS0_10EcoMapInfoEff
0x0000007100e41d64,U,000636,Ecosystem::__auto1
0x0000007100e41d64,O,000636,_ZNK4ksys3eco9Ecosystem12getAreaItemsEiNS0_12AreaItemTypeEPNS0_11AreaItemSetE
0x0000007100e41fe0,m,000384,_ZNK4ksys3eco9Ecosystem19getStatusEffectInfoENS0_12StatusEffectEiPNS0_16StatusEffectInfoE
0x0000007100e42160,O,000120,_ZNK4ksys3eco9Ecosystem16getAreaNameByNumEiPPKc
0x0000007100e421d8,O,000120,_ZNK4ksys3eco9Ecosystem19getClimateNameByNumEiPPKc
0x0000007100e42250,O,000120,_ZNK4ksys3eco9Ecosystem20getEnvSoundNameByNumEiPPKc
0x0000007100e422c8,m,000356,_ZNK4ksys3eco9Ecosystem17getEcoTraitsByNumEiPNS0_15EcosystemTraitsE
0x0000007100e4242c,U,000096,
0x0000007100e4248c,U,000104,
0x0000007100e4242c,O,000096,_ZN4ksys3eco9EcosystemD1Ev
0x0000007100e4248c,O,000104,_ZN4ksys3eco9EcosystemD0Ev
0x0000007100e424f4,O,000040,_ZN4ksys3eco11LevelSensorC1Ev
0x0000007100e4251c,O,000072,_ZN4ksys3eco11LevelSensorD1Ev
0x0000007100e42564,O,000080,_ZN4ksys3eco11LevelSensorD0Ev

Can't render this file because it is too large.

View File

@ -1,7 +1,26 @@
#include "KingSystem/Ecosystem/ecoSystem.h"
#include "KingSystem/Resource/resLoadRequest.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
namespace ksys::eco {
constexpr const char* sAreaItemTypeStr[] = {
"Animal",
"Fish",
"Insect",
"Bird",
"Mushroom",
"Fruit",
"Mineral",
"Plant",
"Enemy",
"GrassCut",
"AutoCliffMaterial",
"AutoPlacementMaterial",
"RuinAutoPlacement",
"RainBonusMaterial",
};
static const char* sStatusEffectNames[22] = {"StatusEffect",
"LifeRecover",
"LifeMaxUp",
@ -27,6 +46,55 @@ static const char* sStatusEffectNames[22] = {"StatusEffect",
SEAD_SINGLETON_DISPOSER_IMPL(Ecosystem)
static void setEcoMapInfo(EcoMapInfo& info, const u8* data) {
info.mHeader = reinterpret_cast<const EcoMapHeader*>(data);
info.mRowOffsets = reinterpret_cast<const u32*>(info.mHeader + 1);
info.mRows =
reinterpret_cast<const char*>(info.mRowOffsets) + sizeof(int) * info.mHeader->num_rows;
}
void Ecosystem::init(sead::Heap* heap) {
res::LoadRequest req;
req.mRequester = "Ecosystem";
req._22 = false;
mHandles.mFieldMapArea.load("Ecosystem/FieldMapArea.beco", &req);
req._22 = true;
mHandles.mAreaData.load("Ecosystem/AreaData.byml", &req);
req._22 = false;
mHandles.mMapTower.load("Ecosystem/MapTower.beco", &req);
req._22 = false;
mHandles.mStatusEffectList.load("Ecosystem/StatusEffectList.byml", &req);
req._22 = false;
mHandles.mLoadBalancer.load("Ecosystem/LoadBalancer.beco", &req);
auto* field_map_area =
sead::DynamicCast<sead::DirectResource>(mHandles.mFieldMapArea.getResource());
setEcoMapInfo(mFieldMapArea, field_map_area->getRawData());
auto* map_tower = sead::DynamicCast<sead::DirectResource>(mHandles.mMapTower.getResource());
setEcoMapInfo(mMapTower, map_tower->getRawData());
auto* load_balancer =
sead::DynamicCast<sead::DirectResource>(mHandles.mLoadBalancer.getResource());
setEcoMapInfo(mLoadBalancer, load_balancer->getRawData());
auto* area_data = sead::DynamicCast<sead::DirectResource>(mHandles.mAreaData.getResource());
mAreaDataIter = new (heap) al::ByamlIter(area_data->getRawData());
mAreaDataSize = mAreaDataIter->getSize();
auto* status_effect_list =
sead::DynamicCast<sead::DirectResource>(mHandles.mStatusEffectList.getResource());
mStatusEffectListIter = new (heap) al::ByamlIter(status_effect_list->getRawData());
mLevelSensor = new (heap) LevelSensor;
mLevelSensor->init(heap);
}
void Ecosystem::calc() {}
// FP instructions rearranged.
@ -65,6 +133,64 @@ s32 Ecosystem::getMapArea(const EcoMapInfo& info, f32 posX, f32 posZ) const {
}
#endif
void Ecosystem::getAreaItems(s32 areaNum, AreaItemType type, AreaItemSet* out) const {
out->count = 0;
if (areaNum < 0 || areaNum >= int(mAreaDataSize))
return;
al::ByamlIter area_iter;
if (!mAreaDataIter->tryGetIterByIndex(&area_iter, areaNum))
return;
al::ByamlIter items_iter;
if (!area_iter.tryGetIterByKey(&items_iter, sAreaItemTypeStr[u32(type)]))
return;
out->count = items_iter.getSize();
for (int i = 0; i < out->count; ++i) {
al::ByamlIter item_iter;
if (!items_iter.tryGetIterByIndex(&item_iter, i))
continue;
auto& entry = out->items[i];
item_iter.tryGetStringByKey(&entry.name, "name");
item_iter.tryGetFloatByKey(&entry.num, "num");
if (!item_iter.tryGetStringByKey(&entry.set, "set"))
entry.set = nullptr;
if (!item_iter.tryGetFloatByKey(&entry.radius, "radius"))
entry.radius = 0.0;
al::ByamlIter weapons_iter;
if (item_iter.tryGetIterByKey(&weapons_iter, "weapons")) {
// Fill in weapon information now.
for (int w_idx = 0; w_idx < weapons_iter.getSize(); ++w_idx) {
al::ByamlIter weapon_iter;
if (!weapons_iter.tryGetIterByIndex(&weapon_iter, w_idx))
continue;
auto& weapon = entry.weapons[w_idx];
weapon_iter.tryGetStringByKey(&weapon.name, "name");
if (!weapon_iter.tryGetFloatByKey(&weapon.prob, "prob")) {
// Try to get `prob` again, this time as an integer.
int prob;
if (weapon_iter.tryGetIntByKey(&prob, "prob"))
weapon.prob = prob;
else
weapon.prob = 100.0;
}
}
entry.num_weapons = weapons_iter.getSize();
} else {
entry.num_weapons = 0;
}
}
}
void Ecosystem::getAreaNameByNum(s32 areaNum, const char** out) const {
*out = nullptr;
@ -199,4 +325,6 @@ void Ecosystem::getEcoTraitsByNum(s32 areaNum, EcosystemTraits* out) const {
}
}
Ecosystem::~Ecosystem() = default;
} // namespace ksys::eco

View File

@ -1,19 +1,27 @@
#pragma once
#include <basis/seadTypes.h>
#include <container/seadSafeArray.h>
#include <heap/seadDisposer.h>
#include <heap/seadExpHeap.h>
#include <math/seadMathCalcCommon.h>
#include "KingSystem/Ecosystem/ecoLevelSensor.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
namespace al {
class ByamlIter;
}
namespace ksys::eco {
struct EcoMapHeader {
u32 unknown;
/// File magic (0x00112233).
u32 magic;
s32 num_rows;
s32 divisor;
u32 reserved;
};
KSYS_CHECK_SIZE_NX150(EcoMapHeader, 0x10);
struct Segment {
s16 value;
s16 length;
@ -21,14 +29,54 @@ struct Segment {
class EcoMapInfo {
public:
EcoMapHeader* mHeader;
u32* mRowOffsets;
char* mRows;
const EcoMapHeader* mHeader;
const u32* mRowOffsets;
const char* mRows;
};
enum ActorType {};
enum class AreaItemType {
Animal,
Fish,
Insect,
Bird,
Mushroom,
Fruit,
Mineral,
Plant,
Enemy,
GrassCut,
AutoCliffMaterial,
AutoPlacementMaterial,
RuinAutoPlacement,
RainBonusMaterial,
};
struct ActorSpawnInfo;
struct AreaWeapon {
/// Weapon name.
const char* name;
/// Probability of this weapon appearing (0 to 100).
float prob;
};
struct AreaItem {
/// Actor name.
const char* name;
/// Appearance weight.
float num;
/// Weapons carried by this actor (if this is an enemy).
sead::SafeArray<AreaWeapon, 24> weapons;
/// Number of valid entries in the `weapons` array.
int num_weapons;
/// Name of the set this item appears in. Typically used for small fruits like berries.
const char* set;
float radius;
};
struct AreaItemSet {
sead::SafeArray<AreaItem, 32> items;
/// Number of valid entries in the `items` array.
int count;
};
union StatusEffectVal {
f32 _f32;
@ -94,14 +142,14 @@ private:
virtual ~Ecosystem();
public:
void init();
void init(sead::Heap* heap);
void calc();
s32 getMapArea(const EcoMapInfo& info, f32 posX, f32 posZ) const;
s32 getFieldMapArea(f32 x, f32 z) const { return getMapArea(mFieldMapArea, x, z); }
void getActorSpawnInfo(s32 areaNum, ActorType actorTypeIdx, ActorSpawnInfo* out) const;
void getAreaItems(s32 areaNum, AreaItemType type, AreaItemSet* out) const;
void getStatusEffectInfo(StatusEffect statusEffectIdx, s32 idx, StatusEffectInfo* out) const;
void getAreaNameByNum(s32 areaNum, const char** out) const;
void getClimateNameByNum(s32 areaNum, const char** out) const;
@ -109,11 +157,14 @@ public:
void getEcoTraitsByNum(s32 areaNum, EcosystemTraits* out) const;
private:
res::Handle mFieldMapAreaFile;
res::Handle mAreaDataFile;
res::Handle mMapTowerFile;
res::Handle mStatusEffectListFile;
res::Handle mLoadBalancerFile;
struct Handles {
res::Handle mFieldMapArea;
res::Handle mAreaData;
res::Handle mMapTower;
res::Handle mStatusEffectList;
res::Handle mLoadBalancer;
};
Handles mHandles;
al::ByamlIter* mAreaDataIter{};
u32 mAreaDataSize{};