mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-28 04:51:42 +00:00
Battle UFO spawning behavior
- MT_BATTLEUFO_SPAWNER args[0] is the ID - Spawn a random UFO from the list spawner at the start of Battle - UFO spawns 200 units above the spawner - After destroyig a UFO, wait 25 seconds before spawning the next UFO (next ID in the list)
This commit is contained in:
parent
2ce05f018e
commit
f5d68783fc
8 changed files with 166 additions and 2 deletions
|
|
@ -350,6 +350,11 @@ void K_RunPaperItemSpawners(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (leveltime == g_battleufo.due)
|
||||||
|
{
|
||||||
|
Obj_SpawnBattleUFOFromSpawner();
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsOnInterval(interval))
|
if (!IsOnInterval(interval))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
@ -797,6 +802,9 @@ void K_BattleInit(boolean singleplayercontext)
|
||||||
K_SpawnPlayerBattleBumpers(players+i);
|
K_SpawnPlayerBattleBumpers(players+i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_battleufo.due = starttime;
|
||||||
|
g_battleufo.previousId = Obj_GetFirstBattleUFOSpawnerID();
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT8 K_Bumpers(player_t *player)
|
UINT8 K_Bumpers(player_t *player)
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ extern "C" {
|
||||||
#define BATTLE_SPAWN_INTERVAL (4*TICRATE)
|
#define BATTLE_SPAWN_INTERVAL (4*TICRATE)
|
||||||
#define BATTLE_DESPAWN_TIME (15*TICRATE)
|
#define BATTLE_DESPAWN_TIME (15*TICRATE)
|
||||||
#define BATTLE_POWERUP_TIME (20*TICRATE)
|
#define BATTLE_POWERUP_TIME (20*TICRATE)
|
||||||
|
#define BATTLE_UFO_TIME (25*TICRATE)
|
||||||
|
|
||||||
extern struct battleovertime
|
extern struct battleovertime
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,11 @@ void Obj_BattleUFOLegThink(mobj_t *leg);
|
||||||
void Obj_BattleUFOThink(mobj_t *ufo);
|
void Obj_BattleUFOThink(mobj_t *ufo);
|
||||||
void Obj_SpawnBattleUFOLegs(mobj_t *ufo);
|
void Obj_SpawnBattleUFOLegs(mobj_t *ufo);
|
||||||
void Obj_BattleUFODeath(mobj_t *ufo);
|
void Obj_BattleUFODeath(mobj_t *ufo);
|
||||||
|
void Obj_LinkBattleUFOSpawner(mobj_t *spawner);
|
||||||
|
void Obj_UnlinkBattleUFOSpawner(mobj_t *spawner);
|
||||||
|
void Obj_SpawnBattleUFOFromSpawner(void);
|
||||||
|
INT32 Obj_GetFirstBattleUFOSpawnerID(void);
|
||||||
|
void Obj_ResetUFOSpawners(void);
|
||||||
|
|
||||||
/* Power-Up Aura */
|
/* Power-Up Aura */
|
||||||
void Obj_SpawnPowerUpAura(player_t* player);
|
void Obj_SpawnPowerUpAura(player_t* player);
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,8 @@ typedef enum
|
||||||
|
|
||||||
PR_MOVINGTARGET, // Randomised moving targets
|
PR_MOVINGTARGET, // Randomised moving targets
|
||||||
|
|
||||||
|
PR_BATTLEUFO, // Battle UFO spawning
|
||||||
|
|
||||||
PR_BOTS, // Bot spawning
|
PR_BOTS, // Bot spawning
|
||||||
|
|
||||||
PRNUMCLASS
|
PRNUMCLASS
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,6 @@ target_sources(SRB2SDL2 PRIVATE
|
||||||
gachabom-rebound.cpp
|
gachabom-rebound.cpp
|
||||||
servant-hand.c
|
servant-hand.c
|
||||||
super-flicky.cpp
|
super-flicky.cpp
|
||||||
battle-ufo.c
|
battle-ufo.cpp
|
||||||
powerup-aura.cpp
|
powerup-aura.cpp
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "../doomdef.h"
|
#include "../doomdef.h"
|
||||||
|
#include "../m_random.h"
|
||||||
#include "../p_local.h"
|
#include "../p_local.h"
|
||||||
|
#include "../k_battle.h"
|
||||||
#include "../k_objects.h"
|
#include "../k_objects.h"
|
||||||
|
|
||||||
#define BATTLEUFO_LEG_ZOFFS (3*FRACUNIT) // Spawn height offset from the body
|
#define BATTLEUFO_LEG_ZOFFS (3*FRACUNIT) // Spawn height offset from the body
|
||||||
|
|
@ -7,6 +13,102 @@
|
||||||
#define BATTLEUFO_BOB_AMP (4) // UFO bob strength
|
#define BATTLEUFO_BOB_AMP (4) // UFO bob strength
|
||||||
#define BATTLEUFO_BOB_SPEED (TICRATE*2) // UFO bob speed
|
#define BATTLEUFO_BOB_SPEED (TICRATE*2) // UFO bob speed
|
||||||
|
|
||||||
|
#define spawner_id(o) ((o)->args[0])
|
||||||
|
|
||||||
|
#define ufo_spawner(o) ((o)->target)
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Spawner : mobj_t
|
||||||
|
{
|
||||||
|
INT32 id() const { return spawner_id(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UFO : mobj_t
|
||||||
|
{
|
||||||
|
Spawner* spawner() const { return static_cast<Spawner*>(ufo_spawner(this)); }
|
||||||
|
void spawner(Spawner* n) { P_SetTarget(&ufo_spawner(this), n); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpawnerCompare
|
||||||
|
{
|
||||||
|
bool operator()(const Spawner* a, const Spawner* b) const
|
||||||
|
{
|
||||||
|
return a->id() < b->id();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpawnerList
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::set<Spawner*, SpawnerCompare> set_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void insert(Spawner* spawner)
|
||||||
|
{
|
||||||
|
auto [it, inserted] = set_.insert(spawner);
|
||||||
|
|
||||||
|
if (inserted)
|
||||||
|
{
|
||||||
|
mobj_t* dummy = nullptr;
|
||||||
|
P_SetTarget(&dummy, spawner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void erase(Spawner* spawner)
|
||||||
|
{
|
||||||
|
if (set_.erase(spawner))
|
||||||
|
{
|
||||||
|
mobj_t* dummy = spawner;
|
||||||
|
P_SetTarget(&dummy, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spawner* next(INT32 order) const
|
||||||
|
{
|
||||||
|
auto it = std::upper_bound(
|
||||||
|
set_.begin(),
|
||||||
|
set_.end(),
|
||||||
|
order,
|
||||||
|
[](INT32 a, const Spawner* b) { return a < b->id(); }
|
||||||
|
);
|
||||||
|
|
||||||
|
return it != set_.end() ? *it : *set_.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32 random_id() const
|
||||||
|
{
|
||||||
|
if (set_.empty())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = set_.begin();
|
||||||
|
|
||||||
|
std::advance(it, P_RandomKey(PR_BATTLEUFO, set_.size()));
|
||||||
|
|
||||||
|
return (*std::prev(it == set_.begin() ? set_.end() : it))->id();
|
||||||
|
}
|
||||||
|
|
||||||
|
void spawn_ufo() const
|
||||||
|
{
|
||||||
|
if (set_.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Spawner* spawner = next(g_battleufo.previousId);
|
||||||
|
UFO* ufo = static_cast<UFO*>(P_SpawnMobjFromMobj(spawner, 0, 0, 200*FRACUNIT, MT_BATTLEUFO));
|
||||||
|
|
||||||
|
ufo->spawner(spawner);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SpawnerList g_spawners;
|
||||||
|
|
||||||
|
}; // namespace
|
||||||
|
|
||||||
void Obj_BattleUFOThink(mobj_t *ufo)
|
void Obj_BattleUFOThink(mobj_t *ufo)
|
||||||
{
|
{
|
||||||
// Copied and slightly modified from k_kart.c
|
// Copied and slightly modified from k_kart.c
|
||||||
|
|
@ -15,10 +117,18 @@ void Obj_BattleUFOThink(mobj_t *ufo)
|
||||||
ufo->momz = targz;
|
ufo->momz = targz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Obj_BattleUFODeath(mobj_t *ufo)
|
void Obj_BattleUFODeath(mobj_t *mobj)
|
||||||
{
|
{
|
||||||
|
UFO* ufo = static_cast<UFO*>(mobj);
|
||||||
|
|
||||||
ufo->momz = -(8*mapobjectscale)/2;
|
ufo->momz = -(8*mapobjectscale)/2;
|
||||||
ufo->fuse = TICRATE;
|
ufo->fuse = TICRATE;
|
||||||
|
|
||||||
|
if (ufo->spawner())
|
||||||
|
{
|
||||||
|
g_battleufo.previousId = ufo->spawner()->id();
|
||||||
|
g_battleufo.due = leveltime + BATTLE_UFO_TIME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Obj_SpawnBattleUFOLegs(mobj_t *ufo)
|
void Obj_SpawnBattleUFOLegs(mobj_t *ufo)
|
||||||
|
|
@ -66,3 +176,28 @@ void Obj_BattleUFOLegThink(mobj_t *leg)
|
||||||
leg->eflags |= (leg->target->eflags & MFE_DAMAGEHITLAG);
|
leg->eflags |= (leg->target->eflags & MFE_DAMAGEHITLAG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Obj_LinkBattleUFOSpawner(mobj_t *spawner)
|
||||||
|
{
|
||||||
|
g_spawners.insert(static_cast<Spawner*>(spawner));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Obj_UnlinkBattleUFOSpawner(mobj_t *spawner)
|
||||||
|
{
|
||||||
|
g_spawners.erase(static_cast<Spawner*>(spawner));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Obj_SpawnBattleUFOFromSpawner(void)
|
||||||
|
{
|
||||||
|
g_spawners.spawn_ufo();
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32 Obj_GetFirstBattleUFOSpawnerID(void)
|
||||||
|
{
|
||||||
|
return g_spawners.random_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Obj_ResetUFOSpawners(void)
|
||||||
|
{
|
||||||
|
g_spawners = {};
|
||||||
|
}
|
||||||
|
|
|
||||||
10
src/p_mobj.c
10
src/p_mobj.c
|
|
@ -11175,6 +11175,11 @@ void P_RemoveMobj(mobj_t *mobj)
|
||||||
Obj_RingShooterDelete(mobj);
|
Obj_RingShooterDelete(mobj);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MT_BATTLEUFO_SPAWNER:
|
||||||
|
{
|
||||||
|
Obj_UnlinkBattleUFOSpawner(mobj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
@ -13442,6 +13447,11 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj)
|
||||||
Obj_InitLoopCenter(mobj);
|
Obj_InitLoopCenter(mobj);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MT_BATTLEUFO_SPAWNER:
|
||||||
|
{
|
||||||
|
Obj_LinkBattleUFOSpawner(mobj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
#include "k_director.h"
|
#include "k_director.h"
|
||||||
#include "k_specialstage.h"
|
#include "k_specialstage.h"
|
||||||
#include "acs/interface.h"
|
#include "acs/interface.h"
|
||||||
|
#include "k_objects.h"
|
||||||
|
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
#include "deh_tables.h" // MOBJTYPE_LIST
|
#include "deh_tables.h" // MOBJTYPE_LIST
|
||||||
|
|
@ -230,6 +231,8 @@ void P_InitThinkers(void)
|
||||||
{
|
{
|
||||||
skyboxcenterpnts[i] = skyboxviewpnts[i] = NULL;
|
skyboxcenterpnts[i] = skyboxviewpnts[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Obj_ResetUFOSpawners();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a new thinker at the end of the list.
|
// Adds a new thinker at the end of the list.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue