Skip to content

Commit

Permalink
Wonderitem Shuffle
Browse files Browse the repository at this point in the history
  • Loading branch information
rrealmuto committed Nov 29, 2023
1 parent ec47c87 commit a1614c4
Show file tree
Hide file tree
Showing 33 changed files with 30,375 additions and 28,941 deletions.
1,224 changes: 617 additions & 607 deletions ASM/build/asm_symbols.txt

Large diffs are not rendered by default.

Binary file modified ASM/build/bundle.o
Binary file not shown.
1,103 changes: 559 additions & 544 deletions ASM/build/c_symbols.txt

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions ASM/c/actor.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "obj_comb.h"
#include "textures.h"
#include "actor.h"
#include "en_wonderitem.h"

extern uint8_t POTCRATE_TEXTURES_MATCH_CONTENTS;
extern uint16_t CURR_ACTOR_SPAWN_INDEX;
Expand All @@ -23,6 +24,7 @@ extern int8_t curr_scene_setup;
#define OBJ_KIBAKO 0x110 // Small Crate
#define OBJ_KIBAKO2 0x1A0 // Large Crate
#define EN_G_SWITCH 0x0117 //Silver Rupee
#define EN_WONDER_ITEM 0x0112 // Wonder Item

// Called at the end of Actor_SetWorldToHome
// Reset the rotations for any actors that we may have passed data in through Actor_Spawn
Expand All @@ -35,7 +37,8 @@ void Actor_SetWorldToHome_End(z64_actor_t* actor) {
actor->rot_world.z = 0;
break;
}
case EN_ITEM00: {
case EN_ITEM00:
case EN_WONDER_ITEM: {
actor->rot_world.y = 0;
}
default: {
Expand All @@ -54,6 +57,9 @@ void Actor_After_UpdateAll_Hack(z64_actor_t* actor, z64_game_t* game) {
Actor_StoreFlagInRotation(actor, game, CURR_ACTOR_SPAWN_INDEX);
Actor_StoreChestType(actor, game);

// Add additional actor hacks here. These get called shortly after the call to actor_init
// Hacks are responsible for checking that they are the correct actor.
EnWonderitem_AfterInitHack(actor, game);
CURR_ACTOR_SPAWN_INDEX = 0; // reset CURR_ACTOR_SPAWN_INDEX
}

Expand All @@ -71,7 +77,8 @@ void Actor_StoreFlagInRotation(z64_actor_t* actor, z64_game_t* game, uint16_t ac
break;
}
// For the following actors we store the flag in the y rotation
case OBJ_KIBAKO2: {
case OBJ_KIBAKO2:
case EN_WONDER_ITEM: {
actor->rot_init.y = flag;
break;
}
Expand Down
151 changes: 151 additions & 0 deletions ASM/c/en_wonderitem.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#include <stdint.h>
#include "z64.h"
#include "en_wonderitem.h"
#include "get_items.h"

static colorRGBA8_t sEffectPrimColorRed = { 255, 0, 0, 0 };
static colorRGBA8_t sEffectPrimColorGreen = { 0, 255, 0, 0 };
static colorRGBA8_t sEffectPrimColorBlue = { 0, 0, 255, 0 };
static colorRGBA8_t sEffectPrimColorYellow = { 255, 255, 0, 0 };
static colorRGBA8_t sEffectPrimColoMagenta = { 255, 0, 255, 0 };
static colorRGBA8_t sEffectPrimColorCyan = {0, 255, 255, 0 };
static colorRGBA8_t sEffectEnvColor = { 255, 255, 255, 0 };
//static z64_xyzf_t sEffectVelocity = { 0.0f, 0.1f, 0.0f };
//static z64_xyzf_t sEffectAccel = { 0.0f, 0.01f, 0.0f };
static z64_xyzf_t sEffectVelocity = { 0.0f, 0.5f, 0.0f };
static z64_xyzf_t sEffectAccel = { 0.0f, 0.5f, 0.0f };


extern uint16_t drop_collectible_override_flag;
extern uint16_t CURR_ACTOR_SPAWN_INDEX;

void EnWonderitem_AfterInitHack(z64_actor_t* this, z64_game_t* globalCtx)
{
if(this->main_proc == NULL)
return;
if(this->actor_id != 0x112)
return;

EnWonderItem* wonderitem = (EnWonderItem*)this;
wonderitem->overridden = 0;

EnItem00 dummy;
dummy.actor.actor_id = 0x15;
dummy.actor.rot_init.y = this->rot_init.y; //flag was just stored in y rotation
dummy.actor.variable = 0;

// Check if the Wonderitem should be overridden
dummy.override = lookup_override(&(dummy.actor), globalCtx->scene_index, 0);
if(dummy.override.key.all != 0 && !Get_CollectibleOverrideFlag(&dummy))
{
wonderitem->overridden = 1;
}
}

void EnWonderItem_Multitag_DrawHack(z64_xyzf_t* tags, uint32_t index, EnWonderItem* this)
{
if(this->overridden)
{
colorRGBA8_t* color = &sEffectPrimColorBlue;
if(this->wonderMode == WONDERITEM_MULTITAG_ORDERED)
color = &sEffectPrimColorCyan;
z64_xyzf_t pos = tags[index];
// if(this->wonderMode != WONDERITEM_INTERACT_SWITCH)
// pos.y += 20.0;
z64_EffectSsKiraKira_SpawnSmall(&z64_game, &pos, &sEffectVelocity, &sEffectAccel, color, &sEffectEnvColor );
}

}

void EnWonderItem_DropCollectible_Hack(EnWonderItem* this, z64_game_t* globalCtx, int32_t autoCollect)
{
static int16_t dropTable[] = {
ITEM00_NUTS, ITEM00_HEART_PIECE, ITEM00_MAGIC_LARGE, ITEM00_MAGIC_SMALL,
ITEM00_HEART, ITEM00_ARROWS_SMALL, ITEM00_ARROWS_MEDIUM, ITEM00_ARROWS_LARGE,
ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_RUPEE_RED, ITEM00_FLEXIBLE,
};
int16_t i;
int16_t randomDrop;

// Always play the SFX
z64_PlaySFXID(NA_SE_SY_GET_ITEM);

// Override behavior. Spawn an overridden collectible on link
if(this->overridden)
{
drop_collectible_override_flag = this->actor.rot_init.y;
if(autoCollect)
z64_Item_DropCollectible2(globalCtx, &(z64_link.common.pos_world), 0);
else
z64_Item_DropCollectible(globalCtx, &this->actor.pos_world, 0);
drop_collectible_override_flag = 0;
if (this->switchFlag >= 0)
z64_Flags_SetSwitch(globalCtx, this->switchFlag);
z64_ActorKill(&this->actor);
return;
}

// Not overridden so use vanilla behavior
if (this->dropCount == 0) {
this->dropCount++;
}
for (i = this->dropCount; i > 0; i--) {
if (this->itemDrop < WONDERITEM_DROP_RANDOM) {
if ((this->itemDrop == WONDERITEM_DROP_FLEXIBLE) || !autoCollect) {
z64_Item_DropCollectible(globalCtx, &this->actor.pos_world, dropTable[this->itemDrop]);
} else {
z64_Item_DropCollectible(globalCtx, &this->actor.pos_world, dropTable[this->itemDrop] | 0x8000);
}
} else {
randomDrop = this->itemDrop - WONDERITEM_DROP_RANDOM;
if (!autoCollect) {
z64_Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.pos_world, randomDrop);
} else {
z64_Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.pos_world, randomDrop | 0x8000);
}
}
}
if (this->switchFlag >= 0) {
z64_Flags_SetSwitch(globalCtx, this->switchFlag);
}
z64_ActorKill(&this->actor);
}

void EnWonderItem_Update_Hack(EnWonderItem* this) {
colorRGBA8_t* color = NULL;
if(this->overridden) {
switch(this->wonderMode){
case(WONDERITEM_PROXIMITY_DROP): {
color = &sEffectPrimColorYellow;
break;
}
case(WONDERITEM_INTERACT_SWITCH):
case(WONDERITEM_BOMB_SOLDIER): {
color = &sEffectPrimColorRed;
break;
}
default:
break;
}
if(color) {
z64_EffectSsKiraKira_SpawnSmall(&z64_game, &(this->actor.pos_world), &sEffectVelocity, &sEffectAccel, color, &sEffectEnvColor );
}
}
}

// Hack to not kill wonderitem when switch flag is set if we need to override still
uint32_t EnWonderItem_Kill_Hack(EnWonderItem* this) {
EnItem00 dummy;
dummy.actor.actor_id = 0x15;
dummy.actor.rot_init.y = (CURR_ACTOR_SPAWN_INDEX) | (this->actor.room_index << 8);
dummy.actor.variable = 0;

// Check if the Wonderitem should be overridden
dummy.override = lookup_override(&(dummy.actor), z64_game.scene_index, 0);

if(dummy.override.key.all != 0 && !Get_CollectibleOverrideFlag(&dummy))
return 0;
if ((this->switchFlag >= 0) && z64_Flags_GetSwitch(&z64_game, this->switchFlag))
return 1;
return 0;
}
65 changes: 65 additions & 0 deletions ASM/c/en_wonderitem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#ifndef Z_EN_WONDER_ITEM_H
#define Z_EN_WONDER_ITEM_H

#include <stdint.h>
#include "z64.h"

struct EnWonderItem;

typedef void (*EnWonderItemUpdateFunc)(struct EnWonderItem*, z64_game_t*);

void EnWonderitem_AfterInitHack(z64_actor_t* actor, z64_game_t* game);

typedef struct EnWonderItem {
/* 0x0000 */ z64_actor_t actor;
/* 0x013C */ EnWonderItemUpdateFunc updateFunc;
/* 0x0140 */ float unkHeight; // sets height of dummied out mode 4
/* 0x0144 */ int16_t wonderMode;
/* 0x0146 */ int16_t itemDrop;
/* 0x0148 */ int16_t numTagPoints;
/* 0x014A */ int16_t dropCount;
/* 0x014C */ int16_t timer;
/* 0x014E */ int16_t tagFlags;
/* 0x014A */ int16_t tagCount;
/* 0x0152 */ int16_t switchFlag;
/* 0x0154 */ char unk_164[4];
/* 0x0158 */ int16_t nextTag;
/* 0x015A */ int16_t timerMod;
/* 0x015C */ z64_xyzf_t unkPos; // set to initial position by mode bomb soldier, then never used.
/* 0x0168 */ char unk_178[8];
/* 0x0170 */ char collider[0x4C];
/* 0x01BC */ char unk_1CC[4];
/* 0x01C0 */ uint8_t overridden;
/* 0x01C1 */ uint8_t spare[15];
} EnWonderItem; // size = 0x01D0

typedef enum {
/* 0 */ WONDERITEM_MULTITAG_FREE,
/* 1 */ WONDERITEM_TAG_POINT_FREE,
/* 2 */ WONDERITEM_PROXIMITY_DROP,
/* 3 */ WONDERITEM_INTERACT_SWITCH,
/* 4 */ WONDERITEM_UNUSED,
/* 5 */ WONDERITEM_MULTITAG_ORDERED,
/* 6 */ WONDERITEM_TAG_POINT_ORDERED,
/* 7 */ WONDERITEM_PROXIMITY_SWITCH,
/* 8 */ WONDERITEM_BOMB_SOLDIER,
/* 9 */ WONDERITEM_ROLL_DROP
} EnWonderItemMode;

typedef enum {
/* 0 */ WONDERITEM_DROP_NUTS,
/* 1 */ WONDERITEM_DROP_HEART_PIECE,
/* 2 */ WONDERITEM_DROP_MAGIC_LARGE,
/* 3 */ WONDERITEM_DROP_MAGIC_SMALL,
/* 4 */ WONDERITEM_DROP_HEART,
/* 5 */ WONDERITEM_DROP_ARROWS_SMALL,
/* 6 */ WONDERITEM_DROP_ARROWS_MEDIUM,
/* 7 */ WONDERITEM_DROP_ARROWS_LARGE,
/* 8 */ WONDERITEM_DROP_GREEN_RUPEE,
/* 9 */ WONDERITEM_DROP_BLUE_RUPEE,
/* A */ WONDERITEM_DROP_RED_RUPEE,
/* B */ WONDERITEM_DROP_FLEXIBLE,
/* C */ WONDERITEM_DROP_RANDOM
} EnWonderItemDrop;

#endif
25 changes: 20 additions & 5 deletions ASM/c/get_items.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extern uint8_t FAST_CHESTS;
extern uint8_t OCARINAS_SHUFFLED;
extern uint8_t NO_COLLECTIBLE_HEARTS;
extern uint32_t FREE_BOMBCHU_DROPS;
override_t cfg_item_overrides[1536] = { 0 };
override_t cfg_item_overrides[2200] = { 0 };
int item_overrides_count = 0;

z64_actor_t* dummy_actor = NULL;
Expand Down Expand Up @@ -44,8 +44,8 @@ uint8_t satisfied_pending_frames = 0;

// This table contains the offset (in bytes) of the start of a particular scene/room/setup flag space in collectible_override_flags.
// Call get_collectible_flag_offset to retrieve the desired offset.
uint8_t collectible_scene_flags_table[600];
alt_override_t alt_overrides[64];
uint8_t collectible_scene_flags_table[1000];
alt_override_t alt_overrides[90];

extern int8_t curr_scene_setup;
extern uint16_t CURR_ACTOR_SPAWN_INDEX;
Expand Down Expand Up @@ -635,6 +635,18 @@ void Item_DropCollectible_Room_Hack(EnItem00* spawnedActor) {
}
}

