mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-02-07 02:40:30 -05:00
Custom Tunics (#4774)
* Custom Tunics Co-authored-by: MoriyaFaith 46070717+MoriyaFaith@users.noreply.github.com * Works for necessary scenarios * make variable static again
This commit is contained in:
parent
91720a3857
commit
f0b02d6c7e
@ -162,3 +162,22 @@ static const ALIGN_ASSET(2) char gFileSelLanguageGERTex[] = dgFileSelLanguageGER
|
||||
|
||||
#define dgEmptyTexture "__OTR__textures/virtual/gEmptyTexture"
|
||||
static const ALIGN_ASSET(2) char gEmptyTexture[] = dgEmptyTexture;
|
||||
|
||||
// Custom Tunic Models
|
||||
#define dgLinkChildKokiriTunicSkel "__OTR__objects/object_link_child_kokiri/gLinkChildKokiriTunicSkel"
|
||||
static const ALIGN_ASSET(2) char gLinkChildKokiriTunicSkel[] = dgLinkChildKokiriTunicSkel;
|
||||
|
||||
#define dgLinkChildGoronTunicSkel "__OTR__objects/object_link_child_goron/gLinkChildGoronTunicSkel"
|
||||
static const ALIGN_ASSET(2) char gLinkChildGoronTunicSkel[] = dgLinkChildGoronTunicSkel;
|
||||
|
||||
#define dgLinkChildZoraTunicSkel "__OTR__objects/object_link_child_zora/gLinkChildZoraTunicSkel"
|
||||
static const ALIGN_ASSET(2) char gLinkChildZoraTunicSkel[] = dgLinkChildZoraTunicSkel;
|
||||
|
||||
#define dgLinkAdultKokiriTunicSkel "__OTR__objects/object_link_boy_kokiri/gLinkAdultKokiriTunicSkel"
|
||||
static const ALIGN_ASSET(2) char gLinkAdultKokiriTunicSkel[] = dgLinkAdultKokiriTunicSkel;
|
||||
|
||||
#define dgLinkAdultGoronTunicSkel "__OTR__objects/object_link_boy_goron/gLinkAdultGoronTunicSkel"
|
||||
static const ALIGN_ASSET(2) char gLinkAdultGoronTunicSkel[] = dgLinkAdultGoronTunicSkel;
|
||||
|
||||
#define dgLinkAdultZoraTunicSkel "__OTR__objects/object_link_boy_zora/gLinkAdultZoraTunicSkel"
|
||||
static const ALIGN_ASSET(2) char gLinkAdultZoraTunicSkel[] = dgLinkAdultZoraTunicSkel;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/SaveManager.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/resource/type/Skeleton.h"
|
||||
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
|
||||
#include "soh/Enhancements/boss-rush/BossRush.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
@ -38,6 +39,7 @@
|
||||
#include "src/overlays/actors/ovl_En_Door/z_en_door.h"
|
||||
#include "objects/object_link_boy/object_link_boy.h"
|
||||
#include "objects/object_link_child/object_link_child.h"
|
||||
#include "soh_assets.h"
|
||||
#include "kaleido.h"
|
||||
|
||||
extern "C" {
|
||||
@ -1435,6 +1437,30 @@ void RegisterRandomizerCompasses() {
|
||||
});
|
||||
}
|
||||
|
||||
void RegisterCustomSkeletons() {
|
||||
static int8_t previousTunic = -1;
|
||||
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
|
||||
|
||||
if (!GameInteractor::IsSaveLoaded() || gPlayState == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) != previousTunic) {
|
||||
SOH::SkeletonPatcher::UpdateCustomSkeletons();
|
||||
}
|
||||
previousTunic = CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC);
|
||||
});
|
||||
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnAssetAltChange>([]() {
|
||||
if (!GameInteractor::IsSaveLoaded() || gPlayState == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SOH::SkeletonPatcher::UpdateCustomSkeletons();
|
||||
});
|
||||
}
|
||||
|
||||
void InitMods() {
|
||||
BossRush_RegisterHooks();
|
||||
RandomizerRegisterHooks();
|
||||
@ -1479,4 +1505,5 @@ void InitMods() {
|
||||
RegisterHurtContainerModeHandler();
|
||||
RegisterPauseMenuHooks();
|
||||
RandoKaleido_RegisterHooks();
|
||||
RegisterCustomSkeletons();
|
||||
}
|
||||
|
@ -2,6 +2,13 @@
|
||||
#include "Skeleton.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "libultraship/libultraship.h"
|
||||
#include <soh_assets.h>
|
||||
#include <objects/object_link_child/object_link_child.h>
|
||||
#include <objects/object_link_boy/object_link_boy.h>
|
||||
|
||||
extern "C" SaveContext gSaveContext;
|
||||
extern "C" u16 gEquipMasks[4];
|
||||
extern "C" u8 gEquipShifts[4];
|
||||
|
||||
namespace SOH {
|
||||
SkeletonData* Skeleton::GetPointer() {
|
||||
@ -66,10 +73,10 @@ void SkeletonPatcher::ClearSkeletons()
|
||||
|
||||
void SkeletonPatcher::UpdateSkeletons() {
|
||||
auto resourceMgr = Ship::Context::GetInstance()->GetResourceManager();
|
||||
bool isHD = resourceMgr->IsAltAssetsEnabled();
|
||||
bool isAlt = resourceMgr->IsAltAssetsEnabled();
|
||||
for (auto skel : skeletons) {
|
||||
Skeleton* newSkel =
|
||||
(Skeleton*)resourceMgr->LoadResource((isHD ? Ship::IResource::gAltAssetPrefix : "") + skel.vanillaSkeletonPath, true).get();
|
||||
(Skeleton*)resourceMgr->LoadResource((isAlt ? Ship::IResource::gAltAssetPrefix : "") + skel.vanillaSkeletonPath, true).get();
|
||||
|
||||
if (newSkel != nullptr) {
|
||||
skel.skelAnime->skeleton = newSkel->skeletonData.skeletonHeader.segment;
|
||||
@ -78,4 +85,93 @@ void SkeletonPatcher::UpdateSkeletons() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonPatcher::UpdateCustomSkeletons() {
|
||||
for (auto skel : skeletons) {
|
||||
UpdateTunicSkeletons(skel);
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonPatcher::UpdateTunicSkeletons(SkeletonPatchInfo& skel) {
|
||||
std::string skeletonPath = "";
|
||||
|
||||
// Check if this is one of Link's skeletons
|
||||
if (sOtr + skel.vanillaSkeletonPath == std::string(gLinkAdultSkel)) {
|
||||
// Check what Link's current tunic is
|
||||
switch (TUNIC_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC))) {
|
||||
case PLAYER_TUNIC_KOKIRI:
|
||||
skeletonPath = std::string(gLinkAdultKokiriTunicSkel).substr(sOtr.length());
|
||||
break;
|
||||
case PLAYER_TUNIC_GORON:
|
||||
skeletonPath = std::string(gLinkAdultGoronTunicSkel).substr(sOtr.length());
|
||||
break;
|
||||
case PLAYER_TUNIC_ZORA:
|
||||
skeletonPath = std::string(gLinkAdultZoraTunicSkel).substr(sOtr.length());
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateCustomSkeletonFromPath(skeletonPath, skel);
|
||||
} else if (sOtr + skel.vanillaSkeletonPath == std::string(gLinkChildSkel)) {
|
||||
// Check what Link's current tunic is
|
||||
switch (TUNIC_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC))) {
|
||||
case PLAYER_TUNIC_KOKIRI:
|
||||
skeletonPath = std::string(gLinkChildKokiriTunicSkel).substr(sOtr.length());
|
||||
break;
|
||||
case PLAYER_TUNIC_GORON:
|
||||
skeletonPath = std::string(gLinkChildGoronTunicSkel).substr(sOtr.length());
|
||||
break;
|
||||
case PLAYER_TUNIC_ZORA:
|
||||
skeletonPath = std::string(gLinkChildZoraTunicSkel).substr(sOtr.length());
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateCustomSkeletonFromPath(skeletonPath, skel);
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonPatcher::UpdateCustomSkeletonFromPath(const std::string& skeletonPath, SkeletonPatchInfo& skel) {
|
||||
Skeleton* newSkel = nullptr;
|
||||
Skeleton* altSkel = nullptr;
|
||||
auto resourceMgr = Ship::Context::GetInstance()->GetResourceManager();
|
||||
bool isAlt = resourceMgr->IsAltAssetsEnabled();
|
||||
|
||||
// If alt assets are on, look for alt tagged skeletons
|
||||
if (isAlt) {
|
||||
altSkel =
|
||||
(Skeleton*)Ship::Context::GetInstance()
|
||||
->GetResourceManager()
|
||||
->LoadResource(Ship::IResource::gAltAssetPrefix + skeletonPath, true)
|
||||
.get();
|
||||
|
||||
// Override non-alt skeleton if necessary
|
||||
if (altSkel != nullptr) {
|
||||
newSkel = altSkel;
|
||||
}
|
||||
}
|
||||
|
||||
// Load new skeleton based on the custom model if it exists
|
||||
if (altSkel == nullptr) {
|
||||
newSkel =
|
||||
(Skeleton*)Ship::Context::GetInstance()
|
||||
->GetResourceManager()
|
||||
->LoadResource(skeletonPath, true)
|
||||
.get();
|
||||
}
|
||||
|
||||
// Change back to the original skeleton if no skeleton's were found
|
||||
if (newSkel == nullptr && skeletonPath != skel.vanillaSkeletonPath) {
|
||||
UpdateCustomSkeletonFromPath(skel.vanillaSkeletonPath, skel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (newSkel != nullptr) {
|
||||
skel.skelAnime->skeleton = newSkel->skeletonData.skeletonHeader.segment;
|
||||
uintptr_t skelPtr = (uintptr_t)newSkel->GetPointer();
|
||||
memcpy(&skel.skelAnime->skeletonHeader, &skelPtr, sizeof(uintptr_t));
|
||||
}
|
||||
}
|
||||
} // namespace SOH
|
||||
|
@ -86,8 +86,13 @@ class SkeletonPatcher {
|
||||
static void UnregisterSkeleton(SkelAnime* skelAnime);
|
||||
static void ClearSkeletons();
|
||||
static void UpdateSkeletons();
|
||||
static void UpdateCustomSkeletons();
|
||||
|
||||
static std::vector<SkeletonPatchInfo> skeletons;
|
||||
private:
|
||||
inline static const std::string sOtr = "__OTR__";
|
||||
static void UpdateTunicSkeletons(SkeletonPatchInfo& skel);
|
||||
static void UpdateCustomSkeletonFromPath(const std::string& skeletonPath, SkeletonPatchInfo& skel);
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user