mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-01-13 15:08:03 -05:00
Adds rough ability to differentiate between rando and vanilla items.merge stashed changes from before develop-zhora merge
This commit is contained in:
parent
1da655adb5
commit
95d439bb30
@ -10,6 +10,7 @@ extern "C"
|
||||
#endif
|
||||
|
||||
#include "../../libultraship/libultraship/luslog.h"
|
||||
#include <soh/Enhancements/item-tables/ItemTableTypes.h>
|
||||
|
||||
#if defined(INCLUDE_GAME_PRINTF) && !defined(NDEBUG)
|
||||
#define osSyncPrintf(fmt, ...) lusprintf(__FILE__, __LINE__, 0, fmt, __VA_ARGS__)
|
||||
@ -1045,6 +1046,7 @@ void Interface_LoadItemIcon1(GlobalContext* globalCtx, u16 button);
|
||||
void Interface_LoadItemIcon2(GlobalContext* globalCtx, u16 button);
|
||||
void func_80084BF4(GlobalContext* globalCtx, u16 flag);
|
||||
u8 Item_Give(GlobalContext* globalCtx, u8 item);
|
||||
u16 Randomizer_Item_Give(GlobalContext* globalCtx, GetItemEntry giEntry);
|
||||
u8 Item_CheckObtainability(u8 item);
|
||||
void Inventory_DeleteItem(u16 item, u16 invSlot);
|
||||
s32 Inventory_ReplaceItem(GlobalContext* globalCtx, u16 oldItem, u16 newItem);
|
||||
|
@ -626,6 +626,6 @@ typedef struct Player {
|
||||
/* 0x0A87 */ u8 unk_A87;
|
||||
/* 0x0A88 */ Vec3f unk_A88; // previous body part 0 position
|
||||
/* 0x0A94 */ PendingFlag pendingFlag;
|
||||
} Player; // size = 0xAA0
|
||||
} Player; // size = 0xA94
|
||||
|
||||
#endif
|
||||
|
@ -949,6 +949,7 @@
|
||||
<ClCompile Include="soh\Enhancements\randomizer\randomizer.h" />
|
||||
<ClInclude Include="soh\Enhancements\gfx.h" />
|
||||
<ClInclude Include="soh\Enhancements\item-tables\ItemTableManager.h" />
|
||||
<ClInclude Include="soh\Enhancements\item-tables\ItemTableTypes.h" />
|
||||
<ClInclude Include="soh\Enhancements\randomizer\3drando\category.hpp" />
|
||||
<ClInclude Include="soh\Enhancements\randomizer\3drando\cosmetics.hpp" />
|
||||
<ClInclude Include="soh\Enhancements\randomizer\3drando\custom_messages.hpp" />
|
||||
|
@ -4086,7 +4086,10 @@
|
||||
<Filter>Header Files\soh\Enhancements\randomizer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="soh\Enhancements\item-tables\ItemTableManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
<Filter>Header Files\soh\Enhancements\item-tables</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="soh\Enhancements\item-tables\ItemTableTypes.h">
|
||||
<Filter>Header Files\soh\Enhancements\item-tables</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -1,30 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <ultra64/gbi.h>
|
||||
#include "ItemTableTypes.h"
|
||||
|
||||
#define CHEST_ANIM_SHORT 0
|
||||
#define CHEST_ANIM_LONG 1
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ uint8_t itemId;
|
||||
/* 0x01 */ uint8_t field; // various bit-packed data
|
||||
/* 0x02 */ int8_t gi; // defines the draw id and chest opening animation
|
||||
/* 0x03 */ uint8_t textId;
|
||||
/* 0x04 */ uint16_t objectId;
|
||||
/* 0x06 */ uint16_t modIndex; // 0 = Vanilla, 1 = Randomizer, future mods will increment up?
|
||||
} GetItemEntry; // size = 0x06
|
||||
|
||||
#define GET_ITEM(itemId, objectId, drawId, textId, field, chestAnim) \
|
||||
{ itemId, field, (chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1), textId, objectId }
|
||||
|
||||
#define GET_ITEM_NONE \
|
||||
{ ITEM_NONE, 0, 0, 0, OBJECT_INVALID }
|
||||
|
||||
#ifdef __cplusplus
|
||||
{ 0, 0, 0, 0, 0 }
|
||||
|
||||
#include <unordered_map>
|
||||
#include "z64item.h"
|
||||
#include "z64object.h"
|
||||
|
||||
typedef std::unordered_map<uint8_t, GetItemEntry> ItemTable;
|
||||
|
||||
@ -44,5 +30,3 @@ class ItemTableManager {
|
||||
|
||||
ItemTable* RetrieveItemTable(std::string tableID);
|
||||
};
|
||||
|
||||
#endif
|
13
soh/soh/Enhancements/item-tables/ItemTableTypes.h
Normal file
13
soh/soh/Enhancements/item-tables/ItemTableTypes.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#ifdef __cplusplus
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ uint8_t itemId;
|
||||
/* 0x01 */ uint8_t field; // various bit-packed data
|
||||
/* 0x02 */ int8_t gi; // defines the draw id and chest opening animation
|
||||
/* 0x03 */ uint8_t textId;
|
||||
/* 0x04 */ uint16_t objectId;
|
||||
/* 0x06 */ uint16_t modIndex; // 0 = Vanilla, 1 = Randomizer, future mods will increment up?
|
||||
} GetItemEntry; // size = 0x06
|
@ -2030,8 +2030,8 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId)
|
||||
case RG_MAGIC_BEAN_PACK:
|
||||
return GI_BEAN; //todo make it 10 of them
|
||||
|
||||
case RG_DOUBLE_DEFENSE:
|
||||
return GI_DOUBLE_DEFENSE;
|
||||
/*case RG_DOUBLE_DEFENSE:
|
||||
return GI_DOUBLE_DEFENSE;*/
|
||||
|
||||
case RG_WEIRD_EGG:
|
||||
return GI_WEIRD_EGG;
|
||||
@ -2160,9 +2160,9 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId)
|
||||
case RG_PROGRESSIVE_MAGIC_METER:
|
||||
switch (gSaveContext.magicLevel) {
|
||||
case 0:
|
||||
return GI_SINGLE_MAGIC;
|
||||
return (GetItemID)RG_MAGIC_SINGLE;
|
||||
case 1:
|
||||
return GI_DOUBLE_MAGIC;
|
||||
return (GetItemID)RG_MAGIC_DOUBLE;
|
||||
}
|
||||
return GI_RUPEE_BLUE;
|
||||
|
||||
@ -2182,7 +2182,7 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId)
|
||||
return GI_BOTTLE;
|
||||
case RG_BOTTLE_WITH_MILK:
|
||||
return GI_MILK_BOTTLE;
|
||||
case RG_BOTTLE_WITH_RED_POTION:
|
||||
/*case RG_BOTTLE_WITH_RED_POTION:
|
||||
return GI_BOTTLE_WITH_RED_POTION;
|
||||
case RG_BOTTLE_WITH_GREEN_POTION:
|
||||
return GI_BOTTLE_WITH_GREEN_POTION;
|
||||
@ -2227,7 +2227,7 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId)
|
||||
case RG_NOCTURNE_OF_SHADOW:
|
||||
return GI_NOCTURNE_OF_SHADOW;
|
||||
case RG_PRELUDE_OF_LIGHT:
|
||||
return GI_PRELUDE_OF_LIGHT;
|
||||
return GI_PRELUDE_OF_LIGHT;*/
|
||||
|
||||
// todo implement dungeon-specific maps/compasses
|
||||
case RG_DEKU_TREE_MAP:
|
||||
@ -2290,7 +2290,7 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId)
|
||||
case RG_GANONS_CASTLE_KEY_RING:
|
||||
return GI_RUPEE_BLUE;
|
||||
|
||||
case RG_KOKIRI_EMERALD:
|
||||
/*case RG_KOKIRI_EMERALD:
|
||||
return GI_STONE_KOKIRI;
|
||||
case RG_GORON_RUBY:
|
||||
return GI_STONE_GORON;
|
||||
@ -2308,7 +2308,7 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId)
|
||||
case RG_SHADOW_MEDALLION:
|
||||
return GI_MEDALLION_SHADOW;
|
||||
case RG_LIGHT_MEDALLION:
|
||||
return GI_MEDALLION_LIGHT;
|
||||
return GI_MEDALLION_LIGHT;*/
|
||||
|
||||
case RG_RECOVERY_HEART:
|
||||
return GI_HEART;
|
||||
@ -2387,11 +2387,60 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId)
|
||||
case RG_HINT:
|
||||
return GI_RUPEE_BLUE; //todo
|
||||
|
||||
default:
|
||||
default: {
|
||||
if (IsGetItemRandoExclusive(randoGet)) {
|
||||
return (GetItemID)randoGet;
|
||||
}
|
||||
return ogItemId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Randomizer::IsGetItemRandoExclusive(RandomizerGet randoGet) {
|
||||
switch (randoGet) {
|
||||
case RG_LIGHT_MEDALLION:
|
||||
case RG_FOREST_MEDALLION:
|
||||
case RG_FIRE_MEDALLION:
|
||||
case RG_WATER_MEDALLION:
|
||||
case RG_SHADOW_MEDALLION:
|
||||
case RG_SPIRIT_MEDALLION:
|
||||
case RG_KOKIRI_EMERALD:
|
||||
case RG_GORON_RUBY:
|
||||
case RG_ZORA_SAPPHIRE:
|
||||
case RG_ZELDAS_LULLABY:
|
||||
case RG_SUNS_SONG:
|
||||
case RG_EPONAS_SONG:
|
||||
case RG_SONG_OF_STORMS:
|
||||
case RG_SONG_OF_TIME:
|
||||
case RG_SARIAS_SONG:
|
||||
case RG_MINUET_OF_FOREST:
|
||||
case RG_BOLERO_OF_FIRE:
|
||||
case RG_SERENADE_OF_WATER:
|
||||
case RG_NOCTURNE_OF_SHADOW:
|
||||
case RG_REQUIEM_OF_SPIRIT:
|
||||
case RG_PRELUDE_OF_LIGHT:
|
||||
case RG_PROGRESSIVE_MAGIC_METER:
|
||||
case RG_DOUBLE_DEFENSE:
|
||||
case RG_BOTTLE_WITH_RED_POTION:
|
||||
case RG_BOTTLE_WITH_GREEN_POTION:
|
||||
case RG_BOTTLE_WITH_BLUE_POTION:
|
||||
case RG_BOTTLE_WITH_FAIRY:
|
||||
case RG_BOTTLE_WITH_FISH:
|
||||
case RG_BOTTLE_WITH_BLUE_FIRE:
|
||||
case RG_BOTTLE_WITH_BUGS:
|
||||
case RG_BOTTLE_WITH_POE:
|
||||
case RG_BOTTLE_WITH_BIG_POE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Randomizer::CheckContainsRandoItem(RandomizerCheck randoCheck) {
|
||||
RandomizerGet randoGet = this->itemLocations[randoCheck];
|
||||
return IsGetItemRandoExclusive(randoGet);
|
||||
}
|
||||
|
||||
std::string Randomizer::GetAdultAltarText() const {
|
||||
return this->adultAltarText;
|
||||
}
|
||||
@ -4732,31 +4781,34 @@ void DrawRandoEditor(bool& open) {
|
||||
|
||||
void InitRandoItemTable() {
|
||||
GetItemEntry getItemTable[] = {
|
||||
GET_ITEM(RG_LIGHT_MEDALLION, OBJECT_GI_MEDAL, GID_MEDALLION_LIGHT, 0x40, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_FOREST_MEDALLION, OBJECT_GI_MEDAL, GID_MEDALLION_FOREST, 0x3E, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_FIRE_MEDALLION, OBJECT_GI_MEDAL, GID_MEDALLION_FIRE, 0x3C, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_WATER_MEDALLION, OBJECT_GI_MEDAL, GID_MEDALLION_WATER, 0x3D, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_SHADOW_MEDALLION, OBJECT_GI_MEDAL, GID_MEDALLION_SHADOW, 0x41, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_SPIRIT_MEDALLION, OBJECT_GI_MEDAL, GID_MEDALLION_SPIRIT, 0x3F, 0x80, CHEST_ANIM_LONG),
|
||||
// The first several entries have ItemIDs from vanilla, but not GetItemIDs or entries in sGetItemTable
|
||||
GET_ITEM(ITEM_MEDALLION_LIGHT, OBJECT_GI_MEDAL, GID_MEDALLION_LIGHT, 0x40, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_MEDALLION_FOREST, OBJECT_GI_MEDAL, GID_MEDALLION_FOREST, 0x3E, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_MEDALLION_FIRE, OBJECT_GI_MEDAL, GID_MEDALLION_FIRE, 0x3C, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_MEDALLION_WATER, OBJECT_GI_MEDAL, GID_MEDALLION_WATER, 0x3D, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_MEDALLION_SHADOW, OBJECT_GI_MEDAL, GID_MEDALLION_SHADOW, 0x41, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_MEDALLION_SPIRIT, OBJECT_GI_MEDAL, GID_MEDALLION_SPIRIT, 0x3F, 0x80, CHEST_ANIM_LONG),
|
||||
|
||||
GET_ITEM(RG_KOKIRI_EMERALD, OBJECT_GI_JEWEL, GID_KOKIRI_EMERALD, 0x80, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_GORON_RUBY, OBJECT_GI_JEWEL, GID_GORON_RUBY, 0x81, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_ZORA_SAPPHIRE, OBJECT_GI_JEWEL, GID_ZORA_SAPPHIRE, 0x82, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_KOKIRI_EMERALD, OBJECT_GI_JEWEL, GID_KOKIRI_EMERALD, 0x80, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_GORON_RUBY, OBJECT_GI_JEWEL, GID_GORON_RUBY, 0x81, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_ZORA_SAPPHIRE, OBJECT_GI_JEWEL, GID_ZORA_SAPPHIRE, 0x82, 0x80, CHEST_ANIM_LONG),
|
||||
|
||||
GET_ITEM(RG_ZELDAS_LULLABY, OBJECT_GI_MELODY, GID_SONG_ZELDA, 0xD4, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_SUNS_SONG, OBJECT_GI_MELODY, GID_SONG_SUN, 0xD3, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_EPONAS_SONG, OBJECT_GI_MELODY, GID_SONG_EPONA, 0xD2, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_SONG_OF_STORMS, OBJECT_GI_MELODY, GID_SONG_STORM, 0xD6, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_SONG_OF_TIME, OBJECT_GI_MELODY, GID_SONG_TIME, 0xD5, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_SARIAS_SONG, OBJECT_GI_MELODY, GID_SONG_SARIA, 0xD1, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_SONG_LULLABY, OBJECT_GI_MELODY, GID_SONG_ZELDA, 0xD4, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_SONG_SUN, OBJECT_GI_MELODY, GID_SONG_SUN, 0xD3, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_SONG_EPONA, OBJECT_GI_MELODY, GID_SONG_EPONA, 0xD2, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_SONG_STORMS, OBJECT_GI_MELODY, GID_SONG_STORM, 0xD6, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_SONG_TIME, OBJECT_GI_MELODY, GID_SONG_TIME, 0xD5, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_SONG_SARIA, OBJECT_GI_MELODY, GID_SONG_SARIA, 0xD1, 0x80, CHEST_ANIM_LONG),
|
||||
|
||||
GET_ITEM(RG_MINUET_OF_FOREST, OBJECT_GI_MELODY, GID_SONG_MINUET, 0x73, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_BOLERO_OF_FIRE, OBJECT_GI_MELODY, GID_SONG_BOLERO, 0x74, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_SERENADE_OF_WATER, OBJECT_GI_MELODY, GID_SONG_SERENADE, 0x75, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_NOCTURNE_OF_SHADOW, OBJECT_GI_MELODY, GID_SONG_NOCTURNE, 0x77, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_REQUIEM_OF_SPIRIT, OBJECT_GI_MELODY, GID_SONG_REQUIEM, 0x76, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_PRELUDE_OF_LIGHT, OBJECT_GI_MELODY, GID_SONG_PRELUDE, 0x78, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_SONG_MINUET, OBJECT_GI_MELODY, GID_SONG_MINUET, 0x73, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_SONG_BOLERO, OBJECT_GI_MELODY, GID_SONG_BOLERO, 0x74, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_SONG_SERENADE, OBJECT_GI_MELODY, GID_SONG_SERENADE, 0x75, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_SONG_NOCTURNE, OBJECT_GI_MELODY, GID_SONG_NOCTURNE, 0x77, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_SONG_REQUIEM, OBJECT_GI_MELODY, GID_SONG_REQUIEM, 0x76, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(ITEM_SONG_PRELUDE, OBJECT_GI_MELODY, GID_SONG_PRELUDE, 0x78, 0x80, CHEST_ANIM_LONG),
|
||||
|
||||
// Starting here, these do not have ItemIDs or GetItemIDs from vanilla, so I'm using their
|
||||
// RandomizerGet enum values for both.
|
||||
GET_ITEM(RG_MAGIC_SINGLE, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0xE4, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_MAGIC_DOUBLE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG),
|
||||
GET_ITEM(RG_DOUBLE_DEFENSE, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xE9, 0x80, CHEST_ANIM_LONG),
|
||||
@ -4773,14 +4825,92 @@ void InitRandoItemTable() {
|
||||
};
|
||||
ItemTableManager::Instance->AddItemTable("Randomizer");
|
||||
for (int i = 0; i < ARRAY_SIZE(getItemTable); i++) {
|
||||
getItemTable[i].modIndex = MOD_RANDOMIZER;
|
||||
ItemTableManager::Instance->AddItemEntry("Randomizer", getItemTable[i].itemId, getItemTable[i]);
|
||||
if (i < 21) {
|
||||
// We want to use vanilla Give_Item code for indices 0-20 since
|
||||
// vanilla already handles that.
|
||||
getItemTable[i].modIndex = MOD_VANILLA;
|
||||
} else {
|
||||
// Mark these as randomizer items so we use the rando exclusive
|
||||
// Give_Item_Randomizer for these.
|
||||
getItemTable[i].modIndex = MOD_RANDOMIZER;
|
||||
}
|
||||
uint8_t getItemID;
|
||||
switch (getItemTable[i].itemId) {
|
||||
case ITEM_MEDALLION_LIGHT:
|
||||
getItemID = RG_LIGHT_MEDALLION;
|
||||
break;
|
||||
case ITEM_MEDALLION_FOREST:
|
||||
getItemID = RG_FOREST_MEDALLION;
|
||||
break;
|
||||
case ITEM_MEDALLION_FIRE:
|
||||
getItemID = RG_FIRE_MEDALLION;
|
||||
break;
|
||||
case ITEM_MEDALLION_WATER:
|
||||
getItemID = RG_WATER_MEDALLION;
|
||||
break;
|
||||
case ITEM_MEDALLION_SHADOW:
|
||||
getItemID = RG_SHADOW_MEDALLION;
|
||||
break;
|
||||
case ITEM_MEDALLION_SPIRIT:
|
||||
getItemID = RG_SPIRIT_MEDALLION;
|
||||
break;
|
||||
case ITEM_KOKIRI_EMERALD:
|
||||
getItemID = RG_KOKIRI_EMERALD;
|
||||
break;
|
||||
case ITEM_GORON_RUBY:
|
||||
getItemID = RG_GORON_RUBY;
|
||||
break;
|
||||
case ITEM_ZORA_SAPPHIRE:
|
||||
getItemID = RG_ZORA_SAPPHIRE;
|
||||
break;
|
||||
case ITEM_SONG_LULLABY:
|
||||
getItemID = RG_ZELDAS_LULLABY;
|
||||
break;
|
||||
case ITEM_SONG_SUN:
|
||||
getItemID = RG_SUNS_SONG;
|
||||
break;
|
||||
case ITEM_SONG_EPONA:
|
||||
getItemID = RG_EPONAS_SONG;
|
||||
break;
|
||||
case ITEM_SONG_STORMS:
|
||||
getItemID = RG_SONG_OF_STORMS;
|
||||
break;
|
||||
case ITEM_SONG_TIME:
|
||||
getItemID = RG_SONG_OF_TIME;
|
||||
break;
|
||||
case ITEM_SONG_SARIA:
|
||||
getItemID = RG_SARIAS_SONG;
|
||||
break;
|
||||
case ITEM_SONG_MINUET:
|
||||
getItemID = RG_MINUET_OF_FOREST;
|
||||
break;
|
||||
case ITEM_SONG_BOLERO:
|
||||
getItemID = RG_BOLERO_OF_FIRE;
|
||||
break;
|
||||
case ITEM_SONG_SERENADE:
|
||||
getItemID = RG_SERENADE_OF_WATER;
|
||||
break;
|
||||
case ITEM_SONG_NOCTURNE:
|
||||
getItemID = RG_NOCTURNE_OF_SHADOW;
|
||||
break;
|
||||
case ITEM_SONG_REQUIEM:
|
||||
getItemID = RG_REQUIEM_OF_SPIRIT;
|
||||
break;
|
||||
case ITEM_SONG_PRELUDE:
|
||||
getItemID = RG_PRELUDE_OF_LIGHT;
|
||||
break;
|
||||
default:
|
||||
getItemID = getItemTable[i].itemId;
|
||||
break;
|
||||
}
|
||||
ItemTableManager::Instance->AddItemEntry("Randomizer", getItemID, getItemTable[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InitRando() {
|
||||
SohImGui::AddWindow("Randomizer", "Randomizer Settings", DrawRandoEditor);
|
||||
InitRandoItemTable();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
@ -24,6 +24,8 @@ class Randomizer {
|
||||
void ParseRandomizerSettingsFile(const char* spoilerFileName);
|
||||
void ParseHintLocationsFile(const char* spoilerFileName);
|
||||
void ParseItemLocationsFile(const char* spoilerFileName, bool silent);
|
||||
bool IsGetItemRandoExclusive(RandomizerGet randoGet);
|
||||
|
||||
|
||||
public:
|
||||
Randomizer();
|
||||
@ -37,7 +39,7 @@ class Randomizer {
|
||||
void LoadHintLocations(const char* spoilerFileName);
|
||||
void LoadItemLocations(const char* spoilerFileName, bool silent);
|
||||
u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey);
|
||||
RandomizerCheck GetCheckFromActor(s16 actorId, s16 actorParams, s16 sceneNum);
|
||||
RandomizerCheck GetCheckFromActor(s16 sceneNum, s16 actorId, s16 actorParams);
|
||||
std::string GetChildAltarText() const;
|
||||
std::string GetAdultAltarText() const;
|
||||
std::string GetGanonText() const;
|
||||
@ -45,6 +47,7 @@ class Randomizer {
|
||||
std::string GetHintFromCheck(RandomizerCheck check);
|
||||
GetItemID GetRandomizedItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
|
||||
GetItemID GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum);
|
||||
bool CheckContainsRandoItem(RandomizerCheck randoCheck);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1648,10 +1648,20 @@ extern "C" int Randomizer_CopyHintFromCheck(RandomizerCheck check, char* buffer,
|
||||
}
|
||||
|
||||
extern "C" s32 Randomizer_GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum) {
|
||||
if (OTRGlobals::Instance->gRandomizer->CheckContainsRandoItem(OTRGlobals::Instance->gRandomizer->GetCheckFromActor(sceneNum, actorId, actorParams))) {
|
||||
OTRGlobals::Instance->getItemModIndex = MOD_RANDOMIZER;
|
||||
} else {
|
||||
OTRGlobals::Instance->getItemModIndex = MOD_VANILLA;
|
||||
}
|
||||
return OTRGlobals::Instance->gRandomizer->GetRandomizedItemId(ogId, actorId, actorParams, sceneNum);
|
||||
}
|
||||
|
||||
extern "C" s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId) {
|
||||
if (OTRGlobals::Instance->gRandomizer->CheckContainsRandoItem(randomizerCheck)) {
|
||||
OTRGlobals::Instance->getItemModIndex = MOD_RANDOMIZER;
|
||||
} else {
|
||||
OTRGlobals::Instance->getItemModIndex = MOD_VANILLA;
|
||||
}
|
||||
return OTRGlobals::Instance->gRandomizer->GetRandomizedItemIdFromKnownCheck(randomizerCheck, ogId);
|
||||
}
|
||||
|
||||
@ -1660,5 +1670,14 @@ extern "C" bool Randomizer_ItemIsIceTrap(RandomizerCheck randomizerCheck, GetIte
|
||||
}
|
||||
|
||||
extern "C" GetItemEntry ItemTable_Retrieve(int16_t getItemID) {
|
||||
return ItemTableManager::Instance->RetrieveItemEntry("Vanilla", getItemID);
|
||||
}
|
||||
std::string itemTableID;
|
||||
|
||||
if (OTRGlobals::Instance->getItemModIndex == MOD_VANILLA) {
|
||||
itemTableID = "Vanilla";
|
||||
} else {
|
||||
itemTableID = "Randomizer";
|
||||
getItemID++; // counteracts the - 1 offset used for vanilla table
|
||||
}
|
||||
|
||||
return ItemTableManager::Instance->RetrieveItemEntry(itemTableID, getItemID);
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "GlobalCtx2.h"
|
||||
#include "SaveManager.h"
|
||||
#include <soh/Enhancements/item-tables/ItemTableManager.h>
|
||||
#include <soh/Enhancements/item-tables/ItemTableTypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "Enhancements/savestates.h"
|
||||
@ -19,6 +19,7 @@ public:
|
||||
std::shared_ptr<Ship::GlobalCtx2> context;
|
||||
std::shared_ptr<SaveStateMgr> gSaveStateMgr;
|
||||
std::shared_ptr<Randomizer> gRandomizer;
|
||||
uint16_t getItemModIndex;
|
||||
|
||||
OTRGlobals();
|
||||
~OTRGlobals();
|
||||
|
@ -1578,70 +1578,6 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
|
||||
osSyncPrintf("item_get_setting=%d pt=%d z=%x\n", item, slot, gSaveContext.inventory.items[slot]);
|
||||
osSyncPrintf(VT_RST);
|
||||
|
||||
if (item == ITEM_SINGLE_MAGIC) {
|
||||
gSaveContext.magicAcquired = true;
|
||||
gSaveContext.unk_13F6 = 0x30;
|
||||
Magic_Fill(globalCtx);
|
||||
return ITEM_NONE;
|
||||
} else if (item == ITEM_DOUBLE_MAGIC) {
|
||||
if (!gSaveContext.magicAcquired) {
|
||||
gSaveContext.magicAcquired = true;
|
||||
}
|
||||
gSaveContext.doubleMagic = true;
|
||||
gSaveContext.unk_13F6 = 0x60;
|
||||
gSaveContext.magicLevel = 0;
|
||||
Magic_Fill(globalCtx);
|
||||
return ITEM_NONE;
|
||||
}
|
||||
|
||||
if (item == ITEM_DOUBLE_DEFENSE) {
|
||||
gSaveContext.doubleDefense = true;
|
||||
gSaveContext.inventory.defenseHearts = 20;
|
||||
gSaveContext.healthAccumulator = 0x140;
|
||||
return ITEM_NONE;
|
||||
}
|
||||
|
||||
if (item >= ITEM_BOTTLE_WITH_RED_POTION &&
|
||||
item <= ITEM_BOTTLE_WITH_BIG_POE) {
|
||||
temp = SLOT(ITEM_BOTTLE);
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (gSaveContext.inventory.items[temp + i] == ITEM_NONE) {
|
||||
switch (item) {
|
||||
case ITEM_BOTTLE_WITH_RED_POTION:
|
||||
item = ITEM_POTION_RED;
|
||||
break;
|
||||
case ITEM_BOTTLE_WITH_GREEN_POTION:
|
||||
item = ITEM_POTION_GREEN;
|
||||
break;
|
||||
case ITEM_BOTTLE_WITH_BLUE_POTION:
|
||||
item = ITEM_POTION_BLUE;
|
||||
break;
|
||||
case ITEM_BOTTLE_WITH_FAIRY:
|
||||
item = ITEM_FAIRY;
|
||||
break;
|
||||
case ITEM_BOTTLE_WITH_FISH:
|
||||
item = ITEM_FISH;
|
||||
break;
|
||||
case ITEM_BOTTLE_WITH_BLUE_FIRE:
|
||||
item = ITEM_BLUE_FIRE;
|
||||
break;
|
||||
case ITEM_BOTTLE_WITH_BUGS:
|
||||
item = ITEM_BUG;
|
||||
break;
|
||||
case ITEM_BOTTLE_WITH_POE:
|
||||
item = ITEM_POE;
|
||||
break;
|
||||
case ITEM_BOTTLE_WITH_BIG_POE:
|
||||
item = ITEM_BIG_POE;
|
||||
break;
|
||||
}
|
||||
|
||||
gSaveContext.inventory.items[temp + i] = item;
|
||||
return ITEM_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((item >= ITEM_MEDALLION_FOREST) && (item <= ITEM_MEDALLION_LIGHT)) {
|
||||
gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_MEDALLION_FOREST + QUEST_MEDALLION_FOREST];
|
||||
|
||||
@ -2179,6 +2115,84 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
u16 Randomizer_Item_Give(GlobalContext* globalCtx, GetItemEntry giEntry) {
|
||||
uint16_t item = giEntry.itemId;
|
||||
uint16_t temp;
|
||||
uint16_t i;
|
||||
uint16_t slot;
|
||||
|
||||
slot = SLOT(item);
|
||||
if (item == RG_MAGIC_SINGLE) {
|
||||
gSaveContext.magicAcquired = true;
|
||||
gSaveContext.unk_13F6 = 0x30;
|
||||
Magic_Fill(globalCtx);
|
||||
return RG_NONE;
|
||||
} else if (item == RG_MAGIC_DOUBLE) {
|
||||
if (!gSaveContext.magicAcquired) {
|
||||
gSaveContext.magicAcquired = true;
|
||||
}
|
||||
gSaveContext.doubleMagic = true;
|
||||
gSaveContext.unk_13F6 = 0x60;
|
||||
gSaveContext.magicLevel = 0;
|
||||
Magic_Fill(globalCtx);
|
||||
return RG_NONE;
|
||||
}
|
||||
|
||||
if (item == RG_DOUBLE_DEFENSE) {
|
||||
gSaveContext.doubleDefense = true;
|
||||
gSaveContext.inventory.defenseHearts = 20;
|
||||
gSaveContext.healthAccumulator = 0x140;
|
||||
return RG_NONE;
|
||||
}
|
||||
|
||||
if (item >= RG_BOTTLE_WITH_RED_POTION && item <= RG_BOTTLE_WITH_BIG_POE) {
|
||||
temp = SLOT(ITEM_BOTTLE);
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (gSaveContext.inventory.items[temp + i] == RG_NONE) {
|
||||
switch (item) {
|
||||
case RG_BOTTLE_WITH_RED_POTION:
|
||||
item = ITEM_POTION_RED;
|
||||
break;
|
||||
case RG_BOTTLE_WITH_GREEN_POTION:
|
||||
item = ITEM_POTION_GREEN;
|
||||
break;
|
||||
case RG_BOTTLE_WITH_BLUE_POTION:
|
||||
item = ITEM_POTION_BLUE;
|
||||
break;
|
||||
case RG_BOTTLE_WITH_FAIRY:
|
||||
item = ITEM_FAIRY;
|
||||
break;
|
||||
case RG_BOTTLE_WITH_FISH:
|
||||
item = ITEM_FISH;
|
||||
break;
|
||||
case RG_BOTTLE_WITH_BLUE_FIRE:
|
||||
item = ITEM_BLUE_FIRE;
|
||||
break;
|
||||
case RG_BOTTLE_WITH_BUGS:
|
||||
item = ITEM_BUG;
|
||||
break;
|
||||
case RG_BOTTLE_WITH_POE:
|
||||
item = ITEM_POE;
|
||||
break;
|
||||
case RG_BOTTLE_WITH_BIG_POE:
|
||||
item = ITEM_BIG_POE;
|
||||
break;
|
||||
}
|
||||
|
||||
gSaveContext.inventory.items[temp + i] = item;
|
||||
return RG_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
temp = gSaveContext.inventory.items[slot];
|
||||
osSyncPrintf("Item_Register(%d)=%d %d\n", slot, item, temp);
|
||||
INV_CONTENT(item) = item;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
u8 Item_CheckObtainability(u8 item) {
|
||||
s16 i;
|
||||
s16 slot = SLOT(item);
|
||||
|
@ -367,43 +367,43 @@ void GiveLinkSong(GetItemID getItemId) {
|
||||
gSaveContext.inventory.questItems |= bitMask;
|
||||
}
|
||||
|
||||
void GiveLinkDungeonReward(GetItemID getItemId) {
|
||||
void GiveLinkDungeonReward(uint16_t getItemId) {
|
||||
s16 item;
|
||||
|
||||
u8 medallion = 0;
|
||||
|
||||
switch (getItemId) {
|
||||
case GI_MEDALLION_FOREST:
|
||||
case RG_FOREST_MEDALLION:
|
||||
item = ITEM_MEDALLION_FOREST;
|
||||
medallion = 1;
|
||||
break;
|
||||
case GI_MEDALLION_FIRE:
|
||||
case RG_FIRE_MEDALLION:
|
||||
item = ITEM_MEDALLION_FIRE;
|
||||
medallion = 1;
|
||||
break;
|
||||
case GI_MEDALLION_WATER:
|
||||
case RG_WATER_MEDALLION:
|
||||
item = ITEM_MEDALLION_WATER;
|
||||
medallion = 1;
|
||||
break;
|
||||
case GI_MEDALLION_SHADOW:
|
||||
case RG_SHADOW_MEDALLION:
|
||||
item = ITEM_MEDALLION_SHADOW;
|
||||
medallion = 1;
|
||||
break;
|
||||
case GI_MEDALLION_SPIRIT:
|
||||
case RG_SPIRIT_MEDALLION:
|
||||
item = ITEM_MEDALLION_SPIRIT;
|
||||
medallion = 1;
|
||||
break;
|
||||
case GI_MEDALLION_LIGHT:
|
||||
case RG_LIGHT_MEDALLION:
|
||||
item = ITEM_MEDALLION_LIGHT;
|
||||
medallion = 1;
|
||||
break;
|
||||
case GI_STONE_KOKIRI:
|
||||
case RG_KOKIRI_EMERALD:
|
||||
item = ITEM_KOKIRI_EMERALD;
|
||||
break;
|
||||
case GI_STONE_GORON:
|
||||
case RG_GORON_RUBY:
|
||||
item = ITEM_GORON_RUBY;
|
||||
break;
|
||||
case GI_STONE_ZORA:
|
||||
case RG_ZORA_SAPPHIRE:
|
||||
item = ITEM_ZORA_SAPPHIRE;
|
||||
break;
|
||||
}
|
||||
|
@ -70,6 +70,7 @@ static InitChainEntry sInitChain[] = {
|
||||
};
|
||||
|
||||
static UNK_TYPE sUnused;
|
||||
int32_t sItem;
|
||||
|
||||
void EnBox_SetupAction(EnBox* this, EnBoxActionFunc actionFunc) {
|
||||
this->actionFunc = actionFunc;
|
||||
@ -445,40 +446,40 @@ void EnBox_WaitOpen(EnBox* this, GlobalContext* globalCtx) {
|
||||
func_8002DBD0(&this->dyna.actor, &sp4C, &player->actor.world.pos);
|
||||
if (sp4C.z > -50.0f && sp4C.z < 0.0f && fabsf(sp4C.y) < 10.0f && fabsf(sp4C.x) < 20.0f &&
|
||||
Player_IsFacingActor(&this->dyna.actor, 0x3000, globalCtx)) {
|
||||
int32_t item = Randomizer_GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F, this->dyna.actor.id, this->dyna.actor.params, globalCtx->sceneNum);
|
||||
sItem = Randomizer_GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F, this->dyna.actor.id, this->dyna.actor.params, globalCtx->sceneNum);
|
||||
|
||||
// RANDOTODO treasure chest game rando
|
||||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
|
||||
if (gSaveContext.n64ddFlag && globalCtx->sceneNum == 16 && (this->dyna.actor.params & 0x60) != 0x20) {
|
||||
if((this->dyna.actor.params & 0xF) < 2) {
|
||||
if(Flags_GetCollectible(globalCtx, 0x1B)) {
|
||||
item = GI_RUPEE_BLUE;
|
||||
sItem = GI_RUPEE_BLUE;
|
||||
}
|
||||
}
|
||||
if((this->dyna.actor.params & 0xF) >= 2 && (this->dyna.actor.params & 0xF) < 4) {
|
||||
if(Flags_GetCollectible(globalCtx, 0x1C)) {
|
||||
item = GI_RUPEE_BLUE;
|
||||
sItem = GI_RUPEE_BLUE;
|
||||
}
|
||||
}
|
||||
if((this->dyna.actor.params & 0xF) >= 4 && (this->dyna.actor.params & 0xF) < 6) {
|
||||
if(Flags_GetCollectible(globalCtx, 0x1D)) {
|
||||
item = GI_RUPEE_BLUE;
|
||||
sItem = GI_RUPEE_BLUE;
|
||||
}
|
||||
}
|
||||
if((this->dyna.actor.params & 0xF) >= 6 && (this->dyna.actor.params & 0xF) < 8) {
|
||||
if(Flags_GetCollectible(globalCtx, 0x1E)) {
|
||||
item = GI_RUPEE_BLUE;
|
||||
sItem = GI_RUPEE_BLUE;
|
||||
}
|
||||
}
|
||||
if((this->dyna.actor.params & 0xF) >= 8 && (this->dyna.actor.params & 0xF) < 10) {
|
||||
if(Flags_GetCollectible(globalCtx, 0x1F)) {
|
||||
item = GI_RUPEE_BLUE;
|
||||
sItem = GI_RUPEE_BLUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func_8002F554(&this->dyna.actor, globalCtx, 0 - item);
|
||||
func_8002F554(&this->dyna.actor, globalCtx, 0 - sItem);
|
||||
}
|
||||
if (Flags_GetTreasure(globalCtx, this->dyna.actor.params & 0x1F)) {
|
||||
EnBox_SetupAction(this, EnBox_Open);
|
||||
@ -590,9 +591,7 @@ void EnBox_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
if (((!gSaveContext.n64ddFlag && ((this->dyna.actor.params >> 5 & 0x7F) == 0x7C)) ||
|
||||
(gSaveContext.n64ddFlag && Randomizer_GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F,
|
||||
this->dyna.actor.id, this->dyna.actor.params,
|
||||
globalCtx->sceneNum) == GI_ICE_TRAP)) &&
|
||||
(gSaveContext.n64ddFlag && sItem == GI_ICE_TRAP)) &&
|
||||
this->actionFunc == EnBox_Open && this->skelanime.curFrame > 45 &&
|
||||
this->iceSmokeTimer < 100) EnBox_SpawnIceSmoke(this, globalCtx);
|
||||
}
|
||||
|
@ -12715,9 +12715,13 @@ s32 func_8084DFF4(GlobalContext* globalCtx, Player* this) {
|
||||
gSaveContext.swordHealth = 8;
|
||||
}
|
||||
|
||||
Message_StartTextbox(globalCtx, giEntry->textId, &this->actor);
|
||||
Item_Give(globalCtx, giEntry->itemId);
|
||||
|
||||
Message_StartTextbox(globalCtx, giEntry.textId, &this->actor);
|
||||
if (giEntry.modIndex == 0) {
|
||||
Item_Give(globalCtx, giEntry.itemId);
|
||||
}
|
||||
else {
|
||||
Randomizer_Item_Give(globalCtx, giEntry);
|
||||
}
|
||||
Player_SetPendingFlag(this, globalCtx);
|
||||
|
||||
if (((this->getItemId >= GI_RUPEE_GREEN) && (this->getItemId <= GI_RUPEE_RED)) ||
|
||||
|
Loading…
Reference in New Issue
Block a user