ksys/res: Add Drop

This commit is contained in:
Léo Lam 2020-09-09 18:37:59 +02:00
parent 5ab4e15967
commit 0f0c1b59ca
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
6 changed files with 275 additions and 28 deletions

View File

@ -65,6 +65,8 @@ add_executable(uking
src/KingSystem/Resource/resResourceArchive.h
src/KingSystem/Resource/resResourceDemo.cpp
src/KingSystem/Resource/resResourceDemo.h
src/KingSystem/Resource/resResourceDrop.cpp
src/KingSystem/Resource/resResourceDrop.h
src/KingSystem/Resource/resResourceLod.cpp
src/KingSystem/Resource/resResourceLod.h

View File

@ -85822,32 +85822,32 @@
0x0000007101098234,j__ZdlPv_1174,4,
0x0000007101098238,_ZN4sead15FixedSafeStringILi165EEaSERKNS_14SafeStringBaseIcEE,240,
0x0000007101098328,getDamageReactionTypes,428,
0x0000007101098648,nullsub_4469,4,
0x000000710109864c,nullsub_4470,4,
0x0000007101098650,Bdrop::parse,1684,
0x0000007101098ce4,Bdrop::parseColumns,408,
0x0000007101098e7c,ResourceBdrop::parse,28,
0x0000007101098e98,Bdrop::getRandomDropFromTable,264,
0x0000007101098fa0,Bdrop::getRandomDropFromTableByIdx,260,
0x00000071010990a4,Bdrop::findTableIndex2,588,
0x00000071010992f0,Bdrop::getApproachTypeByIdx,68,
0x0000007101099334,Bdrop::getOccurrenceSpeedTypeByIdx,68,
0x0000007101099378,Bdrop::getRepeatNum,148,
0x000000710109940c,Bdrop::getRepeatNumByIdx,140,
0x0000007101099498,Bdrop::findTableIndex,336,
0x00000071010995e8,sub_71010995E8,124,
0x0000007101099664,sub_7101099664,112,
0x00000071010996d4,sub_71010996D4,8,
0x00000071010996dc,sub_71010996DC,8,
0x00000071010996e4,sub_71010996E4,92,
0x0000007101099740,sub_7101099740,8,
0x0000007101099748,sub_7101099748,8,
0x0000007101099750,sub_7101099750,92,
0x00000071010997ac,sub_71010997AC,120,
0x0000007101099824,sub_7101099824,108,
0x0000007101099890,sub_7101099890,8,
0x0000007101099898,sub_7101099898,128,
0x0000007101099918,sub_7101099918,116,
0x0000007101098648,nullsub_4469,4,_ZN4ksys3res4Drop9doCreate_EPhjPN4sead4HeapE
0x000000710109864c,nullsub_4470,4,_ZThn632_N4ksys3res4Drop9doCreate_EPhjPN4sead4HeapE
0x0000007101098650,Bdrop::parse,1684,_ZN4ksys3res4Drop6parse_EPhmPN4sead4HeapE?
0x0000007101098ce4,Bdrop::parseColumns,408,_ZN4ksys3res4Drop11parseItems_ERi
0x0000007101098e7c,ResourceBdrop::parse,28,_ZThn632_N4ksys3res4Drop6parse_EPhmPN4sead4HeapE
0x0000007101098e98,Bdrop::getRandomDropFromTable,264,_ZNK4ksys3res4Drop22getRandomDropFromTableERKN4sead14SafeStringBaseIcEE
0x0000007101098fa0,Bdrop::getRandomDropFromTableByIdx,260,_ZNK4ksys3res4Drop22getRandomDropFromTableEi
0x00000071010990a4,Bdrop::findTableIndex2,588,_ZNK4ksys3res4Drop22findTableIndexOrNormalERKN4sead14SafeStringBaseIcEE
0x00000071010992f0,Bdrop::getApproachTypeByIdx,68,_ZNK4ksys3res4Drop15getApproachTypeEi
0x0000007101099334,Bdrop::getOccurrenceSpeedTypeByIdx,68,_ZNK4ksys3res4Drop22getOccurrenceSpeedTypeEi
0x0000007101099378,Bdrop::getRepeatNum,148,_ZNK4ksys3res4Drop12getRepeatNumERKN4sead14SafeStringBaseIcEE
0x000000710109940c,Bdrop::getRepeatNumByIdx,140,_ZNK4ksys3res4Drop12getRepeatNumEi
0x0000007101099498,Bdrop::findTableIndex,336,_ZNK4ksys3res4Drop14findTableIndexERKN4sead14SafeStringBaseIcEE
0x00000071010995e8,sub_71010995E8,124,_ZN4ksys3res4DropD2Ev
0x0000007101099664,sub_7101099664,112,_ZN4ksys3res4DropD0Ev
0x00000071010996d4,sub_71010996D4,8,_ZN4ksys3res4Drop10ParamIO_m0Ev
0x00000071010996dc,sub_71010996DC,8,_ZNK4ksys3res4Drop27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE?
0x00000071010996e4,sub_71010996E4,92,_ZNK4ksys3res4Drop18getRuntimeTypeInfoEv
0x0000007101099740,sub_7101099740,8,_ZNK4ksys3res4Drop10needsParseEv
0x0000007101099748,sub_7101099748,8,_ZThn632_NK4ksys3res4Drop27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE?
0x0000007101099750,sub_7101099750,92,_ZThn632_NK4ksys3res4Drop18getRuntimeTypeInfoEv
0x00000071010997ac,sub_71010997AC,120,_ZThn632_N4ksys3res4DropD1Ev
0x0000007101099824,sub_7101099824,108,_ZThn632_N4ksys3res4DropD0Ev
0x0000007101099890,sub_7101099890,8,_ZThn632_NK4ksys3res4Drop10needsParseEv
0x0000007101099898,sub_7101099898,128,_ZThn664_N4ksys3res4DropD1Ev
0x0000007101099918,sub_7101099918,116,_ZThn664_N4ksys3res4DropD0Ev
0x0000007101099b00,nullsub_4471,4,
0x0000007101099b04,nullsub_4472,4,
0x0000007101099b08,Blifecondition::parse,1296,

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

@ -1 +1 @@
Subproject commit 2f5bcf2d6617da25a9d60470ae4e5da8380965a1
Subproject commit 0e14378755a859ef307405d8b1c1860949990e65

@ -1 +1 @@
Subproject commit 8a00c624536738a26fc087d478db025e2752fc12
Subproject commit 9e500212341ace1ecd1d970581d4e37b858bea57

View File

@ -0,0 +1,174 @@
#include "KingSystem/Resource/resResourceDrop.h"
#include <random/seadGlobalRandom.h>
namespace ksys::res {
// NON_MATCHING: reorderings for the "テーブルの数" SafeString ctor
bool Drop::parse_(u8* data, size_t, sead::Heap* heap) {
mTableNum.init(0, "TableNum", "テーブルの数", &mObj);
addObj(&mObj, "Header");
if (!data)
return true;
applyResParameterArchive(agl::utl::ResParameterArchive{data});
const s32 num_tables = mTableNum.ref();
if (num_tables < 1)
return true;
mTables.allocBufferAssert(num_tables, heap);
const agl::utl::ResParameterArchive archive{data};
const auto root = archive.getRootList();
const auto header_obj = root.getResParameterObj(0);
for (s32 i = 0; i < num_tables; ++i) {
sead::FormatFixedSafeString<64> name;
name.format("Table%02d", i + 1);
mTables[i].name.init("", name, "テーブル名", &mObj);
}
mObj.applyResParameterObj(header_obj, nullptr);
for (s32 i = 0; i < num_tables; ++i) {
const auto obj = root.getResParameterObj(i + 1);
mTables[i].repeat_num_min.init(0, "RepeatNumMin", "抽選回数最小", &mTables[i].obj);
mTables[i].repeat_num_max.init(0, "RepeatNumMax", "抽選回数最大", &mTables[i].obj);
mTables[i].approach_type.init(0, "ApproachType", "姿勢", &mTables[i].obj);
mTables[i].occurrence_speed_type.init(0, "OccurrenceSpeedType", "発生速度",
&mTables[i].obj);
mTables[i].column_num.init(0, "ColumnNum", "行数", &mTables[i].obj);
addObj(&mTables[i].obj, mTables[i].name.ref());
applyResParameterArchive(agl::utl::ResParameterArchive{data});
mTables[i].obj.applyResParameterObj(obj, nullptr);
if (mTables[i].column_num.ref() > 0) {
mTables[i].items.allocBufferAssert(mTables[i].column_num.ref(), heap);
}
}
for (s32 i = 0; i < num_tables; ++i) {
parseItems_(i);
}
applyResParameterArchive(agl::utl::ResParameterArchive{data});
return true;
}
void Drop::parseItems_(s32& table_idx) {
const s32 num = mTables[table_idx].column_num.ref();
for (s32 i = 0; i < num; ++i) {
sead::FormatFixedSafeString<64> name;
name.format("ItemName%02d", i + 1);
mTables[table_idx].items[i].name.init("", name, "アイテム名", &mTables[table_idx].obj);
sead::FormatFixedSafeString<64> name2;
name2.format("ItemProbability%02d", i + 1);
mTables[table_idx].items[i].probability.init(0.0, name2, "確率", &mTables[table_idx].obj);
}
}
s32 Drop::findTableIndex(const sead::SafeString& table_name) const {
if (!mTables.isBufferReady())
return -1;
const s32 num = mTableNum.ref();
for (s32 i = 0; i < num; ++i) {
if (mTables[i].name.ref() == table_name)
return i;
}
return -1;
}
s32 Drop::findTableIndexOrNormal(const sead::SafeString& table_name) const {
if (!mTables.isBufferReady())
return -1;
s32 normal_idx = -1;
const s32 num = mTableNum.ref();
for (s32 i = 0; i < num; ++i) {
if (mTables[i].name.ref() == table_name)
return i;
if (normal_idx < 0 && mTables[i].name.ref() == "Normal")
normal_idx = i;
}
return normal_idx;
}
const sead::SafeString& Drop::getRandomDropFromTable(const sead::SafeString& table_name) const {
return getRandomDropFromTable(findTableIndexOrNormal(table_name));
}
const sead::SafeString& Drop::getRandomDropFromTable(s32 table_idx) const {
if (!mTables.isBufferReady())
return sead::SafeString::cEmptyString;
/// @bug The index check should be done first...
if (!mTables[table_idx].items.isBufferReady() || table_idx < 0)
return sead::SafeString::cEmptyString;
f32 x = sead::GlobalRandom::instance()->getF32() * 100.0;
const Table& table = mTables[table_idx];
const s32 num_items = table.column_num.ref();
for (s32 i = 0; i < num_items; ++i) {
const Item& item = table.items[i];
const f32 probability = item.probability.ref();
if (x < probability)
return item.name.ref();
x -= probability;
}
return sead::SafeString::cEmptyString;
}
s32 Drop::getApproachType(s32 table_idx) const {
if (!mTables.isBufferReady())
return 0;
/// @bug This bounds checking is bugged: the order is absurd and the second check is off-by-one.
if (!mTables[table_idx].items.isBufferReady() || table_idx < 0 || table_idx > mTables.size())
return 0;
return mTables[table_idx].approach_type.ref();
}
s32 Drop::getOccurrenceSpeedType(s32 table_idx) const {
if (!mTables.isBufferReady())
return 0;
/// @bug This bounds checking is bugged: the order is absurd and the second check is off-by-one.
if (!mTables[table_idx].items.isBufferReady() || table_idx < 0 || table_idx > mTables.size())
return 0;
return mTables[table_idx].occurrence_speed_type.ref();
}
s32 Drop::getRepeatNum(s32 table_idx) const {
if (!mTables.isBufferReady())
return 0;
const Table& table = mTables[table_idx];
if (!mTables[table_idx].items.isBufferReady() || table_idx < 0 || table_idx > mTables.size())
return 0;
const s32 num_min = table.repeat_num_min.ref();
const s32 num_max = table.repeat_num_max.ref();
if (num_min == num_max)
return num_min;
return num_min + sead::GlobalRandom::instance()->getU32(1 - num_min + num_max);
}
s32 Drop::getRepeatNum(const sead::SafeString& table_name) const {
return getRepeatNum(findTableIndexOrNormal(table_name));
}
} // namespace ksys::res

View File

@ -0,0 +1,71 @@
#pragma once
#include <agl/Utils/aglParameter.h>
#include <agl/Utils/aglParameterObj.h>
#include <container/seadBuffer.h>
#include "KingSystem/Resource/resResource.h"
#include "KingSystem/Utils/ParamIO.h"
#include "KingSystem/Utils/Types.h"
namespace ksys::res {
class Drop : public ParamIO, public Resource {
SEAD_RTTI_OVERRIDE(Drop, Resource)
public:
Drop() : ParamIO("drop", 0) {}
/// Returns the name of a randomly chosen drop from the specified table or from the Normal table
/// if the table cannot be found.
/// The empty string is returned if no drop was chosen.
const sead::SafeString& getRandomDropFromTable(const sead::SafeString& table_name) const;
/// Returns the name of a randomly chosen drop from the specified table.
/// The empty string is returned if no drop was chosen.
const sead::SafeString& getRandomDropFromTable(s32 table_idx) const;
/// Returns the index of the specified table. If the table cannot be found, the index of the
/// first Normal table is returned. Note that it may be equal to -1 if there is no Normal table.
s32 findTableIndexOrNormal(const sead::SafeString& table_name) const;
/// Returns the index of the specified table or -1 if it cannot be found.
s32 findTableIndex(const sead::SafeString& table_name) const;
s32 getApproachType(s32 table_idx) const;
s32 getOccurrenceSpeedType(s32 table_idx) const;
s32 getRepeatNum(s32 table_idx) const;
s32 getRepeatNum(const sead::SafeString& table_name) const;
bool ParamIO_m0() override { return true; }
void doCreate_(u8*, u32, sead::Heap*) override {}
bool needsParse() const override { return true; }
private:
struct Item {
agl::utl::Parameter<sead::SafeString> name;
agl::utl::Parameter<f32> probability;
};
KSYS_CHECK_SIZE_NX150(Item, 0x48);
struct Table {
agl::utl::ParameterObj obj;
agl::utl::Parameter<sead::SafeString> name;
agl::utl::Parameter<s32> repeat_num_min;
agl::utl::Parameter<s32> repeat_num_max;
agl::utl::Parameter<s32> approach_type;
agl::utl::Parameter<s32> occurrence_speed_type;
agl::utl::Parameter<s32> column_num;
sead::Buffer<Item> items;
};
KSYS_CHECK_SIZE_NX150(Table, 0x108);
bool parse_(u8* data, size_t size, sead::Heap* heap) override;
void parseItems_(s32& table_idx);
agl::utl::ParameterObj mObj;
agl::utl::Parameter<s32> mTableNum;
sead::Buffer<void*> _300;
sead::Buffer<Table> mTables;
};
KSYS_CHECK_SIZE_NX150(Drop, 0x320);
} // namespace ksys::res