// Prevent overridden collectible items from despawning when changing to a room where
// they are still being drawn.
void Room_Change_Actor_Kill_Hack(z64_actor_t *actor) {
if(actor->actor_id == 0x15)
{
EnItem00* this = (EnItem00*)actor;
if(this->dropped && this->override.key.all > 0)
return;
}
z64_ActorKill(actor);
}

z64_actor_t* Item_DropCollectible_Actor_Spawn_Override(void* actorCtx, z64_game_t* globalCtx, int16_t actorId, float posX, float posY, float posZ, int16_t rotX, int16_t rotY, int16_t rotZ, int16_t params) {
rotY = drop_collectible_override_flag; // Get the override flag
EnItem00* spawnedActor = (EnItem00*)z64_SpawnActor(actorCtx, globalCtx,actorId, posX, posY, posZ, rotX, rotY, rotZ, params); // Spawn the actor
Expand All @@ -648,9 +660,12 @@ bool Item00_KillActorIfFlagIsSet(z64_actor_t* actor) {
EnItem00* this = (EnItem00*)actor;
this->is_silver_rupee = false;
uint16_t flag = 0;
if (drop_collectible_override_flag) {
this->dropped = false;
if(drop_collectible_override_flag) {
flag = drop_collectible_override_flag;
} else if (CURR_ACTOR_SPAWN_INDEX) {
this->dropped = true;
}
else if(CURR_ACTOR_SPAWN_INDEX) {
flag = (CURR_ACTOR_SPAWN_INDEX) | (actor->room_index << 8);
}
// Still need to build a dummy because we haven't set any info in the actor yet.
Expand Down
4 changes: 3 additions & 1 deletion ASM/c/get_items.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,14 @@ typedef struct EnItem00 {
float scale; // 0x014C
ColliderCylinder collider; // 0x0150 size = 4C
override_t override; // 0x019C
bool is_silver_rupee; // 0x????
bool is_silver_rupee; // 0x????
bool dropped;
} EnItem00;


typedef void (*z64_EnItem00ActionFunc)(struct EnItem00*, z64_game_t*);
typedef EnItem00* (*z64_Item_DropCollectible_proc)(z64_game_t* globalCtx, z64_xyzf_t* spawnPos, int16_t params);
typedef EnItem00* (*z64_Item_DropCollectibleRandom_proc)(z64_game_t *globalCtx, z64_actor_t *fromActor, z64_xyzf_t *spawnPos, int16_t params);

override_t lookup_override_by_key(override_key_t key);
override_t lookup_override(z64_actor_t* actor, uint8_t scene, uint8_t item_id);
Expand Down
Loading

0 comments on commit a1614c4

Please sign in to comment.