This commit is contained in:
t. boddy 2026-03-18 13:23:51 -04:00
parent 417cae168f
commit a8bc01bedd
59 changed files with 2053 additions and 1054 deletions

View file

@ -42,19 +42,27 @@ void spawnEnemy(u8 type, u8 zone){
enemies[i].pos.x = randX;
enemies[i].pos.y = randY;
enemies[i].off = 16;
enemies[i].image = SPR_addSprite(&fairySprite,
getScreenX(enemies[i].pos.x, player.camera) - enemies[i].off, fix32ToInt(enemies[i].pos.y) - enemies[i].off, TILE_ATTR(PAL0, 0, 0, 0));
static const SpriteDefinition* bossSpriteDefs[4] = { &boss1Sprite, &boss2Sprite, &boss3Sprite, &boss4Sprite };
SpriteDefinition const* spriteDef;
if(type == ENEMY_TYPE_DRONE) spriteDef = &eyeBigSprite;
else if(type == ENEMY_TYPE_BOSS) spriteDef = bossSpriteDefs[pendingBossNum % 4];
else spriteDef = &fairySprite;
enemies[i].off = (type == ENEMY_TYPE_BOSS) ? 24 : 16;
enemies[i].image = SPR_addSprite(spriteDef,
getScreenX(enemies[i].pos.x, player.camera) - enemies[i].off, F32_toInt(enemies[i].pos.y) - enemies[i].off, TILE_ATTR(PAL0, 0, 0, 0));
if(!enemies[i].image){
enemies[i].active = FALSE;
return;
}
SPR_setDepth(enemies[i].image, (type == ENEMY_TYPE_BOSS) ? 1 : 2);
SPR_setVisibility(enemies[i].image, HIDDEN);
enemies[i].hp = 1;
for(u8 j = 0; j < PROP_COUNT; j++){
enemies[i].ints[j] = 0;
enemies[i].fixes[j] = 0;
}
enemies[i].ints[3] = -1;
enemies[i].anim = 0;
switch(enemies[i].type){
case ENEMY_TYPE_TEST:
loadEnemyOne(i);
@ -75,9 +83,9 @@ void spawnEnemy(u8 type, u8 zone){
loadBoss(i);
break;
}
enemies[i].vel.x = fix32Mul(fix16ToFix32(cosFix16(enemies[i].angle)), enemies[i].speed);
enemies[i].vel.y = fix32Mul(fix16ToFix32(sinFix16(enemies[i].angle)), enemies[i].speed);
enemies[i].vel.x = F32_mul(F32_cos(enemies[i].angle), enemies[i].speed);
enemies[i].vel.y = F32_mul(F32_sin(enemies[i].angle), enemies[i].speed);
SPR_setAnim(enemies[i].image, enemies[i].anim);
}
static void boundsEnemy(u8 i){
@ -92,21 +100,39 @@ static void boundsEnemy(u8 i){
}
// carrying: only check for reaching the top
else if(enemies[i].pos.y <= FIX32(0)){
if(treasures[h].active) killTreasure(h);
enemies[i].ints[3] = -1;
treasureBeingCarried = FALSE;
if(enemies[i].type == ENEMY_TYPE_BUILDER){
u8 zone = fix32ToInt(enemies[i].pos.x) / 512;
spawnEnemy(ENEMY_TYPE_GUNNER, zone);
if(isAttract){
// in attract mode enemies can't die -- drop treasure and head back down
if(treasures[h].active){
treasures[h].state = TREASURE_FALLING;
treasures[h].carriedBy = -1;
treasures[h].vel.x = 0;
treasures[h].vel.y = FIX32(3);
}
enemies[i].ints[3] = -1;
treasureBeingCarried = FALSE;
enemies[i].vel.y = FIX32(1);
} else {
if(treasures[h].active) killTreasure(h);
enemies[i].ints[3] = -1;
treasureBeingCarried = FALSE;
if(enemies[i].type == ENEMY_TYPE_BUILDER){
u8 zone = F32_toInt(enemies[i].pos.x) / 512;
spawnEnemy(ENEMY_TYPE_GUNNER, zone);
}
enemies[i].hp = 0;
killEnemy(i);
}
enemies[i].hp = 0;
killEnemy(i);
return;
}
} else {
// not carrying: bounce off top and bottom
if(enemies[i].pos.y >= GAME_H_F - FIX32(enemies[i].off) || enemies[i].pos.y <= FIX32(enemies[i].off))
enemies[i].vel.y *= -1;
if(enemies[i].pos.y >= GAME_H_F - FIX32(enemies[i].off)){
if(enemies[i].vel.y > 0) enemies[i].vel.y = -enemies[i].vel.y;
enemies[i].pos.y = GAME_H_F - FIX32(enemies[i].off);
} else if(enemies[i].pos.y <= FIX32(enemies[i].off)){
if(enemies[i].vel.y < 0) enemies[i].vel.y = -enemies[i].vel.y;
enemies[i].pos.y = FIX32(enemies[i].off);
}
}
if(enemies[i].pos.x >= GAME_WRAP){
@ -118,8 +144,8 @@ static void boundsEnemy(u8 i){
}
static void updateEnemy(u8 i){
enemies[i].pos.x += enemies[i].vel.x;
enemies[i].pos.y += enemies[i].vel.y;
enemies[i].pos.x += enemies[i].vel.x - (player.vel.x >> 3);
enemies[i].pos.y += enemies[i].vel.y - (playerScrollVelY >> 3);
boundsEnemy(i);
if(!enemies[i].active) return;
@ -169,6 +195,7 @@ static void updateEnemy(u8 i){
bullets[expSlot].frame = 0;
bullets[expSlot].image = SPR_addSprite(&pBulletSprite, -32, -32, TILE_ATTR(PAL0, 0, 0, 0));
if(bullets[expSlot].image){
SPR_setDepth(bullets[expSlot].image, 5);
SPR_setAnim(bullets[expSlot].image, 1);
SPR_setFrame(bullets[expSlot].image, 0);
SPR_setHFlip(bullets[expSlot].image, random() & 1);
@ -180,24 +207,29 @@ static void updateEnemy(u8 i){
enemies[i].hp = 0;
killEnemy(i);
}
player.lives--;
if(player.lives == 0){
gameOver = TRUE;
XGM2_stop();
} else {
player.respawnClock = 120;
SPR_setVisibility(player.image, HIDDEN);
killBullets = TRUE;
hitMessageClock = 120;
hitMessageBullet = FALSE;
if(!isAttract){
player.lives--;
if(player.lives == 0){
gameOver = TRUE;
XGM2_stop();
sfxGameOver();
} else {
sfxPlayerHit();
player.respawnClock = 120;
SPR_setVisibility(player.image, HIDDEN);
killBullets = TRUE;
hitMessageClock = 120;
hitMessageBullet = FALSE;
}
}
}
}
s16 sx = getScreenX(enemies[i].pos.x, player.camera);
s16 sy = fix32ToInt(enemies[i].pos.y);
s16 sy = F32_toInt(enemies[i].pos.y);
SPR_setVisibility(enemies[i].image, enemies[i].onScreen ? VISIBLE : HIDDEN);
SPR_setHFlip(enemies[i].image, enemies[i].vel.x > 0);
if(enemies[i].type != ENEMY_TYPE_DRONE && enemies[i].type != ENEMY_TYPE_BOSS)
SPR_setHFlip(enemies[i].image, enemies[i].vel.x > 0);
SPR_setPosition(enemies[i].image, sx - enemies[i].off, sy - enemies[i].off);
enemies[i].clock++;