mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-04-23 09:04:21 +00:00
2528 lines
88 KiB
C++
2528 lines
88 KiB
C++
#include "System/GameDataFunction.h"
|
|
|
|
#include <g3d/aglNW4FToNN.h>
|
|
|
|
#include "Library/Area/AreaObj.h"
|
|
#include "Library/Area/AreaObjUtil.h"
|
|
#include "Library/Base/Macros.h"
|
|
#include "Library/Layout/LayoutActor.h"
|
|
#include "Library/LiveActor/ActorPoseUtil.h"
|
|
#include "Library/Math/MathUtil.h"
|
|
#include "Library/Message/MessageHolder.h"
|
|
#include "Library/Placement/PlacementFunction.h"
|
|
#include "Library/Placement/PlacementId.h"
|
|
#include "Library/Placement/PlacementInfo.h"
|
|
#include "Library/Resource/ResourceFunction.h"
|
|
#include "Library/Scene/Scene.h"
|
|
#include "Library/Scene/SceneObjHolder.h"
|
|
#include "Library/Scene/SceneObjUtil.h"
|
|
#include "Library/Yaml/ByamlUtil.h"
|
|
|
|
#include "Camera/ScenarioStartCamera.h"
|
|
#include "Item/Shine.h"
|
|
#include "Item/ShineInfo.h"
|
|
#include "Layout/ShopLayoutInfo.h"
|
|
#include "MapObj/RiseMapPartsHolder.h"
|
|
#include "Npc/WorldTravelingNpc.h"
|
|
#include "Player/PlayerFunction.h"
|
|
#include "Scene/QuestInfo.h"
|
|
#include "Scene/QuestInfoHolder.h"
|
|
#include "Scene/TemporaryScenarioCameraHolder.h"
|
|
#include "Sequence/ChangeStageInfo.h"
|
|
#include "System/GameDataUtil.h"
|
|
#include "System/GameProgressData.h"
|
|
#include "System/MapDataHolder.h"
|
|
#include "System/MoonRockData.h"
|
|
#include "System/PlayerHitPointData.h"
|
|
#include "System/WorldList.h"
|
|
#include "Util/ClothUtil.h"
|
|
#include "Util/ScenePrepoFunction.h"
|
|
#include "Util/SpecialBuildUtil.h"
|
|
#include "Util/StageLayoutFunction.h"
|
|
|
|
namespace GameDataFunction {
|
|
|
|
GameDataHolder* getGameDataHolder(const al::IUseSceneObjHolder* scene_obj_holder) {
|
|
return al::getSceneObj<GameDataHolder>(scene_obj_holder);
|
|
}
|
|
|
|
GameDataHolder* getGameDataHolder(const al::SceneObjHolder* scene_obj_holder) {
|
|
return scene_obj_holder->getObj<GameDataHolder>();
|
|
}
|
|
|
|
GameDataHolder* getGameDataHolder(al::GameDataHolderBase* game_data_holder) {
|
|
return static_cast<GameDataHolder*>(game_data_holder);
|
|
}
|
|
|
|
GameDataFile* getGameDataFile(GameDataHolderWriter writer) {
|
|
return writer->getGameDataFile();
|
|
}
|
|
|
|
void setPlayingFileId(GameDataHolderWriter writer, s32 file_id) {
|
|
writer->setPlayingFileId(file_id);
|
|
}
|
|
|
|
void initializeData(GameDataHolderWriter writer, s32 file_id) {
|
|
writer->initializeDataId(file_id);
|
|
}
|
|
|
|
bool isPlayDemoOpening(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isPlayDemoOpening();
|
|
}
|
|
|
|
bool isGameClear(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isGameClear();
|
|
}
|
|
|
|
void setRequireSave(GameDataHolderWriter writer) {
|
|
writer->setRequireSave();
|
|
}
|
|
|
|
void setRequireSaveFrame(GameDataHolderWriter writer) {
|
|
writer->setRequireSaveFrame();
|
|
}
|
|
|
|
s64 getPlayTimeTotal(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getPlayTimeTotal();
|
|
}
|
|
|
|
s64 getPlayTimeAcrossFile(GameDataHolderAccessor accessor) {
|
|
return accessor->getPlayTimeAcrossFile();
|
|
}
|
|
|
|
s64 getSaveDataIdForPrepo(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getSaveDataIdForPrepo();
|
|
}
|
|
|
|
void startDemoStage(GameDataHolderWriter writer, const char* stage_name) {
|
|
writer->getGameDataFile()->startDemoStage(stage_name);
|
|
}
|
|
|
|
bool tryChangeNextStage(GameDataHolderWriter writer, const ChangeStageInfo* info) {
|
|
if (info->isEmpty())
|
|
return false;
|
|
writer->changeNextStage(info);
|
|
return true;
|
|
}
|
|
|
|
bool tryChangeNextStageWithStartRaceFlag(GameDataHolderWriter writer, const ChangeStageInfo* info) {
|
|
if (info->isEmpty())
|
|
return false;
|
|
writer->changeNextStage(info, GameDataFile::RaceType_Flag);
|
|
return true;
|
|
}
|
|
|
|
bool tryChangeNextStageWithStartRaceYukimaru(GameDataHolderWriter writer,
|
|
const ChangeStageInfo* info) {
|
|
if (info->isEmpty())
|
|
return false;
|
|
writer->changeNextStage(info, GameDataFile::RaceType_Yukimaru);
|
|
return true;
|
|
}
|
|
|
|
bool tryChangeNextStageWithDemoWorldWarp(GameDataHolderWriter writer, const char* stage_name) {
|
|
writer->changeNextStageWithDemoWorldWarp(stage_name);
|
|
return true;
|
|
}
|
|
|
|
bool tryChangeNextStageWithWorldWarpHole(GameDataHolderWriter writer, const char* stage_name) {
|
|
return writer->tryChangeNextStageWithWorldWarpHole(stage_name);
|
|
}
|
|
|
|
void changeNextStageWithStartTimeBalloon(GameDataHolderWriter writer, s32 scenario_no) {
|
|
ChangeStageInfo info{writer, "TimeBalloonStart", getCurrentStageName(writer),
|
|
false, scenario_no, ChangeStageInfo::RESET_MINI_GAME1};
|
|
writer->changeNextStage(&info);
|
|
}
|
|
|
|
const char* getCurrentStageName(GameDataHolderAccessor accessor) {
|
|
return accessor->getCurrentStageName();
|
|
}
|
|
|
|
void changeNextStageWithEndTimeBalloon(GameDataHolderWriter writer) {
|
|
ChangeStageInfo info{writer, "TimeBalloonStart", getCurrentStageName(writer)};
|
|
writer->changeNextStage(&info);
|
|
}
|
|
|
|
void changeNextStageWithCloset(GameDataHolderWriter writer) {
|
|
ChangeStageInfo info{writer, "ClosetStart", getCurrentStageName(writer)};
|
|
writer->changeNextStage(&info);
|
|
}
|
|
|
|
void findAreaAndChangeNextStage(GameDataHolderWriter writer, const al::LiveActor* actor,
|
|
const sead::Vector3f* pos_override) {
|
|
if (writer->getGameDataFile()->get_a2c() &&
|
|
writer->getGameDataFile()->getChangeStageInfo()->getSubScenarioType() !=
|
|
ChangeStageInfo::DEFAULT_SUB_SCENARIO)
|
|
return;
|
|
sead::Vector3f pos = al::getTrans(actor);
|
|
if (pos_override)
|
|
pos.set(*pos_override);
|
|
al::AreaObj* area = al::tryFindAreaObj(actor, "ChangeStageArea", pos);
|
|
ChangeStageInfo info{writer, *area->getPlacementInfo()};
|
|
tryChangeNextStage(writer, &info);
|
|
}
|
|
|
|
void returnPrevStage(GameDataHolderWriter writer) {
|
|
writer->returnPrevStage();
|
|
}
|
|
|
|
bool isTimeBalloonSequence(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getChangeStageInfo()->getSubScenarioType() ==
|
|
ChangeStageInfo::RESET_MINI_GAME1;
|
|
}
|
|
|
|
const char* getNextStageName(GameDataHolderAccessor accessor) {
|
|
return accessor->getNextStageName();
|
|
}
|
|
|
|
const char* getCurrentStageName(GameDataHolderAccessor accessor, s32 file_id) {
|
|
return accessor->getCurrentStageName(file_id);
|
|
}
|
|
|
|
static bool isSeaOfTreeStage(const char* stage_name) {
|
|
return al::isEqualString(stage_name, "ForestWorldWoodsStage") ||
|
|
al::isEqualString(stage_name, "ForestWorldWoodsCostumeStage") ||
|
|
al::isEqualString(stage_name, "ForestWorldWoodsTreasureStage");
|
|
}
|
|
|
|
bool isSeaOfTreeStage(GameDataHolderAccessor accessor) {
|
|
return isSeaOfTreeStage(getCurrentStageName(accessor));
|
|
}
|
|
|
|
const char* getNextStageName(GameDataHolderAccessor accessor, s32 file_id) {
|
|
return accessor->getNextStageName(file_id);
|
|
}
|
|
|
|
s32 calcNextScenarioNo(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->calcNextScenarioNo();
|
|
}
|
|
|
|
void restartStage(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->restartStage();
|
|
}
|
|
|
|
void missAndRestartStage(GameDataHolderWriter writer) {
|
|
writer->validateCheckpointWarp();
|
|
writer->enableExplainAmiibo();
|
|
writer->getGameDataFile()->missAndRestartStage();
|
|
}
|
|
|
|
bool isMissEndPrevStageForInit(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isMissEndPrevStage();
|
|
}
|
|
|
|
bool isMissEndPrevStageForSceneDead(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isMissEndPrevStage();
|
|
}
|
|
|
|
void reenterStage(GameDataHolderWriter writer) {
|
|
writer->setStageEnding();
|
|
}
|
|
|
|
s32 getNextWorldId(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getNextWorldId();
|
|
}
|
|
|
|
s32 getPrevWorldId(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getPrevWorldId();
|
|
}
|
|
|
|
s32 getWorldNumForNewReleaseShop(GameDataHolderAccessor accessor) {
|
|
const GameProgressData* game_progress_data = accessor->getGameDataFile()->getGameProgressData();
|
|
s32 unlock_world_num = game_progress_data->getUnlockWorldNum();
|
|
s32 count = 0;
|
|
for (s32 i = 0; i < unlock_world_num; i++) {
|
|
s32 world_id = game_progress_data->getWorldIdForWorldWarpHole(i);
|
|
if (!isAlreadyGoWorld(accessor, world_id))
|
|
continue;
|
|
const char* world_name = getWorldDevelopName(accessor, world_id);
|
|
const sead::PtrArray<sead::FixedSafeString<64>>& list =
|
|
accessor->getWorldsForNewReleaseShop();
|
|
for (s32 j = 0; j < list.size(); j++) {
|
|
if (al::isEqualString(world_name, list[j]->cstr())) {
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
// TODO: check what's happening here
|
|
static s32 blackBox(s32 value) {
|
|
__asm__("" : "+r"(value));
|
|
return value;
|
|
}
|
|
|
|
template <typename F>
|
|
static s32 search(s32 count, F fn) {
|
|
for (s32 i = 0; i < count; i++) {
|
|
s32 status = fn(i);
|
|
if ((blackBox(status | 4) & 7) != 4)
|
|
return status;
|
|
}
|
|
return 2;
|
|
}
|
|
|
|
s32 getWorldIdForNewReleaseShop(GameDataHolderAccessor accessor, s32 index) {
|
|
const GameProgressData* game_progress_data = accessor->getGameDataFile()->getGameProgressData();
|
|
s32 result;
|
|
s32 status = search(game_progress_data->getUnlockWorldNum(), [&](s32 i) {
|
|
s32 world_id = game_progress_data->getWorldIdForWorldWarpHole(i);
|
|
if (!isAlreadyGoWorld(accessor, world_id))
|
|
return 4;
|
|
const char* world_name = getWorldDevelopName(accessor, world_id);
|
|
const sead::PtrArray<sead::FixedSafeString<64>>& list =
|
|
accessor->getWorldsForNewReleaseShop();
|
|
for (s32 j = 0; j < list.size(); j++) {
|
|
if (al::isEqualString(world_name, list[j]->cstr())) {
|
|
if (index == 0) {
|
|
result = world_id;
|
|
return 1;
|
|
} else {
|
|
index--;
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
});
|
|
return status == 2 ? 0 : result;
|
|
}
|
|
|
|
bool isForwardWorldWarpDemo(GameDataHolderAccessor accessor) {
|
|
s32 prev_world_id = getPrevWorldId(accessor);
|
|
s32 next_world_id = getNextWorldId(accessor);
|
|
s32 world_num = getWorldNum(accessor);
|
|
s32 next_world_id_for_demo = -1;
|
|
s32 prev_world_id_for_demo = -1;
|
|
for (s32 i = 0; i < world_num; i++) {
|
|
s32 world_id = accessor->getGameDataFile()->getGameProgressData()->getWorldIdForWorldMap(i);
|
|
if (world_id == prev_world_id)
|
|
prev_world_id_for_demo = i;
|
|
if (world_id == next_world_id)
|
|
next_world_id_for_demo = i;
|
|
}
|
|
if (prev_world_id_for_demo == -1)
|
|
prev_world_id_for_demo = prev_world_id;
|
|
if (next_world_id_for_demo == -1)
|
|
next_world_id_for_demo = next_world_id;
|
|
return prev_world_id_for_demo <= next_world_id_for_demo;
|
|
}
|
|
|
|
s32 getWorldNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getWorldList()->getWorldNum();
|
|
}
|
|
|
|
bool isFirstTimeNextWorld(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isFirstTimeNextWorld();
|
|
}
|
|
|
|
bool checkIsNewWorldInAlreadyGoWorld(GameDataHolderAccessor accessor) {
|
|
s32 world_id = getCurrentWorldIdNoDevelop(accessor);
|
|
if (!isAlreadyGoWorld(accessor, world_id))
|
|
return false;
|
|
const GameProgressData* game_progress_data = accessor->getGameDataFile()->getGameProgressData();
|
|
bool is_after_current_world = false;
|
|
for (s32 i = 0; i < game_progress_data->getUnlockWorldNum(); i++) {
|
|
if (!is_after_current_world) {
|
|
if (game_progress_data->getWorldIdForWorldWarpHole(i) == world_id)
|
|
is_after_current_world = true;
|
|
continue;
|
|
}
|
|
if (accessor->getGameDataFile()->isAlreadyGoWorld(
|
|
game_progress_data->getWorldIdForWorldWarpHole(i)))
|
|
return false;
|
|
}
|
|
return is_after_current_world;
|
|
}
|
|
|
|
static s32 getScenarioNoImpl(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getScenarioNo();
|
|
}
|
|
|
|
s32 getScenarioNo(const al::LiveActor* actor) {
|
|
return getScenarioNoImpl(actor);
|
|
}
|
|
|
|
s32 getScenarioNo(const al::LayoutActor* layout) {
|
|
return getScenarioNoImpl(layout);
|
|
}
|
|
|
|
s32 getScenarioNoPlacement(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getScenarioNoPlacement();
|
|
}
|
|
|
|
bool isEqualScenario(const RiseMapPartsHolder* actor, s32 scenario_no) {
|
|
return getScenarioNo(actor) == scenario_no;
|
|
}
|
|
|
|
s32 getMainQuestMin(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getWorldList()->getMainQuestMin(getCurrentWorldId(actor),
|
|
getScenarioNoImpl(actor));
|
|
}
|
|
|
|
s32 getCurrentWorldId(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getCurrentWorldId();
|
|
}
|
|
|
|
s32 getCurrentWorldIdNoDevelop(GameDataHolderAccessor accessor) {
|
|
return sead::Mathi::clampMin(getCurrentWorldId(accessor), 0);
|
|
}
|
|
|
|
void clearStartId(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->clearStartId();
|
|
}
|
|
|
|
void setCheckpointId(GameDataHolderWriter writer, const al::PlacementId* placement_id) {
|
|
writer->setCheckpointId(placement_id);
|
|
}
|
|
|
|
void setRestartPointId(GameDataHolderWriter writer, const al::PlacementId* placement_id) {
|
|
writer->getGameDataFile()->setRestartPointId(placement_id);
|
|
}
|
|
|
|
const char* tryGetRestartPointIdString(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->tryGetRestartPointIdString();
|
|
}
|
|
|
|
const char* tryGetPlayerStartId(GameDataHolderAccessor accessor) {
|
|
return accessor->getNextPlayerStartId();
|
|
}
|
|
|
|
bool isPlayerStartObj(const al::LiveActor* actor, const al::ActorInitInfo& info) {
|
|
return isPlayerStartObj(actor, *info.placementInfo);
|
|
}
|
|
|
|
bool isPlayerStartObj(const al::LiveActor* actor, const al::PlacementInfo& placement_info) {
|
|
const char* str = tryGetPlayerStartId(actor);
|
|
if (!str)
|
|
return false;
|
|
const char* start_id = nullptr;
|
|
bool has_start_id = al::tryGetStringArg(&start_id, placement_info, "ChangeStageId");
|
|
return start_id && has_start_id && al::isEqualString(str, start_id);
|
|
}
|
|
|
|
bool isPlayerStartObj(const al::LiveActor* actor, const char* start_id) {
|
|
const char* str = tryGetPlayerStartId(actor);
|
|
return str && al::isEqualString(str, start_id);
|
|
}
|
|
|
|
bool isPlayerStartLinkedObj(const al::LiveActor* actor, const al::ActorInitInfo& info,
|
|
const char* link_name) {
|
|
s32 link_num = al::calcLinkChildNum(info, link_name);
|
|
for (s32 i = 0; i < link_num; i++) {
|
|
al::PlacementInfo placement_info;
|
|
al::getLinksInfoByIndex(&placement_info, info, link_name, i);
|
|
if (isPlayerStartObj(actor, placement_info))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void setStartShine(const al::LiveActor* actor, const ShineInfo* info) {
|
|
getGameDataHolder(actor)->getGameDataFile()->setStartShine(info);
|
|
}
|
|
|
|
s32 getStartShineNextIndex(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getStartShineNextIndex();
|
|
}
|
|
|
|
bool isAlreadyShowExplainCheckpointFlag(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isAlreadyShowExplainCheckpointFlag();
|
|
}
|
|
|
|
bool isEnableShowExplainCheckpointFlag(GameDataHolderAccessor accessor) {
|
|
return true;
|
|
}
|
|
|
|
void showExplainCheckpointFlag(GameDataHolderAccessor accessor) {
|
|
accessor->getGameDataFile()->showExplainCheckpointFlag();
|
|
}
|
|
|
|
void getLifeMaxUpItem(const al::LiveActor* actor) {
|
|
if (PlayerFunction::isPlayerDeadStatus(actor))
|
|
return;
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->getPlayerHitPointData()->getMaxUpItem();
|
|
}
|
|
|
|
s32 getPlayerHitPoint(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getPlayerHitPointData()->getCurrent();
|
|
}
|
|
|
|
s32 getPlayerHitPointMaxCurrent(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getPlayerHitPointData()->getMaxCurrent();
|
|
}
|
|
|
|
s32 getPlayerHitPointMaxNormal(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getPlayerHitPointData()->getMaxWithoutItem();
|
|
}
|
|
|
|
bool isPlayerHitPointMax(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getPlayerHitPointData()->isMaxCurrent();
|
|
}
|
|
|
|
bool isPlayerHitPointMaxWithItem(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getPlayerHitPointData()->isMaxWithItem();
|
|
}
|
|
|
|
void recoveryPlayer(const al::LiveActor* actor) {
|
|
if (PlayerFunction::isPlayerDeadStatus(actor))
|
|
return;
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->getPlayerHitPointData()->recover();
|
|
}
|
|
|
|
void recoveryPlayerForDebug(const al::LiveActor* actor) {
|
|
if (PlayerFunction::isPlayerDeadStatus(actor))
|
|
return;
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->getPlayerHitPointData()->recoverForDebug();
|
|
}
|
|
|
|
void recoveryPlayerMax(const al::LiveActor* actor) {
|
|
if (PlayerFunction::isPlayerDeadStatus(actor))
|
|
return;
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->getPlayerHitPointData()->recoverMax();
|
|
}
|
|
|
|
void recoveryPlayerForSystem(const GameDataHolder* game_data_holder) {
|
|
game_data_holder->getGameDataFile()->getPlayerHitPointData()->recover();
|
|
}
|
|
|
|
void recoveryPlayerMaxForSystem(const GameDataHolder* game_data_holder) {
|
|
game_data_holder->getGameDataFile()->getPlayerHitPointData()->recoverMax();
|
|
}
|
|
|
|
void initPlayerHitPointForSystem(const GameDataHolder* game_data_holder) {
|
|
game_data_holder->getGameDataFile()->getPlayerHitPointData()->init();
|
|
}
|
|
|
|
void damagePlayer(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->getPlayerHitPointData()->damage();
|
|
}
|
|
|
|
void killPlayer(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->getPlayerHitPointData()->kill();
|
|
}
|
|
|
|
bool isPlayerLifeZero(GameDataHolderAccessor accessor) {
|
|
return getPlayerHitPoint(accessor) <= 0;
|
|
}
|
|
|
|
bool isGotShine(GameDataHolderAccessor accessor, const ShineInfo* info) {
|
|
return accessor->getGameDataFile()->isGotShine(info);
|
|
}
|
|
|
|
bool isGotShine(GameDataHolderAccessor accessor, const al::PlacementId* placement_id) {
|
|
ShineInfo shine_info;
|
|
shine_info.init(getCurrentStageName(accessor), al::makeStringPlacementId(placement_id).cstr(),
|
|
nullptr, nullptr, ShineInfo::Type_Shine);
|
|
return isGotShine(accessor, &shine_info);
|
|
}
|
|
|
|
bool isGotShine(GameDataHolderAccessor accessor, const char* stage_name, const char* obj_id) {
|
|
ShineInfo shine_info;
|
|
shine_info.init(stage_name, obj_id, nullptr, nullptr, ShineInfo::Type_Shine);
|
|
return isGotShine(accessor, &shine_info);
|
|
}
|
|
|
|
bool isGotShine(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->isGotShine(index);
|
|
}
|
|
|
|
bool isGotShine(const Shine* shine) {
|
|
return shine->isGot();
|
|
}
|
|
|
|
void setGotShine(GameDataHolderWriter writer, const ShineInfo* info) {
|
|
writer->getGameDataFile()->setGotShine(info);
|
|
}
|
|
|
|
s32 getGotShineNum(GameDataHolderAccessor accessor, s32 file_id) {
|
|
return file_id == -1 ? accessor->getGameDataFile()->getShineNum() :
|
|
accessor->getGameDataFile(file_id)->getShineNum();
|
|
}
|
|
|
|
const ShineInfo* getLatestGetShineInfo(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getLatestGetShineInfo();
|
|
}
|
|
|
|
s32 getCurrentShineNum(GameDataHolderAccessor accessor) {
|
|
if (isGameClear(accessor)) {
|
|
s32 world_num = getWorldNum(accessor);
|
|
s32 count = 0;
|
|
for (s32 i = 0; i < world_num; i++)
|
|
count += sead::Mathi::clampMin(accessor->getGameDataFile()->getShineNum(i) -
|
|
accessor->getGameDataFile()->getPayShineNum(i),
|
|
0);
|
|
return count;
|
|
}
|
|
return sead::Mathi::clampMin(accessor->getGameDataFile()->getShineNum() -
|
|
accessor->getGameDataFile()->getPayShineNum(),
|
|
0);
|
|
}
|
|
|
|
s32 getTotalShineNum(GameDataHolderAccessor accessor, s32 file_id) {
|
|
return file_id == -1 ? accessor->getGameDataFile()->getTotalShineNum() :
|
|
accessor->getGameDataFile(file_id)->getTotalShineNum();
|
|
}
|
|
|
|
s32 getTotalShopShineNum(GameDataHolderAccessor accessor, s32 file_id) {
|
|
return file_id == -1 ? accessor->getGameDataFile()->getTotalShopShineNum() :
|
|
accessor->getGameDataFile(file_id)->getTotalShopShineNum();
|
|
}
|
|
|
|
bool tryGetNextMainScenarioLabel(sead::BufferedSafeString* out_label,
|
|
sead::BufferedSafeString* out_stage_name,
|
|
const al::IUseSceneObjHolder* scene_obj_holder) {
|
|
GameDataHolderAccessor accessor{scene_obj_holder};
|
|
return accessor->getGameDataFile()->tryGetNextMainScenarioLabel(out_label, out_stage_name);
|
|
}
|
|
|
|
s32 getMainScenarioNumMax(GameDataHolderAccessor accessor) {
|
|
return 10;
|
|
}
|
|
|
|
void setMainScenarioNo(GameDataHolderWriter writer, s32 scenario_no) {
|
|
writer->getGameDataFile()->setMainScenarioNo(scenario_no);
|
|
}
|
|
|
|
bool tryGetNextMainScenarioPos(sead::Vector3f* out, GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->tryGetNextMainScenarioPos(out);
|
|
}
|
|
|
|
bool isPlayScenarioCamera(GameDataHolderAccessor accessor, const QuestInfo* info) {
|
|
return accessor->getGameDataFile()->isPlayScenarioCamera(info);
|
|
}
|
|
|
|
bool isPlayAlreadyScenarioStartCamera(GameDataHolderAccessor accessor, s32 quest_no) {
|
|
return accessor->isPlayAlreadyScenarioStartCamera(quest_no);
|
|
}
|
|
|
|
bool isEnterStageFirst(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isEnterStageFirst();
|
|
}
|
|
|
|
bool isNextMainShine(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->isNextMainShine(index);
|
|
}
|
|
|
|
bool isMainShine(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->isMainShine(index);
|
|
}
|
|
|
|
bool isLatestGetMainShine(GameDataHolderAccessor accessor, const ShineInfo* info) {
|
|
return accessor->getGameDataFile()->isLatestGetMainShine(info);
|
|
}
|
|
|
|
s32 tryFindLinkedShineIndex(const al::LiveActor* actor, const al::ActorInitInfo& info) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->tryFindLinkedShineIndex(info, actor);
|
|
}
|
|
|
|
s32 tryFindLinkedShineIndex(const al::LiveActor* actor, const al::ActorInitInfo& info,
|
|
s32 link_index) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->tryFindLinkedShineIndex(info, link_index, actor);
|
|
}
|
|
|
|
s32 tryFindLinkedShineIndexByLinkName(const al::LiveActor* actor, const al::ActorInitInfo& info,
|
|
const char* link_name) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->tryFindLinkedShineIndexByLinkName(actor, info, link_name);
|
|
}
|
|
|
|
s32 calcLinkedShineNum(const al::LiveActor* actor, const al::ActorInitInfo& info) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->calcLinkedShineNum(info);
|
|
}
|
|
|
|
s32 tryFindShineIndex(const al::LiveActor* actor, const al::ActorInitInfo& info) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->tryFindShineIndex(info);
|
|
}
|
|
|
|
s32 tryFindShineIndex(const al::LiveActor* actor, const char* stage_name, const char* obj_id) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->tryFindShineIndex(stage_name, obj_id);
|
|
}
|
|
|
|
s32 tryFindShineUniqueId(const al::Scene* scene, const ShineInfo* shine_info) {
|
|
GameDataHolderAccessor accessor{scene};
|
|
return accessor->getGameDataFile()->tryFindUniqueId(shine_info);
|
|
}
|
|
|
|
void disableHintByShineIndex(const al::LiveActor* actor, s32 index) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->disableHintById(index);
|
|
}
|
|
|
|
void enableHintByShineIndex(const al::LiveActor* actor, s32 index) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->enableHintById(index);
|
|
}
|
|
|
|
bool calcIsGetMainShineAll(const al::IUseSceneObjHolder* scene_obj_holder) {
|
|
GameDataHolderAccessor accessor{scene_obj_holder};
|
|
return accessor->getGameDataFile()->calcIsGetMainShineAll(scene_obj_holder);
|
|
}
|
|
|
|
bool calcIsGetShineAllInWorld(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getGameDataFile()->calcIsGetShineAllInWorld(world_id);
|
|
}
|
|
|
|
bool calcIsGetShineAllInAllWorld(GameDataHolderAccessor accessor) {
|
|
for (s32 i = 0; i < getWorldNum(accessor); i++)
|
|
if (!calcIsGetShineAllInWorld(accessor, i))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
bool tryFindAndInitShineInfoByOptionalId(ShineInfo* info, GameDataHolderAccessor accessor,
|
|
const char* optional_id) {
|
|
return accessor->getGameDataFile()->tryFindAndInitShineInfoByOptionalId(info, optional_id);
|
|
}
|
|
|
|
namespace {
|
|
|
|
class SceneObjAccessor : public al::IUseSceneObjHolder {
|
|
public:
|
|
SceneObjAccessor(al::SceneObjHolder* scene_obj_holder) : mSceneObjHolder(scene_obj_holder) {}
|
|
|
|
al::SceneObjHolder* getSceneObjHolder() const override { return mSceneObjHolder; }
|
|
|
|
private:
|
|
al::SceneObjHolder* mSceneObjHolder;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
bool isGotLinkedShineBeforeInitActor(const al::ActorInitInfo& actor_info, const char* link_name) {
|
|
SceneObjAccessor scene_obj_accessor{actor_info.actorSceneInfo.sceneObjHolder};
|
|
GameDataHolderAccessor accessor{&scene_obj_accessor};
|
|
return accessor->getGameDataFile()->isGotShine(
|
|
accessor->getGameDataFile()->tryFindLinkedShineIndexByLinkName(&scene_obj_accessor,
|
|
actor_info, link_name));
|
|
}
|
|
|
|
bool checkIsComplete(const al::IUseSceneObjHolder* scene_obj_holder, s32 file_id) {
|
|
const GameDataFile* game_data_file =
|
|
getGameDataHolder(scene_obj_holder)->getGameDataFile(file_id);
|
|
for (s32 i = 0; i < getWorldNum(scene_obj_holder); i++)
|
|
if (!game_data_file->calcIsGetShineAllInWorld(i))
|
|
return false;
|
|
|
|
al::Resource* resource = al::findOrCreateResource("SystemData/HackObjList", nullptr);
|
|
al::ByamlIter iter{al::findResourceYaml(resource, "HackObjList", nullptr)};
|
|
s32 hack_obj_count = iter.getSize();
|
|
for (s32 i = 0; i < hack_obj_count; i++) {
|
|
al::ByamlIter subiter;
|
|
iter.tryGetIterByIndex(&subiter, i);
|
|
if (al::tryGetByamlKeyBoolOrFalse(subiter, "IsDebug"))
|
|
continue;
|
|
const char* hack_name = al::getByamlKeyString(subiter, "HackName");
|
|
if (!isExistInHackDictionary(scene_obj_holder, hack_name, file_id))
|
|
return false;
|
|
}
|
|
|
|
if (!rs::isCompleteCloth(scene_obj_holder, file_id) ||
|
|
!rs::isCompleteCap(scene_obj_holder, file_id) ||
|
|
!rs::checkCompleteGift(scene_obj_holder, file_id) ||
|
|
!rs::checkCompleteSticker(scene_obj_holder, file_id))
|
|
return false;
|
|
|
|
if (getCollectedBgmNum(scene_obj_holder, file_id) != getCollectedBgmMaxNum(scene_obj_holder))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool isEnableOpenMoonRock(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->isEnableOpenMoonRock(getCurrentWorldIdNoDevelop(actor));
|
|
}
|
|
|
|
void openMoonRock(const al::LiveActor* actor, const al::PlacementId*) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->unlockHintAddByMoonRock();
|
|
}
|
|
|
|
bool isOpenMoonRock(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isOpenMoonRock(getCurrentWorldIdNoDevelop(accessor));
|
|
}
|
|
|
|
bool isEnableShowDemoOpenMoonRockFirst(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getMoonRockData()->isEnableShowDemoOpenMoonRockFirst();
|
|
}
|
|
|
|
bool isEnableShowDemoOpenMoonRockWorld(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getMoonRockData()->isEnableShowDemoOpenMoonRockWorld(
|
|
getCurrentWorldIdNoDevelop(accessor));
|
|
}
|
|
|
|
void showDemoOpenMoonRockFirst(GameDataHolderAccessor accessor) {
|
|
accessor->getGameDataFile()->getMoonRockData()->showDemoOpenMoonRockFirst();
|
|
}
|
|
|
|
void showDemoOpenMoonRockWorld(GameDataHolderAccessor accessor) {
|
|
accessor->getGameDataFile()->getMoonRockData()->showDemoOpenMoonRockWorld(
|
|
getCurrentWorldIdNoDevelop(accessor));
|
|
}
|
|
|
|
s32 calcMoonRockTalkMessageIndex(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getMoonRockData()->calcMoonRockTalkMessageIndex();
|
|
}
|
|
|
|
void addMoonRockTalkMessageIndex(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->getMoonRockData()->addMoonRockTalkMessageIndex(
|
|
getCurrentWorldId(writer));
|
|
}
|
|
|
|
bool isAppearedMoonRockTalkMessage(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getMoonRockData()->isAppearedMoonRockTalkMessage(
|
|
getCurrentWorldId(accessor));
|
|
}
|
|
|
|
void addPayShine(GameDataHolderWriter writer, s32 count) {
|
|
writer->getGameDataFile()->addPayShine(count);
|
|
}
|
|
|
|
void addPayShineCurrentAll(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->addPayShineCurrentAll();
|
|
}
|
|
|
|
s32 getPayShineNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getPayShineNum();
|
|
}
|
|
|
|
s32 getPayShineNum(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getGameDataFile()->getPayShineNum(world_id);
|
|
}
|
|
|
|
s32 getTotalPayShineNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getTotalPayShineNum();
|
|
}
|
|
|
|
s32 getTotalPayShineNumClamp(GameDataHolderAccessor accessor) {
|
|
return sead::Mathi::clampMax(getTotalPayShineNum(accessor), 999);
|
|
}
|
|
|
|
bool isPayShineAllInAllWorld(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isPayShineAllInAllWorld();
|
|
}
|
|
|
|
void addKey(GameDataHolderWriter writer, s32 count) {
|
|
writer->getGameDataFile()->addKey(count);
|
|
}
|
|
|
|
s32 getKeyNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getKeyNum();
|
|
}
|
|
|
|
s32 getCurrentKeyNum(GameDataHolderAccessor accessor) {
|
|
return getKeyNum(accessor) - getOpenDoorLockNum(accessor);
|
|
}
|
|
|
|
s32 getOpenDoorLockNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getOpenDoorLockNum();
|
|
}
|
|
|
|
void openDoorLock(GameDataHolderWriter writer, const al::PlacementId* placement_id) {
|
|
if (isOpenDoorLock(writer, placement_id))
|
|
return;
|
|
writer->getGameDataFile()->addOpenDoorLockNum(1);
|
|
writer->getGameDataFile()->setStartedObj(placement_id);
|
|
}
|
|
|
|
bool isOpenDoorLock(GameDataHolderAccessor accessor, const al::PlacementId* placement_id) {
|
|
return accessor->getGameDataFile()->isStartedObj(placement_id);
|
|
}
|
|
|
|
void setObjStarted(GameDataHolder* game_data_holder, const al::PlacementId* placement_id) {
|
|
game_data_holder->getGameDataFile()->setStartedObj(placement_id);
|
|
}
|
|
|
|
bool isObjStarted(const GameDataHolder* game_data_holder, const al::PlacementId* placement_id) {
|
|
return game_data_holder->getGameDataFile()->isStartedObj(placement_id);
|
|
}
|
|
|
|
bool isObjStarted(GameDataHolderAccessor accessor, const char* stage_name, const char* obj_id) {
|
|
return accessor->getGameDataFile()->isStartedObj(stage_name, obj_id);
|
|
}
|
|
|
|
void saveObjS32(GameDataHolderWriter writer, const al::PlacementId* placement_id, s32 value) {
|
|
writer->getGameDataFile()->setSaveObjS32(placement_id, value);
|
|
}
|
|
|
|
bool tryFindSaveObjS32Value(s32* out, GameDataHolderAccessor accessor,
|
|
const al::PlacementId* placement_id) {
|
|
if (const GameDataFile::SaveObjS32* obj =
|
|
accessor->getGameDataFile()->tryFindSaveObjS32(placement_id)) {
|
|
*out = obj->value;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void onObjNoWriteSaveData(GameDataHolderWriter writer, const al::PlacementId* placement_id) {
|
|
writer->onObjNoWriteSaveData(placement_id);
|
|
}
|
|
|
|
void offObjNoWriteSaveData(GameDataHolderWriter writer, const al::PlacementId* placement_id) {
|
|
writer->offObjNoWriteSaveData(placement_id);
|
|
}
|
|
|
|
bool isOnObjNoWriteSaveData(GameDataHolderAccessor accessor, const al::PlacementId* placement_id) {
|
|
return accessor->isOnObjNoWriteSaveData(placement_id);
|
|
}
|
|
|
|
void onObjNoWriteSaveDataResetMiniGame(GameDataHolderWriter writer,
|
|
const al::PlacementId* placement_id) {
|
|
writer->onObjNoWriteSaveDataResetMiniGame(placement_id);
|
|
}
|
|
|
|
void offObjNoWriteSaveDataResetMiniGame(GameDataHolderWriter writer,
|
|
const al::PlacementId* placement_id) {
|
|
writer->offObjNoWriteSaveDataResetMiniGame(placement_id);
|
|
}
|
|
|
|
bool isOnObjNoWriteSaveDataResetMiniGame(GameDataHolderAccessor accessor,
|
|
const al::PlacementId* placement_id) {
|
|
return accessor->isOnObjNoWriteSaveDataResetMiniGame(placement_id);
|
|
}
|
|
|
|
void onObjNoWriteSaveDataInSameScenario(GameDataHolder* game_data_holder,
|
|
const al::PlacementId* placement_id) {
|
|
game_data_holder->onObjNoWriteSaveDataInSameScenario(placement_id);
|
|
}
|
|
|
|
bool isOnObjNoWriteSaveDataInSameScenario(const GameDataHolder* game_data_holder,
|
|
const al::PlacementId* placement_id) {
|
|
return game_data_holder->isOnObjNoWriteSaveDataInSameScenario(placement_id);
|
|
}
|
|
|
|
void setSessionEventProgress(GameDataHolderWriter writer, const SessionEventProgress& progress) {
|
|
writer->getGameDataFile()->setSessionEventProgress(progress);
|
|
}
|
|
|
|
const SessionEventProgress& getSessionEventProgress(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getSessionEventProgress();
|
|
}
|
|
|
|
bool isPayCoinToSphinx(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->isPayCoinToSphinx();
|
|
}
|
|
|
|
void payCoinToSphinx(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->payCoinToSphinx();
|
|
}
|
|
|
|
static GameDataFile::CapStatus getCapStatusForJango(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getCapStatusForJango();
|
|
}
|
|
|
|
static void setCapStatusForJango(GameDataHolderAccessor accessor, GameDataFile::CapStatus status) {
|
|
return accessor->getGameDataFile()->setCapStatusForJango(status);
|
|
}
|
|
|
|
static GameDataFile::CapStatus getCapStatusForJangoSubArea(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getCapStatusForJangoSubArea();
|
|
}
|
|
|
|
static void setCapStatusForJangoSubArea(GameDataHolderAccessor accessor,
|
|
GameDataFile::CapStatus status) {
|
|
return accessor->getGameDataFile()->setCapStatusForJangoSubArea(status);
|
|
}
|
|
|
|
bool isRemovedCapByJango(const al::LiveActor* actor) {
|
|
if (!isMainStage(actor))
|
|
return getCapStatusForJangoSubArea(actor) == GameDataFile::CapStatus::Removed;
|
|
return getCapStatusForJango(actor) == GameDataFile::CapStatus::Removed;
|
|
}
|
|
|
|
bool isGetCapFromJango(const al::LiveActor* actor) {
|
|
if (!isMainStage(actor))
|
|
return getCapStatusForJangoSubArea(actor) == GameDataFile::CapStatus::GotBack;
|
|
return getCapStatusForJango(actor) == GameDataFile::CapStatus::GotBack;
|
|
}
|
|
|
|
void removeCapByJango(const al::LiveActor* actor) {
|
|
if (!isMainStage(actor)) {
|
|
setCapStatusForJangoSubArea(actor, GameDataFile::CapStatus::Removed);
|
|
return;
|
|
}
|
|
setCapStatusForJango(actor, GameDataFile::CapStatus::Removed);
|
|
}
|
|
|
|
void getCapFromJango(const al::LiveActor* actor) {
|
|
if (!isMainStage(actor)) {
|
|
setCapStatusForJangoSubArea(actor, GameDataFile::CapStatus::GotBack);
|
|
return;
|
|
}
|
|
setCapStatusForJango(actor, GameDataFile::CapStatus::GotBack);
|
|
}
|
|
|
|
void addJangoCount(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->addJangoCount();
|
|
}
|
|
|
|
s32 getJangoCount(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->getJangoCount();
|
|
}
|
|
|
|
bool isFirstWorldTravelingStatus(const WorldTravelingNpc* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->isFirstWorldTravelingStatus();
|
|
}
|
|
|
|
void saveWorldTravelingStatus(const WorldTravelingNpc* actor, const char* status) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->saveWorldTravelingStatus(status);
|
|
}
|
|
|
|
const char* getWorldTravelingStatus(const WorldTravelingNpc* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->getWorldTravelingStatus();
|
|
}
|
|
|
|
bool isRaceStart(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isRaceStart();
|
|
}
|
|
|
|
bool isRaceStartFlag(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getRaceType() == GameDataFile::RaceType_Flag;
|
|
}
|
|
|
|
bool isRaceStartYukimaru(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getRaceType() == GameDataFile::RaceType_Yukimaru;
|
|
}
|
|
|
|
bool isRaceStartYukimaruTutorial(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getRaceType() == GameDataFile::RaceType_YukimaruTutorial;
|
|
}
|
|
|
|
bool isRaceWin(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getRaceResult() == GameDataFile::RaceResult_Win;
|
|
}
|
|
|
|
bool isRaceWin(GameDataHolderAccessor, s32) {
|
|
return false;
|
|
}
|
|
|
|
bool isRaceResultSecond(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getRaceResult() == GameDataFile::RaceResult_Second;
|
|
}
|
|
|
|
bool isRaceResultThird(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getRaceResult() == GameDataFile::RaceResult_Third;
|
|
}
|
|
|
|
bool isRaceLose(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getRaceResult() == GameDataFile::RaceResult_Lose;
|
|
}
|
|
|
|
bool isRaceCancel(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getRaceResult() == GameDataFile::RaceResult_Cancel;
|
|
}
|
|
|
|
void winRace(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->winRace();
|
|
}
|
|
|
|
void endRaceResultSecond(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->setRaceResult(GameDataFile::RaceResult_Second);
|
|
}
|
|
|
|
void endRaceResultThird(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->setRaceResult(GameDataFile::RaceResult_Third);
|
|
}
|
|
|
|
void loseRace(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->setRaceResult(GameDataFile::RaceResult_Lose);
|
|
}
|
|
|
|
static s32 getRaceRivalLevelImpl(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getRaceRivalLevel();
|
|
}
|
|
|
|
s32 getRaceRivalLevel(const al::LiveActor* actor) {
|
|
return getRaceRivalLevelImpl(actor);
|
|
}
|
|
|
|
s32 getRaceRivalLevel(const al::Scene* scene) {
|
|
return getRaceRivalLevelImpl(scene);
|
|
}
|
|
|
|
void setRaceRivalLevel(const al::LiveActor* actor, s32 level) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->setRaceRivalLevel(level);
|
|
}
|
|
|
|
void setLastRaceRanking(GameDataHolderAccessor accessor, s32 ranking) {
|
|
accessor->getGameDataFile()->setLastRaceRanking(ranking);
|
|
}
|
|
|
|
s32 getLastRaceRanking(GameDataHolderWriter writer) {
|
|
return writer->getGameDataFile()->getLastRaceRanking();
|
|
}
|
|
|
|
void incrementRaceLoseCount(const al::Scene* scene, s32 level) {
|
|
GameDataHolderAccessor accessor{scene};
|
|
accessor->getGameDataFile()->incrementRaceLoseCount(level);
|
|
}
|
|
|
|
s32 getRaceLoseCount(const al::LiveActor* actor, s32 level) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->getRaceLoseCount(level);
|
|
}
|
|
|
|
void addCoinCollect(GameDataHolderWriter writer, const al::PlacementId* placement_id) {
|
|
writer->getGameDataFile()->addCoinCollect(placement_id);
|
|
}
|
|
|
|
void useCoinCollect(GameDataHolderWriter writer, s32 count) {
|
|
writer->getGameDataFile()->useCoinCollect(count);
|
|
}
|
|
|
|
bool isGotCoinCollect(GameDataHolderAccessor accessor, const al::ActorInitInfo& actor_info) {
|
|
al::PlacementId placement_id;
|
|
al::tryGetPlacementId(&placement_id, actor_info);
|
|
return accessor->getGameDataFile()->isGotCoinCollect(&placement_id);
|
|
}
|
|
|
|
s32 getCoinCollectNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getCoinCollectNum();
|
|
}
|
|
|
|
s32 getCoinCollectGotNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getCoinCollectGotNum();
|
|
}
|
|
|
|
s32 getCoinCollectGotNum(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getGameDataFile()->getCoinCollectGotNum(world_id);
|
|
}
|
|
|
|
s32 getCoinCollectNumMax(GameDataHolderAccessor accessor) {
|
|
return accessor->getCoinCollectNumMax(getCurrentWorldId(accessor));
|
|
}
|
|
|
|
s32 getCoinCollectNumMax(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getCoinCollectNumMax(world_id);
|
|
}
|
|
|
|
bool tryFindExistCoinCollectStagePosExcludeHomeStageInCurrentWorld(
|
|
sead::Vector3f* out_pos, const char** out_stage_name, GameDataHolderAccessor accessor) {
|
|
s32 world_id = getCurrentWorldIdNoDevelop(accessor);
|
|
if (const char* stage_name =
|
|
accessor->getGameDataFile()->tryFindExistCoinCollectStageName(world_id)) {
|
|
if (accessor->getWorldList()->tryFindTransOnMainStageByStageName(
|
|
out_pos, stage_name, getWorldScenarioNo(accessor, world_id))) {
|
|
*out_stage_name = stage_name;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
s32 getWorldScenarioNo(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getGameDataFile()->getScenarioNo(world_id);
|
|
}
|
|
|
|
void addCoin(GameDataHolderWriter writer, s32 count) {
|
|
writer->getGameDataFile()->addCoin(count);
|
|
}
|
|
|
|
void subCoin(GameDataHolderWriter writer, s32 count) {
|
|
writer->getGameDataFile()->addCoin(-count);
|
|
}
|
|
|
|
s32 getCoinNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getCoinNum();
|
|
}
|
|
|
|
s32 getTotalCoinNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getTotalCoinNum();
|
|
}
|
|
|
|
bool isAppearCourseName(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isAppearCourseName();
|
|
}
|
|
|
|
void setStageHakoniwa(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->setStageHakoniwa();
|
|
}
|
|
|
|
bool isEnableCheckpointWarp(GameDataHolderAccessor accessor) {
|
|
return accessor->isEnableCheckpointWarp();
|
|
}
|
|
|
|
void validateCheckpointWarp(GameDataHolderWriter writer) {
|
|
writer->validateCheckpointWarp();
|
|
}
|
|
|
|
void invalidateCheckpointWarp(GameDataHolderWriter writer) {
|
|
writer->invalidateCheckpointWarp();
|
|
}
|
|
|
|
s32 getCheckpointNumMaxInWorld(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getCheckpointNumMaxInWorld();
|
|
}
|
|
|
|
const sead::Vector3f& getCheckpointTransInWorld(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->getCheckpointTransInWorld(
|
|
getCheckpointObjIdInWorld(accessor, index));
|
|
}
|
|
|
|
const sead::Vector3f& getCheckpointTransInWorld(GameDataHolderAccessor accessor,
|
|
const char* obj_id) {
|
|
return accessor->getGameDataFile()->getCheckpointTransInWorld(obj_id);
|
|
}
|
|
|
|
const char* getCheckpointObjIdInWorld(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->getCheckpointObjIdInWorld(index);
|
|
}
|
|
|
|
bool isGotCheckpointInWorld(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->isGotCheckpointInWorld(index);
|
|
}
|
|
|
|
bool isGotCheckpoint(GameDataHolderAccessor accessor, al::PlacementId* placement_id) {
|
|
return accessor->getGameDataFile()->isGotCheckpoint(placement_id);
|
|
}
|
|
|
|
s32 calcGotCheckpointNumInWorld(GameDataHolderAccessor accessor) {
|
|
s32 max = getCheckpointNumMaxInWorld(accessor);
|
|
s32 count = 0;
|
|
for (s32 i = 0; i < max; i++)
|
|
if (isGotCheckpointInWorld(accessor, i))
|
|
count++;
|
|
return count;
|
|
}
|
|
|
|
void changeNextSceneByGotCheckpoint(GameDataHolderWriter writer, s32 index) {
|
|
writer->getGameDataFile()->changeNextSceneByGotCheckpoint(index);
|
|
}
|
|
|
|
void changeNextSceneByHome(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->changeNextSceneByHome();
|
|
}
|
|
|
|
bool isWarpCheckpoint(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isWarpCheckpoint();
|
|
}
|
|
|
|
const char* getCheckpointWarpObjId(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getCheckpointWarpObjId();
|
|
}
|
|
|
|
void registerCheckpointTrans(GameDataHolderWriter writer, const al::PlacementId* placement_id,
|
|
const sead::Vector3f& trans) {
|
|
writer->getGameDataFile()->registerCheckpointTrans(placement_id, trans);
|
|
}
|
|
|
|
bool isEnableUnlockHint(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isEnableUnlockHint();
|
|
}
|
|
|
|
void unlockHint(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->unlockHint();
|
|
}
|
|
|
|
void unlockHintAmiibo(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->unlockHintAmiibo();
|
|
}
|
|
|
|
s32 calcHintNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->calcHintNum();
|
|
}
|
|
|
|
s32 calcRestHintNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->calcRestHintNum();
|
|
}
|
|
|
|
bool checkExistHint(GameDataHolderAccessor accessor) {
|
|
return calcHintNum(accessor) > 0;
|
|
}
|
|
|
|
s32 getHintNumMax(GameDataHolderAccessor accessor) {
|
|
return 70;
|
|
}
|
|
|
|
const sead::Vector3f& calcHintTrans(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->calcHintTrans(index);
|
|
}
|
|
|
|
const sead::Vector3f& getLatestHintTrans(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getLatestHint()->trans;
|
|
}
|
|
|
|
bool checkLatestHintSeaOfTree(GameDataHolderAccessor accessor) {
|
|
return isSeaOfTreeStage(accessor->getGameDataFile()->getLatestHint()->stageName.cstr());
|
|
}
|
|
|
|
s32 calcHintMoonRockNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->calcHintMoonRockNum();
|
|
}
|
|
|
|
s32 getHintMoonRockNumMax(GameDataHolderAccessor accessor) {
|
|
return 25;
|
|
}
|
|
|
|
const sead::Vector3f& calcHintMoonRockTrans(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->calcHintMoonRockTrans(index);
|
|
}
|
|
|
|
void initializeHintList(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->initializeHintList();
|
|
}
|
|
|
|
const sead::Vector3f& calcHintTransMostEasy(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->calcHintTransMostEasy();
|
|
}
|
|
|
|
bool calcHintTransMostNear(sead::Vector3f* out, GameDataHolderAccessor accessor,
|
|
const sead::Vector3f& pos) {
|
|
s32 hint_num = calcHintNum(accessor);
|
|
if (hint_num == 0)
|
|
return false;
|
|
f32 min_dist = sead::Mathf::maxNumber();
|
|
for (s32 i = 0; i < hint_num; i++) {
|
|
sead::Vector3f trans = calcHintTrans(accessor, i);
|
|
f32 dist = (trans - pos).length();
|
|
if (dist < min_dist) {
|
|
out->set(trans);
|
|
min_dist = dist;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool checkHintSeaOfTree(GameDataHolderAccessor accessor, s32 index) {
|
|
return isSeaOfTreeStage(accessor->getGameDataFile()->findHint(index).stageName.cstr());
|
|
}
|
|
|
|
bool checkHintSeaOfTreeMoonRock(GameDataHolderAccessor accessor, s32 index) {
|
|
return isSeaOfTreeStage(accessor->getGameDataFile()->findHintMoonRock(index).stageName.cstr());
|
|
}
|
|
|
|
s32 findUnlockShineNum(bool* out_is_game_clear, GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->findUnlockShineNumCurrentWorld(out_is_game_clear);
|
|
}
|
|
|
|
s32 findUnlockShineNumByWorldId(bool* out_is_game_clear, GameDataHolderAccessor accessor,
|
|
s32 world_id) {
|
|
return accessor->findUnlockShineNum(out_is_game_clear, world_id);
|
|
}
|
|
|
|
bool isUnlockedWorld(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getGameDataFile()->isUnlockedWorld(world_id);
|
|
}
|
|
|
|
bool isUnlockedNextWorld(GameDataHolderAccessor accessor) {
|
|
bool is_game_clear = false;
|
|
s32 unlock_shine_num = findUnlockShineNum(&is_game_clear, accessor);
|
|
return is_game_clear || getPayShineNum(accessor) >= unlock_shine_num;
|
|
}
|
|
|
|
bool isUnlockedAllWorld(GameDataHolderAccessor accessor) {
|
|
return isUnlockedWorld(accessor, getWorldIndexSpecial2());
|
|
}
|
|
|
|
bool isUnlockedCurrentWorld(GameDataHolderAccessor accessor) {
|
|
return isUnlockedWorld(accessor, getCurrentWorldIdNoDevelop(accessor));
|
|
}
|
|
|
|
bool isCollectShineForNextWorldAndNotUnlockNextWorld(const al::LiveActor* actor) {
|
|
return !isUnlockedNextWorld(actor) && rs::checkGetEnoughShineInCurrentWorld(actor);
|
|
}
|
|
|
|
bool isAlreadyGoWorld(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getGameDataFile()->isAlreadyGoWorld(world_id);
|
|
}
|
|
|
|
bool isMainStage(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getMainStageName(accessor, getCurrentWorldId(accessor)),
|
|
getCurrentStageName(accessor));
|
|
}
|
|
|
|
const char* getMainStageName(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getWorldList()->getMainStageName(world_id);
|
|
}
|
|
|
|
const char* tryGetCurrentMainStageName(GameDataHolderAccessor accessor) {
|
|
s32 world_id = getCurrentWorldId(accessor);
|
|
if (world_id >= 1) {
|
|
const char* stage_name = getMainStageName(accessor, world_id);
|
|
if (stage_name && !al::isEqualString(stage_name, ""))
|
|
return stage_name;
|
|
}
|
|
return getMainStageName(accessor, 0);
|
|
}
|
|
|
|
const char16* tryGetWorldName(const al::LayoutActor* layout, s32 world_id) {
|
|
al::StringTmp<128> label;
|
|
label.format("WorldName_%s", getWorldDevelopName(layout, world_id));
|
|
return al::getSystemMessageString(layout, "StageName", label.cstr());
|
|
}
|
|
|
|
const char16* tryGetWorldNameCurrent(const al::LayoutActor* layout) {
|
|
return tryGetWorldName(layout, getCurrentWorldId(layout));
|
|
}
|
|
|
|
const char16* tryGetRegionNameCurrent(const al::LayoutActor* layout) {
|
|
s32 world_id = getCurrentWorldId(layout);
|
|
al::StringTmp<128> label;
|
|
label.format("RegionName_%s", getWorldDevelopName(layout, world_id));
|
|
return al::getSystemMessageString(layout, "StageName", label.cstr());
|
|
}
|
|
|
|
const char* getWorldDevelopName(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getWorldList()->getWorldDevelopName(sead::Mathi::max(world_id, 0));
|
|
}
|
|
|
|
const char* getWorldDevelopNameCurrent(GameDataHolderAccessor accessor) {
|
|
return accessor->getWorldList()->getWorldDevelopName(
|
|
accessor->getGameDataFile()->getCurrentWorldIdNoDevelop());
|
|
}
|
|
|
|
s32 getWorldScenarioNum(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getWorldList()->getWorldScenarioNum(sead::Mathi::max(world_id, 0));
|
|
}
|
|
|
|
const char* findMainStageNameByDevelopName(GameDataHolderAccessor accessor, const char* name) {
|
|
for (s32 i = 0; i < getWorldNum(accessor); i++)
|
|
if (al::isEqualString(getWorldDevelopName(accessor, i), name))
|
|
return getMainStageName(accessor, i);
|
|
return nullptr;
|
|
}
|
|
|
|
s32 findWorldIdByDevelopName(GameDataHolderAccessor accessor, const char* name) {
|
|
for (s32 i = 0; i < getWorldNum(accessor); i++)
|
|
if (al::isEqualString(getWorldDevelopName(accessor, i), name))
|
|
return i;
|
|
return 0;
|
|
}
|
|
|
|
static s32 tryFindWorldIdByMainStageNameImpl(GameDataHolderAccessor accessor,
|
|
const char* stage_name) {
|
|
return accessor->getWorldList()->tryFindWorldIndexByMainStageName(stage_name);
|
|
}
|
|
|
|
s32 tryFindWorldIdByMainStageName(const al::Scene* scene, const char* stage_name) {
|
|
return tryFindWorldIdByMainStageNameImpl(scene, stage_name);
|
|
}
|
|
|
|
s32 tryFindWorldIdByMainStageName(const al::IUseSceneObjHolder* scene_obj_holder,
|
|
const char* stage_name) {
|
|
return tryFindWorldIdByMainStageNameImpl(scene_obj_holder, stage_name);
|
|
}
|
|
|
|
bool checkEnableUnlockWorldSpecial1(const al::LiveActor* actor) {
|
|
if (isUnlockedWorld(actor, getWorldIndexSpecial1()) ||
|
|
isUnlockedWorld(actor, getWorldIndexSpecial2()))
|
|
return false;
|
|
bool is_game_clear = false;
|
|
s32 unlock_shine_num = findUnlockShineNum(&is_game_clear, actor);
|
|
return is_game_clear && getTotalPayShineNum(actor) >= unlock_shine_num;
|
|
}
|
|
|
|
bool checkEnableUnlockWorldSpecial2(const al::LiveActor* actor) {
|
|
if (!isUnlockedWorld(actor, getWorldIndexSpecial1()) ||
|
|
isUnlockedWorld(actor, getWorldIndexSpecial2()))
|
|
return false;
|
|
bool is_game_clear = false;
|
|
s32 unlock_shine_num = findUnlockShineNum(&is_game_clear, actor);
|
|
return is_game_clear && getTotalPayShineNum(actor) >= unlock_shine_num;
|
|
}
|
|
|
|
const char16* tryGetWorldNameByFileId(const al::LayoutActor* layout, s32 file_id) {
|
|
GameDataHolderAccessor accessor{layout};
|
|
s32 world_id = accessor->getGameDataFile(file_id)->getCurrentWorldIdForDisp();
|
|
return tryGetWorldName(layout, world_id);
|
|
}
|
|
|
|
bool isNewSaveDataByFileId(const al::LayoutActor* layout, s32 file_id) {
|
|
GameDataHolderAccessor accessor{layout};
|
|
return accessor->getGameDataFile(file_id)->isPlayDemoOpening();
|
|
}
|
|
|
|
u64 getLastUpdateFileTime(const al::LayoutActor* layout, s32 file_id) {
|
|
GameDataHolderAccessor accessor{layout};
|
|
return accessor->getGameDataFile(file_id)->getLastUpdateTime();
|
|
}
|
|
|
|
static bool isGotShine(const GameDataHolder* game_data_holder, const char* stage_name,
|
|
const char* obj_id) {
|
|
ShineInfo shine_info;
|
|
shine_info.init(stage_name, obj_id, nullptr, nullptr, ShineInfo::Type_Shine);
|
|
return game_data_holder->getGameDataFile()->isGotShine(&shine_info);
|
|
}
|
|
|
|
void makeTextureSaveDataFileName(sead::BufferedSafeString* out, const nn::g3d::ResFile* res_file,
|
|
const GameDataHolder* game_data_holder, s32 file_id) {
|
|
const GameDataFile* game_data_file = game_data_holder->getGameDataFile(file_id);
|
|
s32 world_id = sead::Mathi::clampMin(game_data_file->getCurrentWorldIdForDisp(), 0);
|
|
const char* world_name = game_data_holder->getWorldList()->getWorldDevelopName(world_id);
|
|
s32 main_scenario_no = game_data_file->getMainScenarioNo(world_id);
|
|
s32 scenario_no = game_data_file->getScenarioNo(world_id);
|
|
|
|
if (world_id == getWorldIndexPeach()) {
|
|
if (game_data_file->getTotalPayShineNumForDisp() == 999) {
|
|
out->format("PeachWorldCapOn");
|
|
if (agl::g3d::ResFile::GetTextureIndex(res_file, out->cstr()) != -1)
|
|
return;
|
|
}
|
|
out->format("PeachWorld");
|
|
if (agl::g3d::ResFile::GetTextureIndex(res_file, out->cstr()) != -1)
|
|
return;
|
|
}
|
|
|
|
if (game_data_holder->getWorldList()->isEqualMoonRockScenarioNo(world_id, scenario_no)) {
|
|
out->format("%sWorldMoonRock", world_name);
|
|
if (agl::g3d::ResFile::GetTextureIndex(res_file, out->cstr()) != -1)
|
|
return;
|
|
out->format("%sWorldED", world_name);
|
|
if (agl::g3d::ResFile::GetTextureIndex(res_file, out->cstr()) != -1)
|
|
return;
|
|
out->format("%sWorld", world_name);
|
|
if (agl::g3d::ResFile::GetTextureIndex(res_file, out->cstr()) != -1)
|
|
return;
|
|
return;
|
|
}
|
|
|
|
if (game_data_holder->getWorldList()->isEqualAfterEndingScenarioNo(world_id, scenario_no)) {
|
|
out->format("%sWorldED", world_name);
|
|
if (agl::g3d::ResFile::GetTextureIndex(res_file, out->cstr()) != -1)
|
|
return;
|
|
out->format("%sWorld", world_name);
|
|
if (agl::g3d::ResFile::GetTextureIndex(res_file, out->cstr()) != -1)
|
|
return;
|
|
return;
|
|
}
|
|
|
|
if (world_id == getWorldIndexCity()) {
|
|
if (scenario_no == 1) {
|
|
out->format("CityWorld00");
|
|
return;
|
|
}
|
|
if (scenario_no == 2) {
|
|
if (main_scenario_no <= 3) {
|
|
out->format("CityWorld01");
|
|
return;
|
|
}
|
|
out->format("CityWorld02");
|
|
return;
|
|
}
|
|
if (isCityWorldCeremonyAll(world_id, scenario_no)) {
|
|
out->format("CityWorld03");
|
|
return;
|
|
}
|
|
out->format("CityWorld");
|
|
return;
|
|
}
|
|
|
|
if (world_id == getWorldIndexSea()) {
|
|
if (scenario_no == 1) {
|
|
if (main_scenario_no == 0) {
|
|
s32 count = 0;
|
|
if (isGotShine(game_data_holder, "SeaWorldHomeStage", "obj382"))
|
|
count++;
|
|
if (isGotShine(game_data_holder, "SeaWorldLighthouseZone", "obj16"))
|
|
count++;
|
|
if (isGotShine(game_data_holder, "SeaWorldLavaZone", "obj168"))
|
|
count++;
|
|
if (isGotShine(game_data_holder, "SeaWorldDamageBallZone", "obj60"))
|
|
count++;
|
|
if (count == 0) {
|
|
out->format("SeaWorld00");
|
|
return;
|
|
}
|
|
out->format("SeaWorld01");
|
|
return;
|
|
}
|
|
if (main_scenario_no == 1) {
|
|
out->format("SeaWorld02");
|
|
return;
|
|
}
|
|
}
|
|
out->format("SeaWorld");
|
|
return;
|
|
}
|
|
|
|
if (game_data_file->isPlayDemoOpening()) {
|
|
out->format("Empty");
|
|
return;
|
|
}
|
|
|
|
if (main_scenario_no >= 0) {
|
|
out->format("%sWorld%02d", world_name, main_scenario_no);
|
|
if (agl::g3d::ResFile::GetTextureIndex(res_file, out->cstr()) != -1)
|
|
return;
|
|
}
|
|
|
|
out->format("%sWorld", world_name);
|
|
if (agl::g3d::ResFile::GetTextureIndex(res_file, out->cstr()) != -1)
|
|
return;
|
|
}
|
|
|
|
void unlockWorld(GameDataHolderWriter writer, s32 world_id) {
|
|
writer->getGameDataFile()->unlockWorld(world_id);
|
|
}
|
|
|
|
static s32 getUnlockWorldIdForWorldMapImpl(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getGameDataFile()->getGameProgressData()->getWorldIdForWorldMap(world_id);
|
|
}
|
|
|
|
s32 getUnlockWorldIdForWorldMap(const al::LayoutActor* layout, s32 world_id) {
|
|
return getUnlockWorldIdForWorldMapImpl(layout, world_id);
|
|
}
|
|
|
|
s32 getUnlockWorldIdForWorldMap(const al::LiveActor* actor, s32 world_id) {
|
|
return getUnlockWorldIdForWorldMapImpl(actor, world_id);
|
|
}
|
|
|
|
s32 getUnlockWorldIdForWorldMap(const al::Scene* scene, s32 world_id) {
|
|
return getUnlockWorldIdForWorldMapImpl(scene, world_id);
|
|
}
|
|
|
|
s32 getUnlockWorldIdForWorldMap(const GameDataHolder* game_data_holder, s32 world_id) {
|
|
return game_data_holder->getGameDataFile()->getGameProgressData()->getWorldIdForWorldMap(
|
|
world_id);
|
|
}
|
|
|
|
static s32 getUnlockWorldNumForWorldMapImpl(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getGameProgressData()->getUnlockWorldNum();
|
|
}
|
|
|
|
s32 getUnlockWorldNumForWorldMap(const al::Scene* scene) {
|
|
return getUnlockWorldNumForWorldMapImpl(scene);
|
|
}
|
|
|
|
s32 getUnlockWorldNumForWorldMap(const al::LiveActor* actor) {
|
|
return getUnlockWorldNumForWorldMapImpl(actor);
|
|
}
|
|
|
|
s32 getUnlockWorldNumForWorldMap(const al::LayoutActor* layout) {
|
|
return getUnlockWorldNumForWorldMapImpl(layout);
|
|
}
|
|
|
|
static s32 calcNextLockedWorldIdForWorldMapImpl(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getGameDataFile()->getGameProgressData()->calcNextLockedWorldIdForWorldMap(
|
|
world_id);
|
|
}
|
|
|
|
s32 calcNextLockedWorldIdForWorldMap(const al::LayoutActor* layout, s32 world_id) {
|
|
return calcNextLockedWorldIdForWorldMapImpl(layout, world_id);
|
|
}
|
|
|
|
s32 calcNextLockedWorldIdForWorldMap(const al::Scene* scene, s32 world_id) {
|
|
return calcNextLockedWorldIdForWorldMapImpl(scene, world_id);
|
|
}
|
|
|
|
static s32 calcNextLockedWorldNumForWorldMapImpl(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getGameProgressData()->calcNextLockedWorldNumForWorldMap();
|
|
}
|
|
|
|
s32 calcNextLockedWorldNumForWorldMap(const al::Scene* scene) {
|
|
return calcNextLockedWorldNumForWorldMapImpl(scene);
|
|
}
|
|
|
|
s32 calcNextLockedWorldNumForWorldMap(const al::LayoutActor* layout) {
|
|
return calcNextLockedWorldNumForWorldMapImpl(layout);
|
|
}
|
|
|
|
s32 getWorldIdForShineList(const al::LayoutActor* layout, s32 world_id) {
|
|
GameDataHolderAccessor accessor{layout};
|
|
return accessor->getGameDataFile()->getGameProgressData()->getWorldIdForShineList(world_id);
|
|
}
|
|
|
|
s32 calcWorldNumForShineList(const al::LayoutActor* layout) {
|
|
GameDataHolderAccessor accessor{layout};
|
|
return accessor->getGameDataFile()->getGameProgressData()->calcWorldNumForShineList();
|
|
}
|
|
|
|
s32 getLatestUnlockWorldIdForShineTowerMeter(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->getGameProgressData()->getWorldIdForWorldWarpHole(
|
|
getUnlockWorldNumForWorldMapImpl(accessor) - 1);
|
|
}
|
|
|
|
bool isClearSandWorldScenario1(const al::Scene* scene) {
|
|
GameDataHolderAccessor accessor{scene};
|
|
s32 world_id = accessor->getWorldList()->tryFindWorldIndexByDevelopName("Sand");
|
|
return getWorldScenarioNo(scene, world_id) > 1;
|
|
}
|
|
|
|
bool isClearCityWorldScenario1(const al::Scene* scene) {
|
|
GameDataHolderAccessor accessor{scene};
|
|
s32 world_id = accessor->getWorldList()->tryFindWorldIndexByDevelopName("City");
|
|
return getWorldScenarioNo(scene, world_id) > 1;
|
|
}
|
|
|
|
bool isClearSkyWorldScenario1(const al::Scene* scene) {
|
|
GameDataHolderAccessor accessor{scene};
|
|
s32 world_id = accessor->getWorldList()->tryFindWorldIndexByDevelopName("Sky");
|
|
return getWorldScenarioNo(scene, world_id) > 1;
|
|
}
|
|
|
|
bool isCityWorldScenario2(const al::IUseSceneObjHolder* scene_obj_holder) {
|
|
if (isWorldCity(scene_obj_holder) && rs::getActiveQuestNum(scene_obj_holder) > 0) {
|
|
s32 quest_no = rs::getActiveQuestNo(scene_obj_holder);
|
|
if (quest_no >= 2 && quest_no <= 6)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
s32 calcNextWorldId(GameDataHolderAccessor accessor) {
|
|
return accessor->getWorldList()->tryFindWorldIndexByMainStageName(accessor->getNextStageName());
|
|
}
|
|
|
|
bool isPlayDemoWorldWarp(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isPlayDemoWorldWarp();
|
|
}
|
|
|
|
bool isPlayDemoWorldWarpHole(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isPlayDemoWorldWarpHole();
|
|
}
|
|
|
|
void noPlayDemoWorldWarp(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->noPlayDemoWorldWarp();
|
|
}
|
|
|
|
bool isPlayDemoReturnToHome(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isPlayDemoReturnToHome();
|
|
}
|
|
|
|
void requestPlayDemoReturnToHome(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->requestPlayDemoReturnToHome();
|
|
}
|
|
|
|
bool isPlayDemoAwardSpecial(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isPlayDemoAwardSpecial();
|
|
}
|
|
|
|
void requestPlayDemoAwardSpecial(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->requestPlayDemoAwardSpecial();
|
|
}
|
|
|
|
bool isPlayDemoLavaErupt(GameDataHolderAccessor accessor) {
|
|
return accessor->isPlayDemoLavaErupt();
|
|
}
|
|
|
|
bool isPlayDemoPlayerDownForBattleKoopaAfter(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isPlayDemoPlayerDownForBattleKoopaAfter();
|
|
}
|
|
|
|
void disablePlayDemoPlayerDownForBattleKoopaAfter(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->disablePlayDemoPlayerDownForBattleKoopaAfter();
|
|
}
|
|
|
|
void enteredStage(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->enteredStage();
|
|
writer->resetTemporaryScenarioCameraHolder();
|
|
}
|
|
|
|
const char* getCurrentCostumeTypeName(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getCurrentCostumeName();
|
|
}
|
|
|
|
const char* getCurrentCapTypeName(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getCurrentCapName();
|
|
}
|
|
|
|
void wearCostume(GameDataHolderWriter writer, const char* name) {
|
|
writer->getGameDataFile()->wearCostume(name);
|
|
rs::trySavePrepoChangeClothEvent(name, getPlayTimeTotal(writer), getSaveDataIdForPrepo(writer),
|
|
getPlayTimeAcrossFile(writer));
|
|
}
|
|
|
|
void wearCap(GameDataHolderWriter writer, const char* name) {
|
|
writer->getGameDataFile()->wearCap(name);
|
|
rs::trySavePrepoChangeCapEvent(name, getPlayTimeTotal(writer), getSaveDataIdForPrepo(writer),
|
|
getPlayTimeAcrossFile(writer));
|
|
}
|
|
|
|
void wearCostumeRandom(al::IUseSceneObjHolder* scene_obj_holder) {
|
|
const char* current = getCurrentCostumeTypeName(scene_obj_holder);
|
|
const char* target = "Mario";
|
|
s32 total_num = rs::calcHaveClothNum(scene_obj_holder);
|
|
if (total_num != 1) {
|
|
s32 seen_num = 1;
|
|
for (s32 i = 0; i < rs::getClothListSize(scene_obj_holder); i++) {
|
|
if (!rs::isHaveCloth(scene_obj_holder, i) ||
|
|
al::isEqualString(current, rs::getClothList(scene_obj_holder)[i]->name))
|
|
continue;
|
|
f32 chance = 100.0f / (total_num - seen_num++);
|
|
if (al::getRandom(0.0f, 100.0f) < chance) {
|
|
target = rs::getClothList(scene_obj_holder)[i]->name;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
GameDataHolderAccessor accessor{scene_obj_holder};
|
|
accessor->getGameDataFile()->wearCostume(target);
|
|
}
|
|
|
|
void wearCapRandom(al::IUseSceneObjHolder* scene_obj_holder) {
|
|
const char* current = getCurrentCapTypeName(scene_obj_holder);
|
|
const char* target = "Mario";
|
|
s32 total_num = rs::calcHaveCapNum(scene_obj_holder);
|
|
if (total_num != 1) {
|
|
s32 seen_num = 1;
|
|
for (s32 i = 0; i < rs::getCapListSize(scene_obj_holder); i++) {
|
|
if (!rs::isHaveCap(scene_obj_holder, i) ||
|
|
al::isEqualString(current, rs::getClothList(scene_obj_holder)[i]->name))
|
|
continue;
|
|
f32 chance = 100.0f / (total_num - seen_num++);
|
|
if (al::getRandom(0.0f, 100.0f) < chance) {
|
|
target = rs::getCapList(scene_obj_holder)[i]->name;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
GameDataHolderAccessor accessor{scene_obj_holder};
|
|
accessor->getGameDataFile()->wearCap(target);
|
|
}
|
|
|
|
void tryWearCostumeRandomIfEnable(al::IUseSceneObjHolder* scene_obj_holder) {
|
|
if (isCostumeRandomMode(scene_obj_holder))
|
|
wearCostumeRandom(scene_obj_holder);
|
|
}
|
|
|
|
void tryWearCapRandomIfEnable(al::IUseSceneObjHolder* scene_obj_holder) {
|
|
if (isCapRandomMode(scene_obj_holder))
|
|
wearCapRandom(scene_obj_holder);
|
|
}
|
|
|
|
bool isCostumeRandomMode(al::IUseSceneObjHolder* scene_obj_holder) {
|
|
GameDataHolderAccessor accessor{scene_obj_holder};
|
|
return accessor->getGameDataFile()->isCostumeRandom();
|
|
}
|
|
|
|
bool isCapRandomMode(al::IUseSceneObjHolder* scene_obj_holder) {
|
|
GameDataHolderAccessor accessor{scene_obj_holder};
|
|
return accessor->getGameDataFile()->isCapRandom();
|
|
}
|
|
|
|
void setCostumeRandomMode(al::IUseSceneObjHolder* scene_obj_holder) {
|
|
GameDataHolderAccessor accessor{scene_obj_holder};
|
|
accessor->getGameDataFile()->setCostumeRandom(true);
|
|
rs::trySavePrepoChangeClothEvent("Random", getPlayTimeTotal(scene_obj_holder),
|
|
getSaveDataIdForPrepo(scene_obj_holder),
|
|
getPlayTimeAcrossFile(scene_obj_holder));
|
|
}
|
|
|
|
void setCapRandomMode(al::IUseSceneObjHolder* scene_obj_holder) {
|
|
GameDataHolderAccessor accessor{scene_obj_holder};
|
|
accessor->getGameDataFile()->setCapRandom(true);
|
|
rs::trySavePrepoChangeCapEvent("Random", getPlayTimeTotal(scene_obj_holder),
|
|
getSaveDataIdForPrepo(scene_obj_holder),
|
|
getPlayTimeAcrossFile(scene_obj_holder));
|
|
}
|
|
|
|
void resetCostumeRandomMode(al::IUseSceneObjHolder* scene_obj_holder) {
|
|
GameDataHolderAccessor accessor{scene_obj_holder};
|
|
accessor->getGameDataFile()->setCostumeRandom(false);
|
|
}
|
|
|
|
void resetCapRandomMode(al::IUseSceneObjHolder* scene_obj_holder) {
|
|
GameDataHolderAccessor accessor{scene_obj_holder};
|
|
accessor->getGameDataFile()->setCapRandom(false);
|
|
}
|
|
|
|
const sead::PtrArray<ShopItem::ShopItemInfo>& getShopItemInfoList(GameDataHolderAccessor accessor) {
|
|
return *&accessor->getShopItemInfoList();
|
|
}
|
|
|
|
bool isExistHackObjInfo(GameDataHolderAccessor accessor, const char* hack_name) {
|
|
return getHackObjInfo(accessor, hack_name) != nullptr;
|
|
}
|
|
|
|
const HackObjInfo* getHackObjInfo(GameDataHolderAccessor accessor, const char* hack_name) {
|
|
const sead::PtrArray<HackObjInfo>& list = accessor->getHackObjList();
|
|
for (s32 i = 0; i < list.size(); i++)
|
|
if (al::isEqualString(list.unsafeAt(i)->hackName, hack_name))
|
|
return list.unsafeAt(i);
|
|
return nullptr;
|
|
}
|
|
|
|
void addHackDictionary(GameDataHolderWriter writer, const char* hack_name) {
|
|
writer->getGameDataFile()->addHackDictionary(hack_name);
|
|
}
|
|
|
|
bool isExistInHackDictionary(GameDataHolderAccessor accessor, const char* hack_name) {
|
|
return accessor->getGameDataFile()->isExistInHackDictionary(hack_name);
|
|
}
|
|
|
|
bool isExistInHackDictionary(GameDataHolderAccessor accessor, const char* hack_name, s32 file_id) {
|
|
return accessor->getGameDataFile(file_id)->isExistInHackDictionary(hack_name);
|
|
}
|
|
|
|
bool isShowHackTutorial(GameDataHolderAccessor accessor, const char* hack_name,
|
|
const char* suffix) {
|
|
return accessor->isShowHackTutorial(hack_name, suffix);
|
|
}
|
|
|
|
void setShowHackTutorial(GameDataHolderWriter writer, const char* hack_name, const char* suffix) {
|
|
writer->setShowHackTutorial(hack_name, suffix);
|
|
}
|
|
|
|
bool isShowBindTutorial(GameDataHolderAccessor accessor, const BindInfo& bind_info) {
|
|
return accessor->isShowBindTutorial(bind_info.name);
|
|
}
|
|
|
|
void setShowBindTutorial(GameDataHolderWriter writer, const BindInfo& bind_info) {
|
|
writer->setShowBindTutorial(bind_info.name);
|
|
}
|
|
|
|
bool isGotShine(GameDataHolderAccessor accessor, s32 world_id, s32 index) {
|
|
return accessor->getGameDataFile()->isGotShine(world_id, index);
|
|
}
|
|
|
|
bool isOpenShineName(const al::LayoutActor* layout, s32 world_id, s32 index) {
|
|
GameDataHolderAccessor accessor{layout};
|
|
return accessor->getGameDataFile()->isOpenShineName(world_id, index);
|
|
}
|
|
|
|
bool checkAchievementShine(const al::LayoutActor* layout, s32 world_id, s32 index) {
|
|
GameDataHolderAccessor accessor{layout};
|
|
return accessor->getGameDataFile()->checkAchievementShine(world_id, index);
|
|
}
|
|
|
|
s32 calcShineNumInOneShine(const al::LayoutActor* layout, s32 world_id, s32 index) {
|
|
GameDataHolderAccessor accessor{layout};
|
|
return sead::Mathi::clampMax(
|
|
accessor->getGameDataFile()->calcShineNumInOneShine(world_id, index), 99);
|
|
}
|
|
|
|
ALWAYS_INLINE static const char16* getShineMessage(const al::IUseSceneObjHolder* scene_obj_holder,
|
|
const al::IUseMessageSystem* message_system,
|
|
s32 world_id, s32 index) {
|
|
const GameDataFile::HintInfo* info =
|
|
getGameDataHolder(scene_obj_holder)->getGameDataFile()->findShine(world_id, index);
|
|
al::StringTmp<128> label;
|
|
al::PlacementId placement_id{info->objId.cstr(), nullptr, nullptr};
|
|
rs::makeMessageLabel(&label, &placement_id, "ScenarioName");
|
|
return al::isExistLabelInStageMessage(message_system, info->stageName.cstr(), label.cstr()) ?
|
|
al::getStageMessageString(message_system, info->stageName.cstr(), label.cstr()) :
|
|
u"シャイン名未設定";
|
|
}
|
|
|
|
const char16* tryFindShineMessage(const al::LayoutActor* layout, s32 world_id, s32 index) {
|
|
return getShineMessage(layout, layout, world_id, index);
|
|
}
|
|
|
|
const char16* tryFindShineMessage(const al::LiveActor* actor,
|
|
const al::IUseMessageSystem* message_system, s32 world_id,
|
|
s32 index) {
|
|
return getShineMessage(actor, message_system, world_id, index);
|
|
}
|
|
|
|
u64 findShineGetTime(const al::LayoutActor* layout, s32 world_id, s32 index) {
|
|
return getGameDataHolder(layout)->getGameDataFile()->findShine(world_id, index)->getTime;
|
|
}
|
|
|
|
bool checkMoonRockShineForShineList(const al::LayoutActor* layout, s32 world_id, s32 index) {
|
|
return getGameDataHolder(layout)->getGameDataFile()->findShine(world_id, index)->isMoonRock;
|
|
}
|
|
|
|
bool checkUnlockHintByHintNpcForShineList(const al::LayoutActor* layout, s32 world_id, s32 index) {
|
|
return getGameDataHolder(layout)
|
|
->getGameDataFile()
|
|
->findShine(world_id, index)
|
|
->isHintStatusUnlockByNpc();
|
|
}
|
|
|
|
bool checkUnlockHintByAmiiboForShineList(const al::LayoutActor* layout, s32 world_id, s32 index) {
|
|
return getGameDataHolder(layout)
|
|
->getGameDataFile()
|
|
->findShine(world_id, index)
|
|
->isHintStatusUnlockByAmiibo();
|
|
}
|
|
|
|
bool checkShineSeaOfTreeForShineList(const al::LayoutActor* layout, s32 world_id, s32 index) {
|
|
return isSeaOfTreeStage(
|
|
getGameDataHolder(layout)->getGameDataFile()->findShine(world_id, index)->stageName.cstr());
|
|
}
|
|
|
|
s32 getWorldTotalShineNum(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getGameDataFile()->getWorldTotalShineNum(world_id);
|
|
}
|
|
|
|
s32 getWorldTotalShineNumMax(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->getGameDataFile()->getWorldTotalShineNumMax(world_id);
|
|
}
|
|
|
|
void findShineTrans(sead::Vector3f* out, GameDataHolderAccessor accessor, s32 world_id, s32 index) {
|
|
out->set(accessor->getGameDataFile()->findShine(world_id, index)->trans);
|
|
}
|
|
|
|
const sead::Vector3f& getHomeTrans(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getHomeTrans();
|
|
}
|
|
|
|
bool isExistHome(GameDataHolderAccessor accessor) {
|
|
return isGameClear(accessor) || (isActivateHome(accessor) && isUnlockedCurrentWorld(accessor));
|
|
}
|
|
|
|
bool isActivateHome(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getGameProgressData()->isActivateHome();
|
|
}
|
|
|
|
s32 getMiniGameNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->calcMiniGameNum();
|
|
}
|
|
|
|
s32 getMiniGameNumMax(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getMiniGameNumMax();
|
|
}
|
|
|
|
const sead::Vector3f& getMiniGameTrans(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->getMiniGameTrans(index);
|
|
}
|
|
|
|
const char* getMiniGameName(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->getMiniGameName(index);
|
|
}
|
|
|
|
const sead::Vector3f& getRaceStartTrans(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getRaceStartTrans();
|
|
}
|
|
|
|
const sead::Vector3f& getRaceGoalTrans(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getRaceGoalTrans();
|
|
}
|
|
|
|
const sead::Vector3f& getHintNpcTrans(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getHintNpcTrans();
|
|
}
|
|
|
|
const sead::Vector3f& getShopNpcTrans(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->getShopNpcTrans(index);
|
|
}
|
|
|
|
bool isShopSellout(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->isShopSellout(index);
|
|
}
|
|
|
|
s32 calcShopNum(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->calcShopNum();
|
|
}
|
|
|
|
s32 getShopNpcIconNumMax(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getShopNpcIconNumMax();
|
|
}
|
|
|
|
bool isExistRaceStartNpc(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isExistRaceStartNpc();
|
|
}
|
|
|
|
bool isExistHintNpc(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isExistHintNpc();
|
|
}
|
|
|
|
const sead::Matrix34f& getCurrentMapView(GameDataHolderAccessor accessor) {
|
|
return accessor->getMapDataHolder()->findViewMtx(getCurrentWorldIdNoDevelop(accessor));
|
|
}
|
|
|
|
bool isExistJango(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isExistJango();
|
|
}
|
|
|
|
const sead::Vector3f& getJangoTrans(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getJangoTrans();
|
|
}
|
|
|
|
bool isExistAmiiboNpc(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isExistAmiiboNpc();
|
|
}
|
|
|
|
const sead::Vector3f& getAmiiboNpcTrans(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getAmiiboNpcTrans();
|
|
}
|
|
|
|
bool isInInvalidOpenMapStage(GameDataHolderAccessor accessor) {
|
|
return accessor->isInvalidOpenMapStage(getCurrentStageName(accessor),
|
|
getScenarioNoImpl(accessor));
|
|
}
|
|
|
|
const sead::Vector3f& getStageMapPlayerPos(GameDataHolderAccessor accessor) {
|
|
return accessor->getStageMapPlayerPos();
|
|
}
|
|
|
|
bool isExistTimeBalloonNpc(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isExistTimeBalloonNpc();
|
|
}
|
|
|
|
const sead::Vector3f& getTimeBalloonNpcTrans(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getTimeBalloonNpcTrans();
|
|
}
|
|
|
|
bool isExistPoetter(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isExistPoetter();
|
|
}
|
|
|
|
const sead::Vector3f& getPoetterTrans(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getPoetterTrans();
|
|
}
|
|
|
|
const sead::Vector3f& getMoonRockTrans(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getMoonRockTrans();
|
|
}
|
|
|
|
void setHomeTrans(const al::LiveActor* actor, const sead::Vector3f& trans) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->setHomeTrans(trans);
|
|
}
|
|
|
|
void setRaceStartNpcTrans(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->setRaceStartNpcTrans(al::getTrans(actor));
|
|
}
|
|
|
|
void setRaceStartTrans(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->setRaceStartTrans(al::getTrans(actor));
|
|
}
|
|
|
|
void setRaceGoalTrans(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->setRaceGoalTrans(al::getTrans(actor));
|
|
}
|
|
|
|
void setHintNpcTrans(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->setHintNpcTrans(al::getTrans(actor));
|
|
}
|
|
|
|
void setJangoTrans(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->setJangoTrans(al::getTrans(actor));
|
|
}
|
|
|
|
void disableJangoTrans(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->disableJangoTrans();
|
|
}
|
|
|
|
void setAmiiboNpcTrans(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->setAmiiboNpcTrans(al::getTrans(actor));
|
|
}
|
|
|
|
void setShopNpcTrans(const al::LiveActor* actor, const char* name, s32 type) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->setShopNpcTrans(al::getTrans(actor), name, type);
|
|
}
|
|
|
|
void setShopNpcTrans(GameDataHolderAccessor accessor, const al::PlacementInfo& placement_info) {
|
|
sead::Vector3f trans = sead::Vector3f::zero;
|
|
al::getTrans(&trans, placement_info);
|
|
const char* name = nullptr;
|
|
if (al::tryGetStringArg(&name, placement_info, "StoreName"))
|
|
accessor->getGameDataFile()->setShopNpcTrans(trans, name, 0);
|
|
}
|
|
|
|
void setMiniGameInfo(GameDataHolderAccessor accessor, const al::PlacementInfo& placement_info) {
|
|
sead::Vector3f trans = sead::Vector3f::zero;
|
|
al::getTrans(&trans, placement_info);
|
|
const char* name = nullptr;
|
|
if (al::tryGetStringArg(&name, placement_info, "MiniGameName"))
|
|
accessor->getGameDataFile()->setMiniGameInfo(trans, name);
|
|
}
|
|
|
|
void setTimeBalloonTrans(GameDataHolderAccessor accessor, const sead::Vector3f& trans) {
|
|
accessor->getGameDataFile()->setTimeBalloonNpcTrans(trans);
|
|
}
|
|
|
|
void setPoetterTrans(GameDataHolderAccessor accessor, const sead::Vector3f& trans) {
|
|
accessor->getGameDataFile()->setPoetterTrans(trans);
|
|
}
|
|
|
|
void setStageMapPlayerPos(GameDataHolderWriter writer, const sead::Vector3f& pos) {
|
|
writer->setStageMapPlayerPos(pos);
|
|
}
|
|
|
|
void setMoonRockTrans(GameDataHolderWriter writer, const sead::Vector3f& trans) {
|
|
writer->getGameDataFile()->setMoonRockTrans(trans);
|
|
}
|
|
|
|
s32 getHomeLevel(GameDataHolderAccessor accessor) {
|
|
if (rs::isModeE3Rom() || rs::isModeE3LiveRom())
|
|
return 3;
|
|
return accessor->getGameDataFile()->getGameProgressData()->getHomeLevel();
|
|
}
|
|
|
|
void upHomeLevel(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->getGameProgressData()->upHomeLevel();
|
|
}
|
|
|
|
void activateHome(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->setActivateHome();
|
|
}
|
|
|
|
bool isLaunchHome(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getGameProgressData()->isLaunchHome();
|
|
}
|
|
|
|
void launchHome(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->getGameProgressData()->launchHome();
|
|
}
|
|
|
|
bool isCrashHome(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getGameProgressData()->isCrashHome();
|
|
}
|
|
|
|
void crashHome(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->getGameProgressData()->crashHome();
|
|
}
|
|
|
|
bool isRepairHome(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getGameProgressData()->isRepairHome();
|
|
}
|
|
|
|
void repairHome(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->getGameProgressData()->repairHome();
|
|
}
|
|
|
|
bool isBossAttackedHome(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getGameProgressData()->isBossAttackedHome();
|
|
}
|
|
|
|
void bossAttackHome(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->getGameProgressData()->bossAttackHome();
|
|
}
|
|
|
|
bool isRepairHomeByCrashedBoss(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getGameProgressData()->isRepairHomeByCrashedBoss();
|
|
}
|
|
|
|
void repairHomeByCrashedBoss(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->getGameProgressData()->repairHomeByCrashedBoss();
|
|
}
|
|
|
|
bool isFindKoopaNext(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->isFindKoopaNext(world_id);
|
|
}
|
|
|
|
bool isBossAttackedHomeNext(GameDataHolderAccessor accessor, s32 world_id) {
|
|
return accessor->isBossAttackedHomeNext(world_id);
|
|
}
|
|
|
|
bool isFindKoopa(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->getGameProgressData()->isFindKoopa();
|
|
}
|
|
|
|
void findKoopa(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->getGameProgressData()->findKoopa();
|
|
}
|
|
|
|
bool isEnableCap(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isEnableCap();
|
|
}
|
|
|
|
bool isMeetCap(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isMeetCap();
|
|
}
|
|
|
|
void enableCap(GameDataHolderWriter writer) {
|
|
writer->getGameDataFile()->meetCap();
|
|
}
|
|
|
|
void disableCapByPlacement(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->disableCapByPlacement();
|
|
}
|
|
|
|
bool isTalkedCapNearHomeInWaterfall(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
return accessor->getGameDataFile()->getGameProgressData()->isTalkedCapNearHomeInWaterfall();
|
|
}
|
|
|
|
void talkCapNearHomeInWaterfall(const al::LiveActor* actor) {
|
|
GameDataHolderAccessor accessor{actor};
|
|
accessor->getGameDataFile()->getGameProgressData()->talkCapNearHomeInWaterfall();
|
|
}
|
|
|
|
bool isFlagOnTalkMessageInfo(const al::IUseSceneObjHolder* scene_obj_holder, s32 index) {
|
|
GameDataHolderAccessor accessor{scene_obj_holder};
|
|
return accessor->getGameDataFile()->isFlagOnTalkMessageInfo(index);
|
|
}
|
|
|
|
void onFlagTalkMessageInfo(const al::IUseSceneObjHolder* scene_obj_holder, s32 index) {
|
|
GameDataHolderAccessor accessor{scene_obj_holder};
|
|
accessor->getGameDataFile()->setFlagOnTalkMessageInfo(index);
|
|
}
|
|
|
|
s32 getWorldIndexHat() {
|
|
return 0;
|
|
}
|
|
|
|
s32 getWorldIndexWaterfall() {
|
|
return 1;
|
|
}
|
|
|
|
s32 getWorldIndexSand() {
|
|
return 2;
|
|
}
|
|
|
|
s32 getWorldIndexForest() {
|
|
return 3;
|
|
}
|
|
|
|
s32 getWorldIndexLake() {
|
|
return 4;
|
|
}
|
|
|
|
s32 getWorldIndexCloud() {
|
|
return 5;
|
|
}
|
|
|
|
s32 getWorldIndexClash() {
|
|
return 6;
|
|
}
|
|
|
|
s32 getWorldIndexCity() {
|
|
return 7;
|
|
}
|
|
|
|
s32 getWorldIndexSea() {
|
|
return 8;
|
|
}
|
|
|
|
s32 getWorldIndexSnow() {
|
|
return 9;
|
|
}
|
|
|
|
s32 getWorldIndexLava() {
|
|
return 10;
|
|
}
|
|
|
|
s32 getWorldIndexBoss() {
|
|
return 11;
|
|
}
|
|
|
|
s32 getWorldIndexSky() {
|
|
return 12;
|
|
}
|
|
|
|
s32 getWorldIndexMoon() {
|
|
return 13;
|
|
}
|
|
|
|
s32 getWorldIndexPeach() {
|
|
return 14;
|
|
}
|
|
|
|
s32 getWorldIndexSpecial1() {
|
|
return 15;
|
|
}
|
|
|
|
s32 getWorldIndexSpecial2() {
|
|
return 16;
|
|
}
|
|
|
|
bool isWorldCap(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "Cap");
|
|
}
|
|
|
|
bool isWorldWaterfall(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)),
|
|
"Waterfall");
|
|
}
|
|
|
|
bool isWorldSand(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "Sand");
|
|
}
|
|
|
|
bool isWorldForest(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "Forest");
|
|
}
|
|
|
|
bool isWorldLake(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "Lake");
|
|
}
|
|
|
|
bool isWorldCloud(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "Cloud");
|
|
}
|
|
|
|
bool isWorldClash(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "Clash");
|
|
}
|
|
|
|
bool isWorldCity(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "City");
|
|
}
|
|
|
|
bool isWorldSnow(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "Snow");
|
|
}
|
|
|
|
bool isWorldSea(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "Sea");
|
|
}
|
|
|
|
bool isWorldBoss(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "Attack");
|
|
}
|
|
|
|
bool isWorldSky(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "Sky");
|
|
}
|
|
|
|
bool isWorldMoon(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "Moon");
|
|
}
|
|
|
|
bool isWorldPeach(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)), "Peach");
|
|
}
|
|
|
|
bool isWorldSpecial1(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)),
|
|
"Special1");
|
|
}
|
|
|
|
bool isWorldSpecial2(GameDataHolderAccessor accessor) {
|
|
return al::isEqualString(getWorldDevelopName(accessor, getCurrentWorldId(accessor)),
|
|
"Special2");
|
|
}
|
|
|
|
bool isWorldTypeMoon(GameDataHolderAccessor, s32 world_id) {
|
|
return world_id == getWorldIndexMoon() || world_id == getWorldIndexSpecial1() ||
|
|
world_id == getWorldIndexSpecial2();
|
|
}
|
|
|
|
bool isSnowMainScenario1(const al::IUseSceneObjHolder* scene_obj_holder) {
|
|
return rs::getActiveQuestNum(scene_obj_holder) > 0 &&
|
|
rs::getActiveQuestList(scene_obj_holder)[0]->getQuestNo() == 0;
|
|
}
|
|
|
|
bool isSnowMainScenario2(const al::IUseSceneObjHolder* scene_obj_holder) {
|
|
return rs::getActiveQuestNum(scene_obj_holder) > 0 &&
|
|
rs::getActiveQuestList(scene_obj_holder)[0]->getQuestNo() == 1;
|
|
}
|
|
|
|
bool isHomeShipStage(const GameDataHolder* game_data_holder) {
|
|
return al::isEqualString(game_data_holder->getCurrentStageName(), getHomeShipStageName());
|
|
}
|
|
|
|
const char* getHomeShipStageName() {
|
|
return "HomeShipInsideStage";
|
|
}
|
|
|
|
bool isCityWorldCeremonyAll(s32 world_id, s32 scenario_no) {
|
|
if (world_id != getWorldIndexCity())
|
|
return false;
|
|
switch (scenario_no) {
|
|
case 3:
|
|
case 7:
|
|
case 11:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool isCityWorldCeremonyAgain(s32 world_id, s32 scenario_no) {
|
|
if (world_id != getWorldIndexCity())
|
|
return false;
|
|
switch (scenario_no) {
|
|
case 7:
|
|
case 11:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool isGoToCeremonyFromInsideHomeShip(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isGoToCeremonyFromInsideHomeShip();
|
|
}
|
|
|
|
void registerScenarioStartCameraInfo(const ScenarioStartCamera* actor, s32 id,
|
|
al::CameraTicket* camera) {
|
|
getGameDataHolder(actor)->getTemporaryScenarioCameraHolder()->registInfo(id, camera);
|
|
}
|
|
|
|
bool isEnableExplainAmiibo(GameDataHolderAccessor accessor) {
|
|
return accessor->isEnableExplainAmiibo();
|
|
}
|
|
|
|
void endExplainAmiibo(GameDataHolderWriter writer) {
|
|
writer->disableExplainAmiibo();
|
|
}
|
|
|
|
void startSearchHintByAmiibo(GameDataHolderWriter writer) {
|
|
writer->startSearchHintByAmiibo();
|
|
}
|
|
|
|
void endSearchHintByAmiibo(GameDataHolderWriter writer) {
|
|
writer->endSearchHintByAmiibo();
|
|
}
|
|
|
|
void setKidsModeOn(const al::Scene* scene) {
|
|
GameDataHolderAccessor accessor{scene};
|
|
accessor->getGameDataFile()->setKidsMode(true);
|
|
}
|
|
|
|
void setKidsModeOff(const al::Scene* scene) {
|
|
GameDataHolderAccessor accessor{scene};
|
|
accessor->getGameDataFile()->setKidsMode(false);
|
|
}
|
|
|
|
bool isCollectedBgm(GameDataHolderAccessor accessor, const char* name, const char* situation_name) {
|
|
return accessor->getGameDataFile()->isCollectedBgm(name, situation_name);
|
|
}
|
|
|
|
const CollectBgm& getCollectBgmByIndex(GameDataHolderAccessor accessor, s32 index) {
|
|
return accessor->getGameDataFile()->getCollectBgmByIndex(index);
|
|
}
|
|
|
|
bool trySetCollectedBgm(GameDataHolderWriter writer, const char* name, const char* situation_name) {
|
|
return writer->getGameDataFile()->trySetCollectedBgm(name, situation_name);
|
|
}
|
|
|
|
s32 getCollectedBgmNum(GameDataHolderWriter writer) {
|
|
return writer->getGameDataFile()->getCollectedBgmNum();
|
|
}
|
|
|
|
s32 getCollectedBgmNum(GameDataHolderAccessor accessor, s32 file_id) {
|
|
return accessor->getGameDataFile(file_id)->getCollectedBgmNum();
|
|
}
|
|
|
|
s32 getCollectedBgmMaxNum(GameDataHolderWriter writer) {
|
|
return writer->getGameDataFile()->getCollectedBgmMaxNum();
|
|
}
|
|
|
|
void registerShineInfo(GameDataHolderAccessor accessor, const ShineInfo* info,
|
|
const sead::Vector3f& trans) {
|
|
accessor->getGameDataFile()->registerShineInfo(info, trans);
|
|
}
|
|
|
|
void setHintTrans(GameDataHolderAccessor accessor, s32 index, const sead::Vector3f& trans) {
|
|
if (isMainStage(accessor))
|
|
accessor->getGameDataFile()->setHintTrans(index, trans);
|
|
}
|
|
|
|
void resetHintTrans(GameDataHolderAccessor accessor, s32 index) {
|
|
accessor->getGameDataFile()->resetHintTrans(index);
|
|
}
|
|
|
|
bool isKoopaLv3(GameDataHolderAccessor accessor) {
|
|
return accessor->getGameDataFile()->isKoopaLv3();
|
|
}
|
|
|
|
} // namespace GameDataFunction
|