mirror of
https://github.com/HarbourMasters/Starship.git
synced 2025-03-13 19:34:03 +03:00
467 lines
15 KiB
C
467 lines
15 KiB
C
/*
|
|
* File: spawner.c
|
|
* System: Spawner
|
|
* Description: Spawner module meant to help documenting the rest of the code
|
|
* by being able to spawn Scenery, Sprites, Actors, Bosses, Items, Effects and Events.
|
|
* This is not part of the original game.
|
|
*/
|
|
|
|
#include "global.h"
|
|
#include "sf64object.h"
|
|
|
|
typedef enum ObjType {
|
|
/* 0 */ OBJ_SPAWN_SCENERY,
|
|
/* 1 */ OBJ_SPAWN_SCENERY_360,
|
|
/* 2 */ OBJ_SPAWN_SPRITE,
|
|
/* 3 */ OBJ_SPAWN_ACTOR,
|
|
/* 4 */ OBJ_SPAWN_BOSS,
|
|
/* 5 */ OBJ_SPAWN_ITEM,
|
|
/* 6 */ OBJ_SPAWN_EFFECT,
|
|
/* 7 */ OBJ_SPAWN_EVENT,
|
|
/* 8 */ OBJ_SPAWN_MAX
|
|
} ObjType;
|
|
|
|
typedef struct ObjCount {
|
|
s32 actor;
|
|
s32 boss;
|
|
s32 scenery;
|
|
s32 sprite;
|
|
s32 effect;
|
|
s32 item;
|
|
} ObjCount;
|
|
|
|
static int sObjId = 0;
|
|
static int sObjType = 0;
|
|
|
|
static int sTextXpos = 239;
|
|
static int sTextYpos = 173;
|
|
|
|
static OSContPad* sContPress;
|
|
static OSContPad* sContHold;
|
|
|
|
void Scenery_Load(Scenery* this, ObjectInit* objInit);
|
|
void Sprite_Load(Sprite* this, ObjectInit* objInit);
|
|
void Item_Load(Item* this, ObjectInit* objInit);
|
|
void Boss_Load(Boss* this, ObjectInit* objInit);
|
|
|
|
void Spawner_Actor(int actorId) {
|
|
if ((gControllerPress[0].button & L_TRIG) && (actorId >= OBJ_ACTOR_CO_GARUDA_1) &&
|
|
(actorId <= OBJ_ACTOR_SUPPLIES)) {
|
|
Vec3f* reticlePos = &D_display_801613E0[0];
|
|
Actor* actorSpawn = Game_SpawnActor(actorId);
|
|
|
|
if (actorSpawn != NULL) {
|
|
actorSpawn->obj.pos.x = reticlePos->x * 1.7f;
|
|
actorSpawn->obj.pos.y = 200.0f;
|
|
actorSpawn->obj.pos.z = gPlayer[0].pos.z - 1500.0f - (reticlePos->y * 1.7f);
|
|
actorSpawn->state = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Spawner_Boss(int bossId) {
|
|
if ((gControllerPress[0].button & L_TRIG) && (bossId >= OBJ_BOSS_CO_GRANGA) && (bossId <= OBJ_BOSS_AND_BRAIN)) {
|
|
Vec3f* reticlePos = &D_display_801613E0[0];
|
|
ObjectInit objInit;
|
|
s32 i;
|
|
|
|
objInit.zPos1 = objInit.zPos2 = 0;
|
|
objInit.xPos = reticlePos->x * 1.7f;
|
|
objInit.yPos = 200.0f;
|
|
objInit.rot.x = objInit.rot.y = objInit.rot.z = 0;
|
|
objInit.id = bossId;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gBosses); i++) {
|
|
if (gBosses[i].obj.status == OBJ_FREE) {
|
|
Boss_Load(&gBosses[i], &objInit);
|
|
gBosses[i].obj.pos.z = gPlayer[0].pos.z - 1500.0f - (reticlePos->y * 1.7f);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Spawner_Scenery(int sceneryId) {
|
|
if ((gControllerPress[0].button & L_TRIG) && (sceneryId >= OBJ_SCENERY_CO_STONE_ARCH) &&
|
|
(sceneryId <= OBJ_SCENERY_VE2_MOUNTAIN)) {
|
|
Vec3f* reticlePos = &D_display_801613E0[0];
|
|
ObjectInit objInit;
|
|
s32 i;
|
|
|
|
objInit.zPos1 = objInit.zPos2 = 0;
|
|
objInit.xPos = reticlePos->x * 1.7f;
|
|
objInit.yPos = 200.0f;
|
|
objInit.rot.x = objInit.rot.y = objInit.rot.z = 0;
|
|
objInit.id = sceneryId;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gScenery); i++) {
|
|
if (gScenery[i].obj.status == OBJ_FREE) {
|
|
Scenery_Load(&gScenery[i], &objInit);
|
|
gScenery[i].obj.pos.z = gPlayer[0].pos.z - 1500.0f - (reticlePos->y * 4.7f);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Spawner_Scenery360(s32 scenery360Id) {
|
|
if ((gControllerPress[0].button & L_TRIG) && (scenery360Id >= OBJ_SCENERY_AND_PATH_INTERSECTION) &&
|
|
(scenery360Id <= OBJ_SCENERY_VE2_MOUNTAIN)) {
|
|
Vec3f* reticlePos = &D_display_801613E0[0];
|
|
s32 i;
|
|
|
|
for (i = 0; i < 200; i++) {
|
|
if (gScenery360[i].obj.status == OBJ_FREE) {
|
|
Scenery360_Initialize(&gScenery360[i]);
|
|
gScenery360[i].obj.status = OBJ_ACTIVE;
|
|
gScenery360[i].obj.id = scenery360Id;
|
|
|
|
gScenery360[i].obj.pos.x = +reticlePos->x * 5.0f;
|
|
gScenery360[i].obj.pos.z = -reticlePos->y * 5.0f;
|
|
|
|
if (gLevelType == LEVELTYPE_PLANET) {
|
|
gScenery360[i].obj.pos.y = gGroundHeight;
|
|
} else {
|
|
gScenery360[i].obj.pos.y = gPlayer[0].pos.y;
|
|
}
|
|
|
|
gScenery360[i].obj.rot.y = 0;
|
|
Object_SetInfo(&gScenery360[i].info, gScenery360[i].obj.id);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Spawner_Sprite(int spriteId) {
|
|
if ((gControllerPress[0].button & L_TRIG) && (spriteId >= OBJ_SPRITE_CO_POLE) &&
|
|
(spriteId <= OBJ_SPRITE_GFOX_TARGET)) {
|
|
Vec3f* reticlePos = &D_display_801613E0[0];
|
|
ObjectInit objInit;
|
|
s32 i;
|
|
|
|
objInit.zPos1 = objInit.zPos2 = 0;
|
|
objInit.xPos = reticlePos->x * 1.7f;
|
|
objInit.yPos = 200.0f;
|
|
objInit.rot.x = objInit.rot.y = objInit.rot.z = 0;
|
|
objInit.id = spriteId;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gSprites); i++) {
|
|
if (gSprites[i].obj.status == OBJ_FREE) {
|
|
Sprite_Load(&gSprites[i], &objInit);
|
|
gSprites[i].obj.pos.z = gPlayer[0].pos.z - 1500.0f - (reticlePos->y * 1.7f);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Spawner_Item(int itemId) {
|
|
if ((gControllerPress[0].button & L_TRIG) && (itemId >= OBJ_ITEM_LASERS) && (itemId <= OBJ_ITEM_TRAINING_RING)) {
|
|
Vec3f* reticlePos = &D_display_801613E0[0];
|
|
ObjectInit objInit;
|
|
s32 i;
|
|
|
|
objInit.zPos1 = objInit.zPos2 = 0;
|
|
objInit.xPos = reticlePos->x * 1.7f;
|
|
objInit.yPos = 200.0f;
|
|
objInit.rot.x = objInit.rot.y = objInit.rot.z = 0;
|
|
objInit.id = itemId;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gItems); i++) {
|
|
if (gItems[i].obj.status == OBJ_FREE) {
|
|
Item_Load(&gItems[i], &objInit);
|
|
gItems[i].obj.pos.z = gPlayer[0].pos.z - 1500.0f - (reticlePos->y * 1.7f);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Spawner_Event(int eventId) {
|
|
if (gControllerPress[0].button & L_TRIG) {
|
|
Vec3f* reticlePos = &D_display_801613E0[0];
|
|
ObjectInit objInit;
|
|
s32 i;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gActors); i++) {
|
|
if (gActors[i].obj.status == OBJ_FREE) {
|
|
objInit.zPos1 = gPlayer[0].pos.z - 1500.0f - (reticlePos->y * 1.7f);
|
|
objInit.zPos2 = gPlayer[0].pos.z - 1500.0f - (reticlePos->y * 1.7f) + 300.0f;
|
|
objInit.xPos = reticlePos->x * 1.7f;
|
|
objInit.yPos = 200.0f;
|
|
objInit.rot.x = 0;
|
|
objInit.rot.y = 0;
|
|
objInit.rot.z = 0;
|
|
objInit.id = ACTOR_EVENT_ID + eventId;
|
|
ActorEvent_Load(&gActors[i], &objInit, i);
|
|
gActors[i].obj.pos.z = gPlayer[0].pos.z - 1500.0f - (reticlePos->y * 1.7f);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Spawner_Effect(int effectId) {
|
|
if ((gControllerPress[0].button & L_TRIG) && (effectId >= OBJ_EFFECT_FIRE_SMOKE_1) && (effectId < OBJ_ID_MAX)) {
|
|
Vec3f* reticlePos = &D_display_801613E0[0];
|
|
s32 i;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gEffects); i++) {
|
|
if (gEffects[i].obj.status == OBJ_FREE) {
|
|
Effect_Initialize(&gEffects[i]);
|
|
gEffects[i].obj.status = OBJ_INIT;
|
|
gEffects[i].obj.id = effectId;
|
|
gEffects[i].obj.pos.x = reticlePos->x * 1.7f;
|
|
gEffects[i].obj.pos.y = 200.0f;
|
|
gEffects[i].obj.pos.z = gPlayer[0].pos.z - 1000.0f - (reticlePos->y * 1.7f);
|
|
gEffects[i].vel.x = 0;
|
|
gEffects[i].vel.y = 0;
|
|
gEffects[i].vel.z = 0;
|
|
gEffects[i].obj.rot.x = 0;
|
|
gEffects[i].obj.rot.y = 0;
|
|
gEffects[i].obj.rot.z = 0;
|
|
// gEffects[i].timer_50 = 200;
|
|
Object_SetInfo(&gEffects[i].info, gEffects[i].obj.id);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ObjCount Spawner_ObjCount(void) {
|
|
ObjCount counter = { 0, 0, 0, 0, 0, 0 };
|
|
s32 i;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gActors); i++) {
|
|
if (gActors[i].obj.status != OBJ_FREE) {
|
|
counter.actor++;
|
|
}
|
|
}
|
|
for (i = 0; i < ARRAY_COUNT(gBosses); i++) {
|
|
if (gBosses[i].obj.status != OBJ_FREE) {
|
|
counter.boss++;
|
|
}
|
|
}
|
|
for (i = 0; i < ARRAY_COUNT(gScenery); i++) {
|
|
if (gScenery[i].obj.status != OBJ_FREE) {
|
|
counter.scenery++;
|
|
}
|
|
}
|
|
if (gLevelMode == LEVELMODE_ALL_RANGE) {
|
|
for (i = 0; i < 200; i++) {
|
|
if (gScenery360[i].obj.status != OBJ_FREE) {
|
|
counter.scenery++;
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < ARRAY_COUNT(gSprites); i++) {
|
|
if (gSprites[i].obj.status != OBJ_FREE) {
|
|
counter.sprite++;
|
|
}
|
|
}
|
|
for (i = 0; i < ARRAY_COUNT(gEffects); i++) {
|
|
if (gEffects[i].obj.status != OBJ_FREE) {
|
|
counter.effect++;
|
|
}
|
|
}
|
|
for (i = 0; i < ARRAY_COUNT(gItems); i++) {
|
|
if (gItems[i].obj.status != OBJ_FREE) {
|
|
counter.item++;
|
|
}
|
|
}
|
|
return counter;
|
|
}
|
|
|
|
void Spawner_ObjKill(void) {
|
|
s32 i;
|
|
|
|
for (i = 0; i <= ARRAY_COUNT(gActors); i++) {
|
|
Object_Kill(&gActors[i].obj, gActors[i].sfxSource);
|
|
}
|
|
for (i = 0; i <= ARRAY_COUNT(gBosses); i++) {
|
|
Object_Kill(&gBosses[i].obj, gBosses[i].sfxSource);
|
|
}
|
|
for (i = 0; i <= ARRAY_COUNT(gScenery); i++) {
|
|
Object_Kill(&gScenery[i].obj, gScenery[i].sfxSource);
|
|
}
|
|
for (i = 0; i <= ARRAY_COUNT(gSprites); i++) {
|
|
Sprite_Initialize(&gSprites[i]);
|
|
}
|
|
for (i = 0; i <= ARRAY_COUNT(gEffects); i++) {
|
|
Object_Kill(&gEffects[i].obj, gEffects[i].sfxSource);
|
|
}
|
|
for (i = 0; i <= ARRAY_COUNT(gItems); i++) {
|
|
Object_Kill(&gItems[i].obj, gItems[i].sfxSource);
|
|
}
|
|
if (gLevelMode == LEVELMODE_ALL_RANGE) {
|
|
for (i = 0; i < 200; i++) {
|
|
gScenery360[i].obj.status = OBJ_FREE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Use this function to add code that eases your documentation work!
|
|
void Spawner_Playground(void) {
|
|
Player* player = &gPlayer[0];
|
|
|
|
player->mercyTimer = 100;
|
|
gLaserStrength[0] = 2;
|
|
gBombCount[0] = 9;
|
|
gLifeCount[0] = 9;
|
|
|
|
#if 0
|
|
if (gControllerPress[0].button & L_JPAD) {
|
|
gArwingSpeed -= 50;
|
|
} else if (gControllerPress[0].button & R_JPAD) {
|
|
gArwingSpeed += 50;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void Spawner(void) {
|
|
static bool sFreeze = true;
|
|
static s32 sHoldTimer = 0;
|
|
ObjCount counter;
|
|
|
|
/* Prevent execution before gameplay */
|
|
if ((gGameState != GSTATE_PLAY) || (gPlayState <= PLAY_INIT)) {
|
|
return;
|
|
}
|
|
|
|
Spawner_Playground();
|
|
|
|
/* Object Selector */
|
|
sContPress = &gControllerPress[gMainController];
|
|
sContHold = &gControllerHold[gMainController];
|
|
|
|
if (sContHold->button & (L_JPAD | R_JPAD)) {
|
|
sHoldTimer++;
|
|
} else {
|
|
sHoldTimer = 0;
|
|
}
|
|
|
|
if (((sContHold->button & L_JPAD) && (sHoldTimer > 15)) || (sContPress->button & L_JPAD)) {
|
|
sObjId--;
|
|
} else if (((sContHold->button & R_JPAD) && (sHoldTimer > 15)) || (sContPress->button & R_JPAD)) {
|
|
sObjId++;
|
|
} else if (gControllerPress[0].button & D_JPAD) {
|
|
sFreeze ^= 1; // Freeze arwing.
|
|
} else if (gControllerPress[0].button & U_JPAD) {
|
|
Spawner_ObjKill();
|
|
} else if (gControllerPress[0].button & R_CBUTTONS) {
|
|
sObjType++;
|
|
switch (sObjType) {
|
|
case OBJ_SPAWN_EVENT:
|
|
sObjId = EVID_VENOM_FIGHTER_1;
|
|
break;
|
|
case OBJ_SPAWN_SCENERY:
|
|
sObjId = OBJ_SCENERY_CO_STONE_ARCH;
|
|
break;
|
|
case OBJ_SPAWN_SCENERY_360:
|
|
sObjId = OBJ_SCENERY_AND_PATH_INTERSECTION;
|
|
break;
|
|
case OBJ_SPAWN_SPRITE:
|
|
sObjId = OBJ_SPRITE_CO_POLE;
|
|
break;
|
|
case OBJ_SPAWN_ACTOR:
|
|
sObjId = OBJ_ACTOR_CO_GARUDA_1;
|
|
break;
|
|
case OBJ_SPAWN_BOSS:
|
|
sObjId = OBJ_BOSS_CO_GRANGA;
|
|
break;
|
|
case OBJ_SPAWN_ITEM:
|
|
sObjId = OBJ_ITEM_LASERS;
|
|
break;
|
|
case OBJ_SPAWN_EFFECT:
|
|
sObjId = OBJ_EFFECT_FIRE_SMOKE_1;
|
|
break;
|
|
default:
|
|
sObjId = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (sObjId < 0) {
|
|
sObjId = 0;
|
|
}
|
|
|
|
if (sObjType >= OBJ_SPAWN_MAX) {
|
|
sObjType = OBJ_SPAWN_SCENERY;
|
|
}
|
|
|
|
/* Freeze arwing */
|
|
if (sFreeze) {
|
|
gPlayer[0].baseSpeed = 0;
|
|
} else {
|
|
gPlayer[0].baseSpeed = gArwingSpeed;
|
|
}
|
|
|
|
RCP_SetupDL(&gMasterDisp, SETUPDL_83_OPTIONAL);
|
|
gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 255, 0, 255);
|
|
|
|
/* Spawners */
|
|
switch (sObjType) {
|
|
case OBJ_SPAWN_SCENERY:
|
|
Graphics_DisplaySmallText(10, 220, 1.0f, 1.0f, "SCENERY:");
|
|
Graphics_DisplaySmallNumber(80, 220, sObjId);
|
|
Spawner_Scenery(sObjId);
|
|
break;
|
|
case OBJ_SPAWN_SCENERY_360:
|
|
Graphics_DisplaySmallText(10, 220, 1.0f, 1.0f, "SCENERY360:");
|
|
Graphics_DisplaySmallNumber(100, 220, sObjId);
|
|
Spawner_Scenery360(sObjId);
|
|
break;
|
|
case OBJ_SPAWN_SPRITE:
|
|
Graphics_DisplaySmallText(10, 220, 1.0f, 1.0f, "SPRITE:");
|
|
Graphics_DisplaySmallNumber(65, 220, sObjId);
|
|
Spawner_Sprite(sObjId);
|
|
break;
|
|
case OBJ_SPAWN_ACTOR:
|
|
Graphics_DisplaySmallText(10, 220, 1.0f, 1.0f, "ACTOR:");
|
|
Graphics_DisplaySmallNumber(60, 220, sObjId);
|
|
Spawner_Actor(sObjId);
|
|
break;
|
|
case OBJ_SPAWN_BOSS:
|
|
Graphics_DisplaySmallText(10, 220, 1.0f, 1.0f, "BOSS:");
|
|
Graphics_DisplaySmallNumber(55, 220, sObjId);
|
|
Spawner_Boss(sObjId);
|
|
break;
|
|
case OBJ_SPAWN_ITEM:
|
|
Graphics_DisplaySmallText(10, 220, 1.0f, 1.0f, "ITEM:");
|
|
Graphics_DisplaySmallNumber(50, 220, sObjId);
|
|
Spawner_Item(sObjId);
|
|
break;
|
|
case OBJ_SPAWN_EFFECT:
|
|
Graphics_DisplaySmallText(10, 220, 1.0f, 1.0f, "EFFECT:");
|
|
Graphics_DisplaySmallNumber(65, 220, sObjId);
|
|
Spawner_Effect(sObjId);
|
|
break;
|
|
case OBJ_SPAWN_EVENT:
|
|
Graphics_DisplaySmallText(10, 220, 1.0f, 1.0f, "EVENT:");
|
|
Graphics_DisplaySmallNumber(60, 220, sObjId);
|
|
Spawner_Event(sObjId);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 255, 255, 255);
|
|
|
|
Graphics_DisplaySmallText(sTextXpos - 8, sTextYpos + 00, 1.0f, 1.0f, "SCENERY:");
|
|
Graphics_DisplaySmallText(sTextXpos - 4, sTextYpos + 10, 1.0f, 1.0f, "SPRITES:");
|
|
Graphics_DisplaySmallText(sTextXpos + 0, sTextYpos + 20, 1.0f, 1.0f, "ACTORS:");
|
|
Graphics_DisplaySmallText(sTextXpos + 0, sTextYpos + 30, 1.0f, 1.0f, "BOSSES:");
|
|
Graphics_DisplaySmallText(sTextXpos + 12, sTextYpos + 40, 1.0f, 1.0f, "ITEMS:");
|
|
Graphics_DisplaySmallText(sTextXpos - 8, sTextYpos + 50, 1.0f, 1.0f, "EFFECTS:");
|
|
|
|
counter = Spawner_ObjCount();
|
|
|
|
Graphics_DisplaySmallNumber(sTextXpos + 55, sTextYpos + 00, counter.scenery);
|
|
Graphics_DisplaySmallNumber(sTextXpos + 55, sTextYpos + 10, counter.sprite);
|
|
Graphics_DisplaySmallNumber(sTextXpos + 55, sTextYpos + 20, counter.actor);
|
|
Graphics_DisplaySmallNumber(sTextXpos + 55, sTextYpos + 30, counter.boss);
|
|
Graphics_DisplaySmallNumber(sTextXpos + 55, sTextYpos + 40, counter.item);
|
|
Graphics_DisplaySmallNumber(sTextXpos + 55, sTextYpos + 50, counter.effect);
|
|
}
|