Deduplicate a bunch of emerald related code

- Add K_BattleOvertimeKiller
  - Kills an object if it is outside of the Overtime
    Barrier in Battle

- Add Obj_SpawnEmeraldSparks
  - Use this function for MT_EMERALD, MT_MONITOR and
    MT_SPECIAL_UFO

- Move thinking code for MT_EMERALD and MT_MONITOR to
  objects/monitor.c and objects/emerald.c
This commit is contained in:
James R 2023-08-12 19:22:48 -07:00
parent 2c8b889eee
commit 1c2a2155c0
9 changed files with 93 additions and 63 deletions

View file

@ -853,3 +853,22 @@ INT32 K_BumpersToHealth(UINT8 bumpers)
{ {
return (bumpers + 1); return (bumpers + 1);
} }
boolean K_BattleOvertimeKiller(mobj_t *mobj)
{
if (battleovertime.enabled < 10*TICRATE)
{
return false;
}
fixed_t distance = R_PointToDist2(mobj->x, mobj->y, battleovertime.x, battleovertime.y);
if (distance <= battleovertime.radius)
{
return false;
}
P_KillMobj(mobj, NULL, NULL, DMG_NORMAL);
return true;
}

View file

@ -51,6 +51,7 @@ void K_SpawnPlayerBattleBumpers(player_t *p);
void K_BattleInit(boolean singleplayercontext); void K_BattleInit(boolean singleplayercontext);
UINT8 K_Bumpers(player_t *player); UINT8 K_Bumpers(player_t *player);
INT32 K_BumpersToHealth(UINT8 bumpers); INT32 K_BumpersToHealth(UINT8 bumpers);
boolean K_BattleOvertimeKiller(mobj_t *mobj);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"

View file

@ -86,6 +86,7 @@ UINT32 K_GetSpecialUFODistance(void);
/* Monitors */ /* Monitors */
mobj_t *Obj_SpawnMonitor(mobj_t *origin, UINT8 numItemTypes, UINT8 emerald); mobj_t *Obj_SpawnMonitor(mobj_t *origin, UINT8 numItemTypes, UINT8 emerald);
void Obj_MonitorSpawnParts(mobj_t *monitor); void Obj_MonitorSpawnParts(mobj_t *monitor);
void Obj_MonitorThink(mobj_t *monitor);
void Obj_MonitorPartThink(mobj_t *part); void Obj_MonitorPartThink(mobj_t *part);
fixed_t Obj_MonitorGetDamage(mobj_t *monitor, mobj_t *inflictor, UINT8 damagetype); fixed_t Obj_MonitorGetDamage(mobj_t *monitor, mobj_t *inflictor, UINT8 damagetype);
void Obj_MonitorOnDamage(mobj_t *monitor, mobj_t *inflictor, INT32 damage); void Obj_MonitorOnDamage(mobj_t *monitor, mobj_t *inflictor, INT32 damage);
@ -201,6 +202,10 @@ void Obj_SneakerPanelSpawn(mobj_t *mobj);
void Obj_SneakerPanelSetup(mobj_t *mobj, mapthing_t *mthing); void Obj_SneakerPanelSetup(mobj_t *mobj, mapthing_t *mthing);
void Obj_SneakerPanelCollide(mobj_t *pad, mobj_t *mo); void Obj_SneakerPanelCollide(mobj_t *pad, mobj_t *mo);
/* Emerald */
void Obj_SpawnEmeraldSparks(mobj_t *source);
void Obj_EmeraldThink(mobj_t *emerald);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

View file

@ -27,4 +27,5 @@ target_sources(SRB2SDL2 PRIVATE
symbol.c symbol.c
dash-rings.c dash-rings.c
sneaker-panel.c sneaker-panel.c
emerald.c
) )

View file

@ -137,6 +137,8 @@ void Obj_BattleUFOThink(mobj_t *mobj)
{ {
Obj_PointPlayersToXY(mobj->x, mobj->y); Obj_PointPlayersToXY(mobj->x, mobj->y);
} }
K_BattleOvertimeKiller(mobj);
} }
void Obj_BattleUFODeath(mobj_t *mobj) void Obj_BattleUFODeath(mobj_t *mobj)

39
src/objects/emerald.c Normal file
View file

