Custom Hand DL's for each tunic take 3 (#6754)

This commit is contained in:
Jameriquiah
2026-06-21 16:46:47 -05:00
committed by GitHub
parent e4b6f1ab87
commit 6a51720194
3 changed files with 97 additions and 0 deletions
@@ -128,9 +128,21 @@ static const ALIGN_ASSET(2) char gCustomMirrorShieldOnBackDL[] = dgCustomMirrorS
#define dgCustomAdultFPSHandDL "__OTR__objects/object_custom_equip/gCustomAdultFPSHandDL"
static const ALIGN_ASSET(2) char gCustomAdultFPSHandDL[] = dgCustomAdultFPSHandDL;
#define dgCustomAdultGoronFPSHandDL "__OTR__objects/object_custom_equip/gCustomAdultGoronFPSHandDL"
static const ALIGN_ASSET(2) char gCustomAdultGoronFPSHandDL[] = dgCustomAdultGoronFPSHandDL;
#define dgCustomAdultZoraFPSHandDL "__OTR__objects/object_custom_equip/gCustomAdultZoraFPSHandDL"
static const ALIGN_ASSET(2) char gCustomAdultZoraFPSHandDL[] = dgCustomAdultZoraFPSHandDL;
#define dgCustomChildFPSHandDL "__OTR__objects/object_custom_equip/gCustomChildFPSHandDL"
static const ALIGN_ASSET(2) char gCustomChildFPSHandDL[] = dgCustomChildFPSHandDL;
#define dgCustomChildGoronFPSHandDL "__OTR__objects/object_custom_equip/gCustomChildGoronFPSHandDL"
static const ALIGN_ASSET(2) char gCustomChildGoronFPSHandDL[] = dgCustomChildGoronFPSHandDL;
#define dgCustomChildZoraFPSHandDL "__OTR__objects/object_custom_equip/gCustomChildZoraFPSHandDL"
static const ALIGN_ASSET(2) char gCustomChildZoraFPSHandDL[] = dgCustomChildZoraFPSHandDL;
#endif // OBJECTS_OBJECT_CUSTOM_EQUIP_H
+21
View File
@@ -25,6 +25,26 @@ static const char* ResolveCustomChain(std::initializer_list<const char*> paths)
return fallback;
}
static const char* ResolveCustomFPSHand(const char* path) {
const bool isAdult = path == gCustomAdultFPSHandDL;
const bool isChild = path == gCustomChildFPSHandDL;
if (!isAdult && !isChild) {
return path;
}
switch (TUNIC_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC))) {
case PLAYER_TUNIC_GORON:
return ResolveCustomChain(
{ isAdult ? gCustomAdultGoronFPSHandDL : gCustomChildGoronFPSHandDL, path, nullptr });
case PLAYER_TUNIC_ZORA:
return ResolveCustomChain(
{ isAdult ? gCustomAdultZoraFPSHandDL : gCustomChildZoraFPSHandDL, path, nullptr });
default:
return path;
}
}
static Gfx* LoadGfxByName(const char* path) {
return path ? ResourceMgr_LoadGfxByName(path) : nullptr;
}
@@ -32,6 +52,7 @@ static Gfx* LoadGfxByName(const char* path) {
static Gfx* LoadCustomGfx(const char* path) {
if (!path)
return nullptr;
path = ResolveCustomFPSHand(path);
if (!ResourceGetIsCustomByName(path) && !ResourceMgr_FileAltExists(path))
return nullptr;
return ResourceMgr_LoadGfxByName(path);
+64
View File
@@ -2,6 +2,7 @@
#include "OTRGlobals.h"
#include "variables.h"
#include "z64.h"
#include "macros.h"
#include "cvar_prefixes.h"
#include "Enhancements/enhancementTypes.h"
#include "Enhancements/randomizer/dungeon.h"
@@ -20,6 +21,68 @@
extern "C" PlayState* gPlayState;
struct LinkTunicDListCacheKey {
size_t operator()(const std::pair<std::string, const char*>& key) const {
return std::hash<std::string>{}(key.first) ^ std::hash<const char*>{}(key.second);
}
};
static const char* ResourceMgr_ResolveLinkTunicDListPath(const char* path) {
if (path == nullptr) {
return nullptr;
}
const char* originalPath = path;
constexpr std::string_view adultPrefix = "__OTR__objects/object_link_boy/";
constexpr std::string_view childPrefix = "__OTR__objects/object_link_child/";
std::string_view objectPrefix;
const char* objectFolder;
if (std::string_view(originalPath).starts_with(adultPrefix)) {
objectPrefix = adultPrefix;
objectFolder = "object_link_boy";
} else if (std::string_view(originalPath).starts_with(childPrefix)) {
objectPrefix = childPrefix;
objectFolder = "object_link_child";
} else {
return path;
}
const char* tunicSuffix = nullptr;
switch (TUNIC_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC))) {
case PLAYER_TUNIC_KOKIRI:
tunicSuffix = "kokiri";
break;
case PLAYER_TUNIC_GORON:
tunicSuffix = "goron";
break;
case PLAYER_TUNIC_ZORA:
tunicSuffix = "zora";
break;
default:
return path;
}
static std::unordered_map<std::pair<std::string, const char*>, std::string, LinkTunicDListCacheKey>
sResolvedLinkTunicDListPaths;
std::pair<std::string, const char*> cacheKey{ originalPath, tunicSuffix };
if (auto it = sResolvedLinkTunicDListPaths.find(cacheKey); it != sResolvedLinkTunicDListPaths.end()) {
return it->second.c_str();
}
const std::string candidate =
fmt::format("__OTR__objects/{}_{}/{}", objectFolder, tunicSuffix, originalPath + objectPrefix.size());
if (!ResourceGetIsCustomByName(candidate.c_str()) && !ResourceMgr_FileExists(candidate.c_str()) &&
!(ResourceMgr_IsAltAssetsEnabled() && ResourceMgr_FileAltExists(candidate.c_str()))) {
return path;
}
auto it = sResolvedLinkTunicDListPaths.emplace(std::move(cacheKey), candidate).first;
return it->second.c_str();
}
extern "C" uint32_t ResourceMgr_GetNumGameVersions() {
return static_cast<u32>(
Ship::Context::GetRawInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions().size());
@@ -307,6 +370,7 @@ extern "C" void ResourceMgr_PushCurrentDirectory(char* path) {
}
extern "C" Gfx* ResourceMgr_LoadGfxByName(const char* path) {
path = ResourceMgr_ResolveLinkTunicDListPath(path);
// When an alt resource exists for the DL, we need to unload the original asset
// to clear the cache so the alt asset will be loaded instead
// OTRTODO: If Alt loading over original cache is fixed, this line can most likely be removed