Add basic Battle UFO object functionality

This commit is contained in:
SteelT 2023-06-27 22:53:16 -04:00 committed by James R
parent 68f1626256
commit a24e9bb19f
5 changed files with 94 additions and 4 deletions

View file

@ -161,6 +161,12 @@ void Obj_SuperFlickyPlayerCollide(mobj_t *flicky, mobj_t *player);
void Obj_SuperFlickyLanding(mobj_t *flicky);
boolean Obj_IsSuperFlickyWhippable(const mobj_t *flicky);
/* Battle/Power-UP UFO */
void Obj_BattleUFOLegThink(mobj_t *leg);
void Obj_BattleUFOThink(mobj_t *ufo);
void Obj_SpawnBattleUFOLegs(mobj_t *ufo);
void Obj_BattleUFODeath(mobj_t *ufo);
/* Power-Up Aura */
void Obj_SpawnPowerUpAura(player_t* player);
void Obj_PowerUpAuraThink(mobj_t* mobj);

View file

@ -22,5 +22,6 @@ target_sources(SRB2SDL2 PRIVATE
gachabom-rebound.cpp
servant-hand.c
super-flicky.cpp
battle-ufo.c
powerup-aura.cpp
)

68
src/objects/battle-ufo.c Normal file
View file

@ -0,0 +1,68 @@
#include "../doomdef.h"
#include "../p_local.h"
#include "../k_objects.h"
#define BATTLEUFO_LEG_ZOFFS (3*FRACUNIT) // Spawn height offset from the body
#define BATTLEUFO_LEGS (3) // Number of UFO legs to spawn
#define BATTLEUFO_BOB_AMP (4) // UFO bob strength
#define BATTLEUFO_BOB_SPEED (TICRATE*2) // UFO bob speed
void Obj_BattleUFOThink(mobj_t *ufo)
{
// 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;
}
void Obj_BattleUFODeath(mobj_t *ufo)
{
ufo->momz = -(8*mapobjectscale)/2;
ufo->fuse = TICRATE;
}
void Obj_SpawnBattleUFOLegs(mobj_t *ufo)
{
INT32 i;
angle_t ang = 0;
const fixed_t angle_factor = ANGLE_MAX / BATTLEUFO_LEGS;
for (i = 0; i < BATTLEUFO_LEGS; i++)
{
mobj_t *leg = P_SpawnMobjFromMobj(ufo, 0, 0, BATTLEUFO_LEG_ZOFFS, MT_BATTLEUFO_LEG);
P_SetTarget(&leg->target, ufo);
ang += angle_factor;
leg->angle = ang;
}
}
void Obj_BattleUFOLegThink(mobj_t *leg)
{
if (!leg->target || P_MobjWasRemoved(leg->target))
{
P_RemoveMobj(leg);
return;
}
// Rotate around the UFO
if (leg->target->health > 0)
{
leg->angle += FixedAngle(leg->info->speed);
const angle_t fa = leg->angle>>ANGLETOFINESHIFT;
const fixed_t radius = FixedMul(14*leg->info->speed, leg->target->scale);
fixed_t x = leg->target->x + FixedMul(FINECOSINE(fa),radius);
fixed_t y = leg->target->y + FixedMul(FINESINE(fa),radius);
// TODO: Take gravflip into account
P_MoveOrigin(leg, x, y, leg->z);
}
leg->momz = leg->target->momz;
if (leg->target->hitlag)
{
leg->hitlag = leg->target->hitlag;
leg->eflags |= (leg->target->eflags & MFE_DAMAGEHITLAG);
}
}

View file

@ -799,7 +799,7 @@ void P_CheckTimeLimit(void)
{
if (((timelimitintics + starttime - leveltime) % TICRATE) == 0)
S_StartSound(NULL, sfx_s3ka7);
}
}
}
return;
}
@ -1725,7 +1725,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
case MT_MONITOR:
Obj_MonitorOnDeath(target);
break;
case MT_BATTLEUFO:
Obj_BattleUFODeath(target);
break;
default:
break;
}

View file

@ -8069,7 +8069,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
// cusval: responsible for disappear FX (should only happen once)
// S_MAGICANBOX: sides, starting angle is set in the spawner (SetRandomFakePlayerSkin)
// S_MAGICIANBOX_TOP, S_MAGICIANBOX_BOTTOM: splats with their own offset sprite sets
// S_MAGICIANBOX_TOP, S_MAGICIANBOX_BOTTOM: splats with their own offset sprite sets
mobj->extravalue2--;
@ -8436,6 +8436,16 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
Obj_ItemDebrisThink(mobj);
break;
}
case MT_BATTLEUFO:
{
Obj_BattleUFOThink(mobj);
break;
}
case MT_BATTLEUFO_LEG:
{
Obj_BattleUFOLegThink(mobj);
break;
}
case MT_ROCKETSNEAKER:
if (!mobj->target || !mobj->target->health)
{
@ -10920,6 +10930,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_SPHEREBOX:
Obj_RandomItemSpawn(mobj);
break;
case MT_BATTLEUFO:
Obj_SpawnBattleUFOLegs(mobj);
break;
default:
break;
}
@ -12268,7 +12281,7 @@ static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i)
if ((i == MT_RANDOMITEM) && (gametyperules & (GTR_PAPERITEMS|GTR_CIRCUIT)) == (GTR_PAPERITEMS|GTR_CIRCUIT))
return MT_PAPERITEMSPOT;
return i;
}