From 42cbb93ca240bd5215fc7056a5a16448e903a99f Mon Sep 17 00:00:00 2001 From: Lat Date: Wed, 20 Sep 2023 16:33:07 +0200 Subject: [PATCH] Hardcode Leaf Storm Eggman balls --- src/deh_tables.c | 2 + src/info.c | 58 +++++++++++++++- src/info.h | 4 ++ src/k_objects.h | 4 ++ src/objects/CMakeLists.txt | 1 + src/objects/eggball.c | 134 +++++++++++++++++++++++++++++++++++++ src/p_mobj.c | 8 +++ 7 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 src/objects/eggball.c diff --git a/src/deh_tables.c b/src/deh_tables.c index a49383b8b..d9e735ac8 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5829,6 +5829,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_RIDEROIDNODE", "MT_LSZ_BUNGEE", + "MT_LSZ_EGGBALLSPAWNER", + "MT_LSZ_EGGBALL", }; const char *const MOBJFLAG_LIST[] = { diff --git a/src/info.c b/src/info.c index 39f3695a8..de181d9ed 100644 --- a/src/info.c +++ b/src/info.c @@ -898,6 +898,9 @@ char sprnames[NUMSPRITES + 1][5] = "RDRC", "RDRL", + // leaf storm egg ball. + "LSZB", + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later "VIEW", }; @@ -5423,7 +5426,6 @@ state_t states[NUMSTATES] = {SPR_RDRD, 0, -1, {NULL}, 0, 0, S_RIDEROID}, // S_RIDEROID {SPR_RDRC, FF_ANIMATE|FF_FULLBRIGHT|FF_TRANS30, -1, {NULL}, 3, 2, S_RIDEROID_ICON}, // S_RIDEROID_ICON - }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = @@ -30469,6 +30471,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOGRAVITY|MF_SPECIAL, // flags S_NULL // raisestate }, + + { // MT_LSZ_EGGBALLSPAWNER + 3443, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // 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 + 0, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_LSZ_EGGBALL + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // 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 + 0, // speed + 32*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + DMG_TUMBLE, // mass + 0, // damage + sfx_None, // activesound + MF_PAIN, // flags + S_NULL // raisestate + }, }; diff --git a/src/info.h b/src/info.h index f8f003468..8a2447854 100644 --- a/src/info.h +++ b/src/info.h @@ -1451,6 +1451,8 @@ typedef enum sprite SPR_RDRC, SPR_RDRL, + SPR_LSZB, // eggman ball. + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later SPR_VIEW, @@ -7027,6 +7029,8 @@ typedef enum mobj_type MT_RIDEROIDNODE, MT_LSZ_BUNGEE, + MT_LSZ_EGGBALLSPAWNER, + MT_LSZ_EGGBALL, MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, diff --git a/src/k_objects.h b/src/k_objects.h index 6166dc279..d67299f84 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -235,6 +235,10 @@ void Obj_getPlayerOffRideroid(mobj_t *mo); // used in p_map.c to get off of em w void Obj_BungeeSpecial(mobj_t *mo, player_t *p); // used when the player touches the bungee, to be used in p_inter.c void Obj_playerBungeeThink(player_t *p); // player interaction with the bungee. The bungee is to be stored in p->mo->tracer. +/* LSZ Balls */ +void Obj_EggBallSpawnerThink(mobj_t *mo); +void Obj_EggBallThink(mobj_t *mo); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index ee7c9df2c..1d2156b87 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -31,4 +31,5 @@ target_sources(SRB2SDL2 PRIVATE checkpoint.cpp rideroid.c bungee.c + eggball.c ) diff --git a/src/objects/eggball.c b/src/objects/eggball.c new file mode 100644 index 000000000..0d9f684f5 --- /dev/null +++ b/src/objects/eggball.c @@ -0,0 +1,134 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour +// Copyright (C) 2022 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file eggball.c +/// \brief Leaf Storm giant Eggman Balls. And their spawner. Yes, that sounds horribly wrong. No, I'm not changing it. + +#include "../doomdef.h" +#include "../doomstat.h" +#include "../info.h" +#include "../k_kart.h" +#include "../k_objects.h" +#include "../m_random.h" +#include "../p_local.h" +#include "../r_main.h" +#include "../s_sound.h" +#include "../g_game.h" +#include "../z_zone.h" +#include "../k_waypoint.h" +#include "../k_respawn.h" +#include "../k_collide.h" + +#define BALLMINSPAWNTIME 3 +#define BALLMAXSPAWNTIME 5 + +// spawns balls every BALLMINSPAWNTIME to BALLMAXSPAWNTIME seconds. +void Obj_EggBallSpawnerThink(mobj_t *mo) +{ + + if (!mo->extravalue1) + { + mobj_t *ball = P_SpawnMobj(mo->x, mo->y, mo->z, MT_LSZ_EGGBALL); + ball->angle = mo->angle; + P_SetScale(ball, 6*mapobjectscale); + + mo->extravalue1 = P_RandomRange(PR_FUZZ, TICRATE*BALLMINSPAWNTIME, TICRATE*BALLMAXSPAWNTIME); + } + mo->extravalue1--; +} + +// ball thinker, it's mostly for particles and some bouncing n stuff to make em fancy. +// vars: +// threshold -> prevmomz +// movedir -> prevz + +void Obj_EggBallThink(mobj_t *mo) +{ + + P_SetScale(mo, 6*mapobjectscale); + + if (mo->eflags & MFE_JUSTHITFLOOR + && mo->threshold) + { + if (mo->threshold < -10*mapobjectscale) + { + UINT8 i; + + mo->momz = (fixed_t)(-mo->threshold)/8; + + for (i=0; i<16; i++) + { + angle_t an = ANG1; + mobj_t *dust = P_SpawnMobj(mo->x, mo->y, mo->z, MT_DRIFTDUST); + P_SetScale(dust, mapobjectscale*3); + P_InstaThrust(dust, (360/16)*an*i, mapobjectscale*24); // the angle thing is to avoid a warning due to overflows. + dust->momz = P_RandomRange(PR_FUZZ, 0, 7)*mapobjectscale; + } + + S_StartSound(mo, sfx_s3k59); + + P_StartQuakeFromMobj(FRACUNIT*20, 6, 512 * mapobjectscale, mo); + + } + } + + if (!mo->extravalue1) + { + if (P_IsObjectOnGround(mo)) + { + mo->extravalue1 = 1; + mo->cusval = 24*mapobjectscale; + mo->movedir = mo->z; + mo->sprite = SPR_LSZB; + } + } + else + { + if (P_IsObjectOnGround(mo) && mo->extravalue2 &1) + { + fixed_t dx = mo->x + P_RandomRange(PR_FUZZ, -96, 96)*mapobjectscale - mo->momx*2; + fixed_t dy = mo->y + P_RandomRange(PR_FUZZ, -96, 96)*mapobjectscale - mo->momy*2; + fixed_t dz = mo->z; + + mobj_t *dust = P_SpawnMobj(dx, dy, dz, MT_DRIFTDUST); + P_SetScale(dust, mapobjectscale*3); + dust->momz = P_RandomRange(PR_FUZZ, 0, 7)*mapobjectscale; + dust->destscale = mapobjectscale*8; + } + + P_InstaThrust(mo, mo->angle, mo->cusval); + mo->extravalue2 += 1; + mo->frame = mo->extravalue2 % (24 * 2) / 2; // 24 is for frame Y. + + // build up speed + if (P_IsObjectOnGround(mo)) + { + if (mo->eflags & MFE_VERTICALFLIP) + { + if (mo->z > (fixed_t)mo->movedir) + { + mo->cusval += max(mapobjectscale/32, abs(mo->z - (fixed_t)mo->movedir)/16); + } + } + else + { + if (mo->z < (fixed_t)mo->movedir) + { + mo->cusval += max(mapobjectscale/32, abs(mo->z - (fixed_t)mo->movedir)/16); + } + } + } + + mo->movedir = mo->z; + } + mo->threshold = mo->momz; + + if (P_CheckDeathPitCollide(mo)) + P_RemoveMobj(mo); +} \ No newline at end of file diff --git a/src/p_mobj.c b/src/p_mobj.c index a17e1eef7..60828fafe 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9646,7 +9646,15 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_RIDEROIDNODE: Obj_RideroidNodeThink(mobj); break; + + case MT_LSZ_EGGBALLSPAWNER: + Obj_EggBallSpawnerThink(mobj); + break; + case MT_LSZ_EGGBALL: + Obj_EggBallThink(mobj); + break; + default: // check mobj against possible water content, before movement code P_MobjCheckWater(mobj);