diff --git a/src/deh_tables.c b/src/deh_tables.c index f517e4484..bec4d9eb7 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4590,6 +4590,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_BATTLEUFO", "S_BATTLEUFO_LEG", "S_BATTLEUFO_DIE", + "S_BATTLEUFO_BEAM1", + "S_BATTLEUFO_BEAM2", "S_POWERUP_AURA", }; @@ -5727,6 +5729,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_BATTLEUFO_SPAWNER", "MT_BATTLEUFO", "MT_BATTLEUFO_LEG", + "MT_BATTLEUFO_BEAM", "MT_POWERUP_AURA", }; diff --git a/src/info.c b/src/info.c index 92f852d71..71ebf8855 100644 --- a/src/info.c +++ b/src/info.c @@ -5264,6 +5264,8 @@ state_t states[NUMSTATES] = {SPR_BUFO, 0, -1, {A_SetScale}, 3*FRACUNIT/2 , 0, S_NULL}, // S_BATTLEUFO {SPR_BUFO, 1, -1, {A_SetScale}, 2*FRACUNIT/2, 0, S_NULL}, // S_BATTLEUFO_LEG {SPR_BUFO, 0, 4, {A_BossScream}, 0, MT_EXPLODE, S_BATTLEUFO_DIE}, // S_BATTLEUFO_DIE + {SPR_DEZL, 1|FF_ANIMATE, 15, {NULL}, 2, 5, S_BATTLEUFO_BEAM2}, // S_BATTLEUFO_BEAM1 + {SPR_DEZL, 3, -1, {NULL}, 0, 0, S_NULL}, // S_BATTLEUFO_BEAM2 {SPR_RBOW, FF_PAPERSPRITE|FF_ADD|FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 14, 2, S_NULL}, // S_POWERUP_AURA }; @@ -22881,7 +22883,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, - + { // MT_SIGNSPARKLE -1, // doomednum S_SIGNSPARK1, // spawnstate @@ -29988,6 +29990,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_BATTLEUFO_BEAM + -1, // doomednum + S_BATTLEUFO_BEAM1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + -(FRACUNIT/2), // speed + 64*FRACUNIT, // radius + 55*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIP|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_POWERUP_AURA -1, // doomednum S_POWERUP_AURA, // spawnstate diff --git a/src/info.h b/src/info.h index b8e47715f..f5f402566 100644 --- a/src/info.h +++ b/src/info.h @@ -5693,6 +5693,8 @@ typedef enum state S_BATTLEUFO, S_BATTLEUFO_LEG, S_BATTLEUFO_DIE, + S_BATTLEUFO_BEAM1, + S_BATTLEUFO_BEAM2, S_POWERUP_AURA, @@ -6849,6 +6851,7 @@ typedef enum mobj_type MT_BATTLEUFO_SPAWNER, MT_BATTLEUFO, MT_BATTLEUFO_LEG, + MT_BATTLEUFO_BEAM, MT_POWERUP_AURA, diff --git a/src/k_objects.h b/src/k_objects.h index f81ddfa98..f48fb7e21 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -171,6 +171,7 @@ void Obj_UnlinkBattleUFOSpawner(mobj_t *spawner); void Obj_SpawnBattleUFOFromSpawner(void); INT32 Obj_GetFirstBattleUFOSpawnerID(void); void Obj_ResetUFOSpawners(void); +void Obj_BattleUFOBeamThink(mobj_t *beam); /* Power-Up Aura */ void Obj_SpawnPowerUpAura(player_t* player); diff --git a/src/objects/battle-ufo.cpp b/src/objects/battle-ufo.cpp index 09a6bc954..e4d45551d 100644 --- a/src/objects/battle-ufo.cpp +++ b/src/objects/battle-ufo.cpp @@ -29,6 +29,15 @@ struct UFO : mobj_t { Spawner* spawner() const { return static_cast(ufo_spawner(this)); } void spawner(Spawner* n) { P_SetTarget(&ufo_spawner(this), n); } + void spawn_beam() + { + mobj_t *x; + + x = P_SpawnMobjFromMobj(this, 0, 0, this->z - this->height, MT_BATTLEUFO_BEAM); + x->renderflags |= RF_FLOORSPRITE|RF_NOSPLATBILLBOARD|RF_SLOPESPLAT|RF_NOSPLATROLLANGLE; + x->colorized = true; + x->color = SKINCOLOR_SAPPHIRE; + } }; struct SpawnerCompare @@ -109,12 +118,19 @@ SpawnerList g_spawners; }; // namespace -void Obj_BattleUFOThink(mobj_t *ufo) +void Obj_BattleUFOThink(mobj_t *mobj) { + UFO* ufo = static_cast(mobj); + // Copied and slightly modified from k_kart.c fixed_t sine = FixedMul(ufo->scale, BATTLEUFO_BOB_AMP * FINESINE((((M_TAU_FIXED * BATTLEUFO_BOB_SPEED) * leveltime) >> ANGLETOFINESHIFT) & FINEMASK)); fixed_t targz = FixedMul(ufo->scale, sine) * P_MobjFlip(ufo); ufo->momz = targz; + + if ((leveltime/2) & 1) + { + ufo->spawn_beam(); + } } void Obj_BattleUFODeath(mobj_t *mobj) @@ -201,3 +217,13 @@ void Obj_ResetUFOSpawners(void) { g_spawners = {}; } + +void Obj_BattleUFOBeamThink(mobj_t *beam) +{ + P_SetObjectMomZ(beam, beam->info->speed, true); + + if (P_IsObjectOnGround(beam)) + { + P_RemoveMobj(beam); + } +} diff --git a/src/p_mobj.c b/src/p_mobj.c index 53b668b15..1e0c6f905 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8446,6 +8446,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj) Obj_BattleUFOLegThink(mobj); break; } + case MT_BATTLEUFO_BEAM: + { + Obj_BattleUFOBeamThink(mobj); + break; + } case MT_ROCKETSNEAKER: if (!mobj->target || !mobj->target->health) {