summaryrefslogtreecommitdiff
path: root/soh/src/code
diff options
context:
space:
mode:
authoraMannus <mannusmenting@gmail.com>2022-12-06 10:33:50 +0100
committerGitHub <noreply@github.com>2022-12-06 10:33:50 +0100
commit598cac725e580b8acdf18f91263efa4d484231c9 (patch)
tree132f385a0add75cff064060d2ca625eef689ab6b /soh/src/code
parentd9a08d0747bcde5e225b1f9b5e8e2055c74827d1 (diff)
[Feature] Rando: Enemy Randomizer V1 (#1781)
Diffstat (limited to 'soh/src/code')
-rw-r--r--soh/src/code/z_actor.c23
-rw-r--r--soh/src/code/z_en_item00.c32
-rw-r--r--soh/src/code/z_horse.c24
-rw-r--r--soh/src/code/z_message_PAL.c2
4 files changed, 50 insertions, 31 deletions
diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c
index 2e17eeacc..f94f3d7ac 100644
--- a/soh/src/code/z_actor.c
+++ b/soh/src/code/z_actor.c
@@ -7,6 +7,7 @@
#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
#include "objects/object_bdoor/object_bdoor.h"
#include "soh/frame_interpolation.h"
+#include "soh/Enhancements/enemyrandomizer.h"
#if defined(_MSC_VER) || defined(__GNUC__)
#include <string.h>
@@ -2506,7 +2507,7 @@ void Actor_UpdateAll(PlayState* play, ActorContext* actorCtx) {
refActor = &GET_PLAYER(play)->actor;
KREG(0) = 0;
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, refActor->world.pos.x,
- refActor->world.pos.y + 100.0f, refActor->world.pos.z, 0, 0, 0, 1);
+ refActor->world.pos.y + 100.0f, refActor->world.pos.z, 0, 0, 0, 1, true);
}
sp80 = &D_80116068[0];
@@ -3141,7 +3142,16 @@ void Actor_FreeOverlay(ActorOverlay* actorOverlay) {
int gMapLoading = 0;
Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 posX, f32 posY, f32 posZ,
- s16 rotX, s16 rotY, s16 rotZ, s16 params) {
+ s16 rotX, s16 rotY, s16 rotZ, s16 params, s16 canRandomize) {
+
+ uint8_t tryRandomizeEnemy = CVar_GetS32("gRandomizedEnemies", 0) && gSaveContext.fileNum >= 0 && gSaveContext.fileNum <= 2 && canRandomize;
+
+ if (tryRandomizeEnemy) {
+ if (!GetRandomizedEnemy(play, &actorId, &posX, &posY, &posZ, &rotX, &rotY, &rotZ, &params)) {
+ return NULL;
+ }
+ }
+
s32 pad;
Actor* actor;
ActorInit* actorInit;
@@ -3226,8 +3236,9 @@ Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 pos
objBankIndex = Object_GetIndex(&play->objectCtx, actorInit->objectId);
- if (objBankIndex < 0 && !gMapLoading)
+ if (objBankIndex < 0 && (!gMapLoading || CVar_GetS32("gRandomizedEnemies", 0))) {
objBankIndex = 0;
+ }
if ((objBankIndex < 0) ||
((actorInit->category == ACTORCAT_ENEMY) && Flags_GetClear(play, play->roomCtx.curRoom.num))) {
@@ -3293,7 +3304,7 @@ Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 pos
Actor* Actor_SpawnAsChild(ActorContext* actorCtx, Actor* parent, PlayState* play, s16 actorId, f32 posX,
f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, s16 params) {
- Actor* spawnedActor = Actor_Spawn(actorCtx, play, actorId, posX, posY, posZ, rotX, rotY, rotZ, params);
+ Actor* spawnedActor = Actor_Spawn(actorCtx, play, actorId, posX, posY, posZ, rotX, rotY, rotZ, params, true);
if (spawnedActor == NULL) {
return NULL;
@@ -3327,7 +3338,7 @@ void Actor_SpawnTransitionActors(PlayState* play, ActorContext* actorCtx) {
(transitionActor->sides[1].room == play->roomCtx.prevRoom.num)))) {
Actor_Spawn(actorCtx, play, (s16)(transitionActor->id & 0x1FFF), transitionActor->pos.x,
transitionActor->pos.y, transitionActor->pos.z, 0, transitionActor->rotY, 0,
- (i << 0xA) + transitionActor->params);
+ (i << 0xA) + transitionActor->params, true);
transitionActor->id = -transitionActor->id;
numActors = play->transiActorCtx.numActors;
@@ -3340,7 +3351,7 @@ void Actor_SpawnTransitionActors(PlayState* play, ActorContext* actorCtx) {
Actor* Actor_SpawnEntry(ActorContext* actorCtx, ActorEntry* actorEntry, PlayState* play) {
gMapLoading = 1;
Actor* ret = Actor_Spawn(actorCtx, play, actorEntry->id, actorEntry->pos.x, actorEntry->pos.y, actorEntry->pos.z,
- actorEntry->rot.x, actorEntry->rot.y, actorEntry->rot.z, actorEntry->params);
+ actorEntry->rot.x, actorEntry->rot.y, actorEntry->rot.z, actorEntry->params, true);
gMapLoading = 0;
return ret;
diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c
index cbc8f7607..f1e920b3d 100644
--- a/soh/src/code/z_en_item00.c
+++ b/soh/src/code/z_en_item00.c
@@ -330,6 +330,17 @@ void EnItem00_SetupAction(EnItem00* this, EnItem00ActionFunc actionFunc) {
this->actionFunc = actionFunc;
}
+void EnItem00_SetObjectDependency(EnItem00* this, PlayState* play, s16 objectIndex) {
+ // Remove object dependency for Enemy Randomizer and Crowd Control to allow Like-likes to
+ // drop equipment correctly in rooms where Like-likes normally don't spawn.
+ if (CVar_GetS32("gRandomizedEnemies", 0) || CVar_GetS32("gCrowdControl", 0)) {
+ this->actor.objBankIndex = 0;
+ } else {
+ this->actor.objBankIndex = Object_GetIndex(&play->objectCtx, objectIndex);
+ Actor_SetObjectDependency(play, &this->actor);
+ }
+}
+
void EnItem00_Init(Actor* thisx, PlayState* play) {
EnItem00* this = (EnItem00*)thisx;
s32 pad;
@@ -397,8 +408,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
this->scale = 0.01f;
break;
case ITEM00_SHIELD_DEKU:
- this->actor.objBankIndex = Object_GetIndex(&play->objectCtx, OBJECT_GI_SHIELD_1);
- Actor_SetObjectDependency(play, &this->actor);
+ EnItem00_SetObjectDependency(this, play, OBJECT_GI_SHIELD_1);
Actor_SetScale(&this->actor, 0.5f);
this->scale = 0.5f;
yOffset = 0.0f;
@@ -406,8 +416,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
this->actor.world.rot.x = 0x4000;
break;
case ITEM00_SHIELD_HYLIAN:
- this->actor.objBankIndex = Object_GetIndex(&play->objectCtx, OBJECT_GI_SHIELD_2);
- Actor_SetObjectDependency(play, &this->actor);
+ EnItem00_SetObjectDependency(this, play, OBJECT_GI_SHIELD_2);
Actor_SetScale(&this->actor, 0.5f);
this->scale = 0.5f;
yOffset = 0.0f;
@@ -416,8 +425,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
break;
case ITEM00_TUNIC_ZORA:
case ITEM00_TUNIC_GORON:
- this->actor.objBankIndex = Object_GetIndex(&play->objectCtx, OBJECT_GI_CLOTHES);
- Actor_SetObjectDependency(play, &this->actor);
+ EnItem00_SetObjectDependency(this, play, OBJECT_GI_CLOTHES);
Actor_SetScale(&this->actor, 0.5f);
this->scale = 0.5f;
yOffset = 0.0f;
@@ -1552,7 +1560,7 @@ EnItem00* Item_DropCollectible(PlayState* play, Vec3f* spawnPos, s16 params) {
if (((params & 0x00FF) == ITEM00_FLEXIBLE) && !param4000) {
// TODO: Prevent the cast to EnItem00 here since this is a different actor (En_Elf)
spawnedActor = (EnItem00*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, spawnPos->x,
- spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0, FAIRY_HEAL_TIMED);
+ spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0, FAIRY_HEAL_TIMED, true);
EffectSsDeadSound_SpawnStationary(play, spawnPos, NA_SE_EV_BUTTERFRY_TO_FAIRY, true,
DEADSOUND_REPEAT_MODE_OFF, 40);
} else {
@@ -1562,7 +1570,7 @@ EnItem00* Item_DropCollectible(PlayState* play, Vec3f* spawnPos, s16 params) {
if (params != -1) {
spawnedActor = (EnItem00*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ITEM00, spawnPos->x,
- spawnPos->y, spawnPos->z, 0, 0, 0, params | param8000 | param3F00);
+ spawnPos->y, spawnPos->z, 0, 0, 0, params | param8000 | param3F00, true);
if ((spawnedActor != NULL) && !param8000) {
spawnedActor->actor.velocity.y = !param4000 ? 8.0f : -2.0f;
spawnedActor->actor.speedXZ = 2.0f;
@@ -1597,14 +1605,14 @@ EnItem00* Item_DropCollectible2(PlayState* play, Vec3f* spawnPos, s16 params) {
if (((params & 0x00FF) == ITEM00_FLEXIBLE) && !param4000) {
// TODO: Prevent the cast to EnItem00 here since this is a different actor (En_Elf)
spawnedActor = (EnItem00*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, spawnPos->x,
- spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0, FAIRY_HEAL_TIMED);
+ spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0, FAIRY_HEAL_TIMED, true);
EffectSsDeadSound_SpawnStationary(play, spawnPos, NA_SE_EV_BUTTERFRY_TO_FAIRY, true,
DEADSOUND_REPEAT_MODE_OFF, 40);
} else {
params = func_8001F404(params & 0x00FF);
if (params != -1) {
spawnedActor = (EnItem00*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ITEM00, spawnPos->x,
- spawnPos->y, spawnPos->z, 0, 0, 0, params | param8000 | param3F00);
+ spawnPos->y, spawnPos->z, 0, 0, 0, params | param8000 | param3F00, true);
if ((spawnedActor != NULL) && !param8000) {
spawnedActor->actor.velocity.y = 0.0f;
spawnedActor->actor.speedXZ = 0.0f;
@@ -1668,7 +1676,7 @@ void Item_DropCollectibleRandom(PlayState* play, Actor* fromActor, Vec3f* spawnP
if (dropId == ITEM00_FLEXIBLE) {
if (gSaveContext.health <= 0x10) { // 1 heart or less
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0,
- 0, 0, FAIRY_HEAL_TIMED);
+ 0, 0, FAIRY_HEAL_TIMED, true);
EffectSsDeadSound_SpawnStationary(play, spawnPos, NA_SE_EV_BUTTERFRY_TO_FAIRY, true,
DEADSOUND_REPEAT_MODE_OFF, 40);
return;
@@ -1716,7 +1724,7 @@ void Item_DropCollectibleRandom(PlayState* play, Actor* fromActor, Vec3f* spawnP
dropId = func_8001F404(dropId);
if (dropId != 0xFF) {
spawnedActor = (EnItem00*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ITEM00, spawnPos->x,
- spawnPos->y, spawnPos->z, 0, 0, 0, dropId);
+ spawnPos->y, spawnPos->z, 0, 0, 0, dropId, true);
if ((spawnedActor != NULL) && (dropId != 0xFF)) {
spawnedActor->actor.velocity.y = 8.0f;
spawnedActor->actor.speedXZ = 2.0f;
diff --git a/soh/src/code/z_horse.c b/soh/src/code/z_horse.c
index 5d829d3e5..9b5caf8b5 100644
--- a/soh/src/code/z_horse.c
+++ b/soh/src/code/z_horse.c
@@ -50,7 +50,7 @@ void func_8006D0EC(PlayState* play, Player* player) {
if ((AREG(6) != 0) && (Flags_GetEventChkInf(0x18) || (DREG(1) != 0))) {
player->rideActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, player->actor.world.pos.x,
player->actor.world.pos.y, player->actor.world.pos.z, player->actor.shape.rot.x,
- player->actor.shape.rot.y, player->actor.shape.rot.z, 9);
+ player->actor.shape.rot.y, player->actor.shape.rot.z, 9, true);
ASSERT(player->rideActor != NULL);
@@ -65,11 +65,11 @@ void func_8006D0EC(PlayState* play, Player* player) {
Actor* horseActor;
gSaveContext.minigameState = 0;
horseActor =
- Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, 3586.0f, 1413.0f, -402.0f, 0, 0x4000, 0, 1);
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, 3586.0f, 1413.0f, -402.0f, 0, 0x4000, 0, 1, true);
horseActor->room = -1;
} else if ((gSaveContext.entranceIndex == 1230) && (gSaveContext.eventChkInf[1] & 0x100)) {
Actor* horseActor =
- Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, -25.0f, 0.0f, -1600.0f, 0, -0x4000, 0, 1);
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, -25.0f, 0.0f, -1600.0f, 0, -0x4000, 0, 1, true);
ASSERT(horseActor != NULL);
} else if ((play->sceneNum == gSaveContext.horseData.scene) &&
(((Flags_GetEventChkInf(0x18) != 0) && (!gSaveContext.n64ddFlag ||
@@ -82,7 +82,7 @@ void func_8006D0EC(PlayState* play, Player* player) {
if (func_8006CFC0(gSaveContext.horseData.scene)) {
Actor* horseActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE,
gSaveContext.horseData.pos.x, gSaveContext.horseData.pos.y,
- gSaveContext.horseData.pos.z, 0, gSaveContext.horseData.angle, 0, 1);
+ gSaveContext.horseData.pos.z, 0, gSaveContext.horseData.angle, 0, 1, true);
ASSERT(horseActor != NULL);
if (play->sceneNum == SCENE_SPOT12) {
horseActor->room = -1;
@@ -96,7 +96,7 @@ void func_8006D0EC(PlayState* play, Player* player) {
}
} else if ((play->sceneNum == SCENE_SPOT20) && !Flags_GetEventChkInf(0x18) && (DREG(1) == 0)) {
Actor* horseActor =
- Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, 0.0f, 0.0f, -500.0f, 0, 0, 0, 1);
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, 0.0f, 0.0f, -500.0f, 0, 0, 0, 1, true);
ASSERT(horseActor != NULL);
} else if (Flags_GetEventChkInf(0x18) || (DREG(1) != 0)) {
for (i = 0; i < ARRAY_COUNT(horseSpawns); i++) {
@@ -104,7 +104,7 @@ void func_8006D0EC(PlayState* play, Player* player) {
if (horseSpawn->scene == play->sceneNum) {
Actor* horseActor =
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, horseSpawn->pos.x, horseSpawn->pos.y,
- horseSpawn->pos.z, 0, horseSpawn->angle, 0, horseSpawn->type);
+ horseSpawn->pos.z, 0, horseSpawn->angle, 0, horseSpawn->type, true);
ASSERT(horseActor != NULL);
if (play->sceneNum == SCENE_SPOT12) {
horseActor->room = -1;
@@ -115,7 +115,7 @@ void func_8006D0EC(PlayState* play, Player* player) {
}
} else if (!Flags_GetEventChkInf(0x18)) {
if ((DREG(1) == 0) && (play->sceneNum == SCENE_SOUKO) && !IS_DAY) {
- Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, 0.0f, 0.0f, -60.0f, 0, 0x7360, 0, 1);
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, 0.0f, 0.0f, -60.0f, 0, 0x7360, 0, 1, true);
}
}
}
@@ -154,7 +154,7 @@ void func_8006D684(PlayState* play, Player* player) {
}
player->rideActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, spawnPos.x, spawnPos.y,
- spawnPos.z, 0, player->actor.world.rot.y, 0, 7);
+ spawnPos.z, 0, player->actor.world.rot.y, 0, 7, true);
ASSERT(player->rideActor != NULL);
Actor_MountHorse(play, player, player->rideActor);
@@ -163,7 +163,7 @@ void func_8006D684(PlayState* play, Player* player) {
} else if ((play->sceneNum == SCENE_SPOT20) && ((gSaveContext.eventInf[0] & 0xF) == 6) &&
(Flags_GetEventChkInf(0x18) == 0) && (DREG(1) == 0)) {
player->rideActor =
- Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, 894.0f, 0.0f, -2084.0f, 0, -0x7FFF, 0, 5);
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, 894.0f, 0.0f, -2084.0f, 0, -0x7FFF, 0, 5, true);
ASSERT(player->rideActor != NULL);
Actor_MountHorse(play, player, player->rideActor);
@@ -193,7 +193,7 @@ void func_8006D684(PlayState* play, Player* player) {
player->rideActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE,
D_8011F9B8[i].pos.x, D_8011F9B8[i].pos.y, D_8011F9B8[i].pos.z, 0,
- player->actor.world.rot.y, 0, D_8011F9B8[i].type);
+ player->actor.world.rot.y, 0, D_8011F9B8[i].type, true);
ASSERT(player->rideActor != NULL);
Actor_MountHorse(play, player, player->rideActor);
@@ -208,7 +208,7 @@ void func_8006D684(PlayState* play, Player* player) {
player->rideActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE,
D_8011F9B8[i].pos.x, D_8011F9B8[i].pos.y, D_8011F9B8[i].pos.z, 0,
- D_8011F9B8[i].angle, 0, D_8011F9B8[i].type | temp);
+ D_8011F9B8[i].angle, 0, D_8011F9B8[i].type | temp, true);
ASSERT(player->rideActor != NULL);
player->actor.world.pos.x = D_8011F9B8[i].pos.x;
@@ -228,7 +228,7 @@ void func_8006D684(PlayState* play, Player* player) {
} else {
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, D_8011F9B8[i].pos.x,
D_8011F9B8[i].pos.y, D_8011F9B8[i].pos.z, 0, D_8011F9B8[i].angle, 0,
- D_8011F9B8[i].type);
+ D_8011F9B8[i].type, true);
}
break;
}
diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c
index 1495a9102..fdc6b5b68 100644
--- a/soh/src/code/z_message_PAL.c
+++ b/soh/src/code/z_message_PAL.c
@@ -2680,7 +2680,7 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
Actor_Spawn(&play->actorCtx, play,
sOcarinaEffectActorIds[msgCtx->lastPlayedSong - OCARINA_SONG_SARIAS],
player->actor.world.pos.x, player->actor.world.pos.y, player->actor.world.pos.z, 0,
- 0, 0, sOcarinaEffectActorParams[msgCtx->lastPlayedSong - OCARINA_SONG_SARIAS]);
+ 0, 0, sOcarinaEffectActorParams[msgCtx->lastPlayedSong - OCARINA_SONG_SARIAS], true);
}
}
break;