@ -0,0 +1,39 @@
#include "../k_battle.h"
#include "../k_objects.h"
#include "../info.h"
#include "../m_random.h"
#include "../p_local.h"
void Obj_SpawnEmeraldSparks(mobj_t *mobj)
{
if (leveltime % 3 != 0)
{
return;
}
mobj_t *sparkle = P_SpawnMobjFromMobj(
mobj,
P_RandomRange(PR_SPARKLE, -48, 48) * FRACUNIT,
P_RandomRange(PR_SPARKLE, -48, 48) * FRACUNIT,
P_RandomRange(PR_SPARKLE, 0, 64) * FRACUNIT,
MT_EMERALDSPARK
);
sparkle->color = mobj->color;
sparkle->momz += 8 * mobj->scale * P_MobjFlip(mobj);
sparkle->sprzoff = mobj->sprzoff;
}
void Obj_EmeraldThink(mobj_t *emerald)
{
if (emerald->threshold > 0)
{
emerald->threshold--;
}
A_AttractChase(emerald);
Obj_SpawnEmeraldSparks(emerald);
K_BattleOvertimeKiller(emerald);
}

View file

@ -495,6 +495,17 @@ Obj_SpawnMonitor
return monitor; return monitor;
} }
void
Obj_MonitorThink (mobj_t *monitor)
{
if (Obj_MonitorGetEmerald(monitor))
{
Obj_SpawnEmeraldSparks(monitor);
}
K_BattleOvertimeKiller(monitor);
}
void void
Obj_MonitorPartThink (mobj_t *part) Obj_MonitorPartThink (mobj_t *part)
{ {

View file

@ -467,19 +467,7 @@ static void UFOEmeraldVFX(mobj_t *ufo)
ufo->sprzoff = FixedMul(bobH, FINESINE(bobA >> ANGLETOFINESHIFT)); ufo->sprzoff = FixedMul(bobH, FINESINE(bobA >> ANGLETOFINESHIFT));
if (leveltime % 3 == 0) Obj_SpawnEmeraldSparks(ufo);
{
mobj_t *sparkle = P_SpawnMobjFromMobj(
ufo,
P_RandomRange(PR_SPARKLE, -48, 48) * FRACUNIT,
P_RandomRange(PR_SPARKLE, -48, 48) * FRACUNIT,
(P_RandomRange(PR_SPARKLE, 0, 64) * FRACUNIT) + FixedDiv(ufo->sprzoff, ufo->scale),
MT_EMERALDSPARK
);
sparkle->color = ufo->color;
sparkle->momz += 8 * ufo->scale * P_MobjFlip(ufo);
}
} }
static boolean UFOHumPlaying(mobj_t *ufo) { static boolean UFOHumPlaying(mobj_t *ufo) {

View file

@ -7550,48 +7550,19 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
break; break;
} }
case MT_EMERALD: case MT_EMERALD:
{ Obj_EmeraldThink(mobj);
if (mobj->threshold > 0)
mobj->threshold--;
A_AttractChase(mobj); if (P_MobjWasRemoved(mobj))
{
return false;
} }
/*FALLTHRU*/ break;
case MT_MONITOR: case MT_MONITOR:
Obj_MonitorThink(mobj);
if (P_MobjWasRemoved(mobj))
{ {
if (battleovertime.enabled >= 10*TICRATE) return false;
{
fixed_t distance = R_PointToDist2(mobj->x, mobj->y, battleovertime.x, battleovertime.y);
if (distance > battleovertime.radius)
{
// Delete emeralds to let them reappear
P_KillMobj(mobj, NULL, NULL, DMG_NORMAL);
return false;
}
}
// Don't spawn sparkles on a monitor with no
// emerald inside
if (mobj->type == MT_MONITOR &&
Obj_MonitorGetEmerald(mobj) == 0)
{
break;
}
if (leveltime % 3 == 0)
{
mobj_t *sparkle = P_SpawnMobjFromMobj(
mobj,
P_RandomRange(PR_SPARKLE, -48, 48) * FRACUNIT,
P_RandomRange(PR_SPARKLE, -48, 48) * FRACUNIT,
P_RandomRange(PR_SPARKLE, 0, 64) * FRACUNIT,
MT_EMERALDSPARK
);
sparkle->color = mobj->color;
sparkle->momz += 8 * mobj->scale * P_MobjFlip(mobj);
}
} }
break; break;
case MT_DRIFTEXPLODE: case MT_DRIFTEXPLODE:
@ -8466,19 +8437,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
} }
case MT_BATTLEUFO: case MT_BATTLEUFO:
{ {
if (battleovertime.enabled >= 10*TICRATE)
{
fixed_t distance = R_PointToDist2(mobj->x, mobj->y, battleovertime.x, battleovertime.y);
if (distance > battleovertime.radius)
{
// Delete emeralds to let them reappear
P_KillMobj(mobj, NULL, NULL, DMG_NORMAL);
return false;
}
}
Obj_BattleUFOThink(mobj); Obj_BattleUFOThink(mobj);
if (P_MobjWasRemoved(mobj))
{
return false;
}
break; break;
} }
case MT_BATTLEUFO_LEG: case MT_BATTLEUFO_LEG: