Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leoetlino/6e08d1626e5e082a03ce7be9fd91efed to your computer and use it in GitHub Desktop.
Save leoetlino/6e08d1626e5e082a03ce7be9fd91efed to your computer and use it in GitHub Desktop.
bool MapIcon::Tower::isVisited() const {
gmd::StructHandle IsVisitLocation;
if (!gmd::GameDataMgr::instance()->getStruct(&IsVisitLocation, "IsVisitLocation")) {
return false;
}
bool visited;
if (!gmd::GameDataMgr::instance()->getBool(&visited, IsVisitLocation, mLocationNameHash)) {
return false;
}
return visited;
}
bool MapIcon::Shrine::isVisited() const {
gmd::StructHandle IsVisitLocation;
if (!gmd::GameDataMgr::instance()->getStruct(&IsVisitLocation, "IsVisitLocation")) {
return false;
}
bool visited;
if (!gmd::GameDataMgr::instance()->getBool2(&visited, IsVisitLocation, mLocationNameHash)) {
return false;
}
return visited;
}
bool MapIcon::LargeDungeon::isVisited() const {
gmd::StructHandle IsVisitLocation;
if (!gmd::GameDataMgr::instance()->getStruct(&IsVisitLocation, "IsVisitLocation")) {
return false;
}
bool visited;
if (!gmd::GameDataMgr::instance()->getBool(&visited, IsVisitLocation, mNameHash)) {
return false;
}
return visited;
}
bool MapIcon::Cave::isVisited() const {
gmd::StructHandle IsVisitLocation;
if (!gmd::GameDataMgr::instance()->getStruct(&IsVisitLocation, "IsVisitLocation")) {
return false;
}
bool visited;
if (!gmd::GameDataMgr::instance()->getBool2(&visited, IsVisitLocation, mLocationNameHash) ||
!visited) {
return false;
}
if (mInstanceIdHash != 0) {
bool visited_cave = true;
gmd::StructHandle IsVisitLocationArea_CaveEntrance;
if (gmd::GameDataMgr::instance()->getStruct(&IsVisitLocationArea_CaveEntrance,
"IsVisitLocationArea_CaveEntrance")) {
gmd::GameDataMgr::instance()->getBool(&visited_cave, IsVisitLocationArea_CaveEntrance,
mInstanceIdHash);
if (!visited_cave) {
return false;
}
}
}
return true;
}
bool MapIcon::Spot::isVisited() const {
auto* location_table = RSDB::instance()->Location;
if (!location_table) {
return false;
}
const auto& location = location_table->rows[mLocationIdx];
const auto category = location.Category;
const auto dependence_location_hash = location.DependenceLocationHash;
switch (category) {
case LocationCategory::SkyArchipelago:
case LocationCategory::SpotBigWater:
case LocationCategory::SpotBigArtifact:
case LocationCategory::SpotBigMagma:
case LocationCategory::SpotBigTimber:
case LocationCategory::SpotBigMountain:
case LocationCategory::SpotBigOther:
case LocationCategory::SpotMiddleWater:
case LocationCategory::SpotMiddleArtifact:
case LocationCategory::SpotMiddleMagma:
case LocationCategory::SpotMiddleTimber:
case LocationCategory::SpotMiddleMountain:
case LocationCategory::SpotMiddleOther:
case LocationCategory::SpotBigWithNameIcon: {
gmd::StructHandle handle;
if (!gmd::GameDataMgr::instance()->getStruct(&handle, "IsVisitLocation")) {
return false;
}
bool value;
if (!gmd::GameDataMgr::instance()->getBool(&value, handle, mLocationNameHash)) {
return false;
}
return value;
}
case LocationCategory::District:
case LocationCategory::SpotSmallWater:
case LocationCategory::SpotSmallArtifact:
case LocationCategory::SpotSmallMagma:
case LocationCategory::SpotSmallTimber:
case LocationCategory::SpotSmallMountain:
case LocationCategory::SpotSmallOther: {
if (dependence_location_hash == 0) {
return true;
}
gmd::StructHandle handle;
if (!gmd::GameDataMgr::instance()->getStruct(&handle, "IsOpenCannon")) {
return false;
}
bool value;
gmd::GameDataMgr::instance()->getBool2(&value, handle, dependence_location_hash);
return value;
}
default:
return false;
}
}
bool MapIcon::SpecialWarpPoint::isVisited() const {
if (!unkGmdGetter(0x34326518)) {
return false;
}
bool value = false;
switch (mType) {
case 0:
// WarpPos_StartIsland_WakeupAltar
return true;
case 1:
// WarpPoint_BlueprintShrine
gmd::GameDataMgr::instance()->getBool(&value, "OpenWarpPoint_BlueprintShrine");
return value;
}
return false;
}
bool MapIcon::Labo::isVisited() const {
gmd::StructHandle handle;
if (!gmd::GameDataMgr::instance()->getStruct(&handle, "IsVisitLocation")) {
return false;
}
bool value;
if (!gmd::GameDataMgr::instance()->getBool2(&value, handle, mLocationNameHash)) {
return false;
}
return value;
}
bool MapIcon::PlaceOfInterest::isVisited() const {
bool value = false;
// from the game::location::Location
if (mOverrideIconFlagHash != 0) {
if (mOverrideIconFlagType == 0) {
gmd::GameDataMgr::instance()->getBool(&value, mOverrideIconFlagHash);
} else {
gmd::GameDataMgr::instance()->getBoolExp(&value, mOverrideIconFlagHash);
}
} else {
gmd::StructHandle handle;
if (gmd::GameDataMgr::instance()->getStruct(&handle, "IsVisitLocation")) {
gmd::GameDataMgr::instance()->getBool2(&value, handle, mLocationNameHash);
}
}
return value;
}
bool MapIcon::Shop::isVisited() const {
auto* location_table = RSDB::instance()->Location;
if (!location_table) {
return false;
}
const auto& location = location_table->rows[mLocationIdx];
const auto dependence_location_hash = location.DependenceLocationHash;
const auto override_icon_flag_hash = location.OverrideIconFlagHash;
bool value = false;
if (override_icon_flag_hash != 0) {
if (mIsBoolExpFlag) {
gmd::GameDataMgr::instance()->getBoolExp(&value, override_icon_flag_hash);
} else {
gmd::GameDataMgr::instance()->getBool(&value, override_icon_flag_hash);
}
} else {
gmd::StructHandle handle;
if (gmd::GameDataMgr::instance()->getStruct(&handle, "IsVisitLocation")) {
gmd::GameDataMgr::instance()->getBool2(&value, handle, dependence_location_hash);
}
}
return value;
}
bool MapIcon::FairyFountain::isVisited() const {
// flag names from:
// GameParameter/FairyFountainGlobalSetting/Default.game__ui__FairyFountainGlobalSetting.bgyml
//
// - Fairy_MapOpen
// - Fairy_MapOpen_DressFairy_00
// - Fairy_MapOpen_DressFairy_01
// - Fairy_MapOpen_DressFairy_02
// - HaveTalked.HorseGod001
if (mHaveKnownFlagHash == 0) {
return true;
}
bool value;
if (mHaveKnownFlagType == 0) {
if (!gmd::GameDataMgr::instance()->getBool(&value, mHaveKnownFlagHash)) {
return false;
}
} else {
if (!gmd::GameDataMgr::instance()->getBoolExp(&value, mHaveKnownFlagHash)) {
return false;
}
}
return value;
}
bool MapIcon::ImportantShop::isVisited() const {
// EvilStatue "HaveKnownFlag":
// - HaveKnownDemonStatue_00
// - HaveKnownDemonStatue_01
// - HaveKnownDemonStatue_02
// - HaveKnownDemonStatue_03
// - HaveKnownDemonStatue_04
// - HaveKnownDemonStatue_05
// otherwise, the flag is the location's OverrideIconFlagHash
if (mFlagHash == 0) {
return true;
}
bool value;
if (mFlagType == 0) {
if (!gmd::GameDataMgr::instance()->getBool(&value, mFlagHash)) {
return false;
}
} else {
if (!gmd::GameDataMgr::instance()->getBoolExp(&value, mFlagHash)) {
return false;
}
}
return value;
}
bool MapIcon::ZonauRelief::isVisited() const {
auto* location_table = RSDB::instance()->Location;
if (!location_table) {
return false;
}
const auto& location = location_table->rows[mLocationIdx];
const auto override_icon_flag_hash = location.OverrideIconFlagHash;
if (override_icon_flag_hash == 0) {
return true;
}
bool value;
if (mIsBoolExpFlag) {
gmd::GameDataMgr::instance()->getBoolExp(&value, override_icon_flag_hash);
} else {
gmd::GameDataMgr::instance()->getBool(&value, override_icon_flag_hash);
}
return value;
}
float MapIcon::calcMapCompletion() const {
int count = 0;
int total = 0;
// Towers
//
// LocationArea category: Tower
total += mTowers.size();
for (const Tower* tower : mTowers) {
count += tower->isVisited();
}
// Shrines and Lightroots
//
// LocationArea categories: Shrine, CheckPoint
// - must have OverrideIconType = None
for (const Shrine& shrine : mShrines) {
count += shrine.isVisited();
sead::FixedSafeString<256> name;
shrine.getName(&name); // unused debug code?
}
total += mShrines.size();
// Temples
//
// LargeDungeonWater/Fire/Wind/Thunder/Soul
for (const LargeDungeon* dungeon : mLargeDungeons) {
count += dungeon->isVisited();
}
total += mLargeDungeons.size();
// Caves
//
// LocationArea categories: CaveEntranceNormal, CaveEntranceSpecial, CaveEntranceWell
// - must have OverrideIconType = None
// - each entry can have multiple Trans values; each position generates a marker
for (const Cave& cave : mCaves) {
count += cave.isVisited();
sead::FixedSafeString<256> name;
cave.getName(&name);
}
total += mCaves.size();
// Spots
//
// LocationArea categories:
// ['District', 'SkyArchipelago', 'SpotBigWater', 'SpotBigArtifact', 'SpotBigMagma',
// 'SpotBigTimber', 'SpotBigMountain', 'SpotBigOther', 'SpotMiddleWater', 'SpotMiddleArtifact',
// 'SpotMiddleMagma', 'SpotMiddleTimber', 'SpotMiddleMountain', 'SpotMiddleOther',
// 'SpotSmallWater', 'SpotSmallArtifact', 'SpotSmallMagma', 'SpotSmallTimber',
// 'SpotSmallMountain', 'SpotSmallOther', 'SpotBigWithNameIcon']
//
// - must have OverrideIconType = None
// - each entry can have multiple Trans values; each position generates a marker
// (up to a maximum of 32)
for (const Spot& spot : mSpots) {
count += spot.isVisited();
sead::FixedSafeString<256> name;
spot.getName(&name);
}
total += mSpots.size();
// Special fast travel locations
//
// WarpPos_StartIsland_WakeupAltar
// WarpPoint_BlueprintShrine
for (const SpecialWarpPoint& warp_point : mSpecialWarpPoints) {
count += warp_point.isVisited();
}
total += mSpecialWarpPoints.size();
// Hateno lab
count += mHatenoLabo->isVisited();
total += 1;
// Places of interest
//
// - LocationArea categories: City, Stable
// - must have OverrideIconType = None
//
// - LocationArea (any category)
// - must have OverrideIconType = ['Building', 'Castle', 'NewspaperPublisher',
// 'PlayerHouse', 'JobField']
for (const PlaceOfInterest* place : mPlacesOfInterest) {
count += place->isVisited();
}
total += mPlacesOfInterest.size();
// Shops (and places that are not actually shops)
//
// - LocationArea categories: ['ShopInn', 'ShopGeneral', 'ShopArmor', 'ShopDye', 'ShopJewelry']
// - must have OverrideIconType = None
// - each entry can have multiple Trans values; each position generates a marker
//
// - LocationArea (any category)
// - must have OverrideIconType = ['SmallEvilStatue', 'TreasureBoxShop', 'CookingShop',
// 'ScrapShop', 'Bar', 'RentalZarashiShop', 'HorseStableBranchOffice', 'FigureGallery',
// 'InvestigatingGroupBase', 'Farm', 'School', 'Circuit_Uotori', 'Circuit_Ichikara']
// - each entry can have multiple Trans values; each position generates a marker
for (const Shop& shop : mShops) {
count += shop.isVisited();
sead::FixedSafeString<256> name;
shop.getName(&name);
}
total += mShops.size();
// Koroks
// (self-explanatory so I won't bother decompiling isVisited())
for (const Korok& korok : mKoroks) {
count += korok.isVisited();
}
total += mKoroks.size();
// Device dispensers
for (const RecycleBox& box : mRecycleBoxes) {
count += box.isVisited();
}
total += mRecycleBoxes.size();
// Dragon tears
for (const DragonTear* tear : mDragonTears) {
count += tear->isVisited();
}
total += mDragonTears.size();
// Fairy fountains
// OverrideIconType = ['FairyFountain', 'HorseFairyFountain']
for (const FairyFountain* fountain : mFairyFountains) {
count += fountain->isVisited();
// + unused debug crap
}
total += mFairyFountains.size();
// Important shops
// OverrideIconType = ['EvilStatue', 'SmeltShop', 'ForgeShop', 'BatteryExchangeShop']
for (const ImportantShop* shop : mImportantShops) {
count += shop->isVisited();
// + unused debug crap
}
total += mImportantShops.size();
// Ancient stone tablets
// OverrideIconType = 'ZonauRelief'
for (const ZonauRelief& relief : mZonauReliefs) {
count += relief.isVisited();
// + unused debug crap
}
total += mZonauReliefs.size();
if (total <= 0)
return 0.0;
else
return float(count) / float(total);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment