From f9c4f66931808a96b05d203eaf0905d51837f484 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 28 Sep 2022 01:47:56 -0400 Subject: [PATCH] Add duel bomb objects Basically a landmine, but strafes back and forth. Currently uses SPB sprites, IDK if we'll end up replacing it later. --- extras/conf/D3R-Config.cfg | 51 ++++++++------------ src/deh_tables.c | 2 + src/info.c | 27 +++++++++++ src/info.h | 2 + src/k_botsearch.c | 1 + src/k_kart.c | 1 + src/k_objects.h | 6 +++ src/objects/Sourcefile | 1 + src/objects/duel-bomb.c | 98 ++++++++++++++++++++++++++++++++++++++ src/p_inter.c | 5 ++ src/p_mobj.c | 32 ++++++++++--- 11 files changed, 188 insertions(+), 38 deletions(-) create mode 100644 src/objects/duel-bomb.c diff --git a/extras/conf/D3R-Config.cfg b/extras/conf/D3R-Config.cfg index 7db8d8d99..862fb0cf3 100644 --- a/extras/conf/D3R-Config.cfg +++ b/extras/conf/D3R-Config.cfg @@ -5167,51 +5167,64 @@ thingtypes { color = 4; // Red arrow = 1; - title = "Duel-Only"; + title = "Duel Objects"; sprite = "SPBMA2A8"; - width = 16; - height = 32; + width = 24; + height = 48; flags1text = "[1] Spawn in all modes"; 2050 { title = "Duel Bomb"; + flags8text = "[8] Flip strafe"; } 2051 { title = "Banana"; sprite = "BANAA2A8"; + width = 16; + height = 32; } 2052 { title = "Eggman Item"; sprite = "FITMA0"; + width = 24; + height = 32; } 2053 { title = "Proximity Mine"; sprite = "SSMNA0"; + width = 16; + height = 24; } 2054 { title = "Land Mine"; - sprite = "LNDMA0"; + sprite = "LNDMALAR"; + width = 24; + height = 32; } 2055 { title = "Hyudoro"; sprite = "HYUUA2A8"; + width = 32; + height = 24; } 2056 { title = "Drop Target"; - sprite = "DTRGA0"; + sprite = "DTRGALAR"; + width = 45; + height = 32; } } } @@ -5236,24 +5249,6 @@ thingsfilters } filter2 - { - name = "Enemies"; - category = "enemies"; - type = -1; - - } - - - filter3 - { - name = "NiGHTS Track"; - category = "nightstrk"; - type = -1; - - } - - - filter4 { name = "Normal Gravity"; category = ""; @@ -5266,8 +5261,7 @@ thingsfilters } - - filter5 + filter3 { name = "Reverse Gravity"; category = ""; @@ -5279,11 +5273,4 @@ thingsfilters } } - - filter6 - { - name = "Boss Waypoints"; - category = ""; - type = 292; - } } diff --git a/src/deh_tables.c b/src/deh_tables.c index a0084ec85..a0d4e55bd 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5362,6 +5362,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_SINK_SHIELD", "MT_SINKTRAIL", + "MT_DUELBOMB", // Duel mode bombs + "MT_BATTLEBUMPER", // Battle Mode bumper "MT_BATTLEBUMPER_DEBRIS", "MT_BATTLEBUMPER_BLAST", diff --git a/src/info.c b/src/info.c index dd93bf376..b05a20abc 100644 --- a/src/info.c +++ b/src/info.c @@ -24362,6 +24362,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_DUELBOMB + 2050, // doomednum + S_SPB1, // 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 + 64*FRACUNIT, // speed + 24*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_DONTENCOREMAP|MF_APPLYTERRAIN, // flags + S_NULL // raisestate + }, + { // MT_BATTLEBUMPER -1, // doomednum S_BATTLEBUMPER1,// spawnstate diff --git a/src/info.h b/src/info.h index 29e2695bf..e40ea51ee 100644 --- a/src/info.h +++ b/src/info.h @@ -6408,6 +6408,8 @@ typedef enum mobj_type MT_SINK_SHIELD, MT_SINKTRAIL, + MT_DUELBOMB, // Duel mode bombs + MT_BATTLEBUMPER, // Battle Mode bumpers MT_BATTLEBUMPER_DEBRIS, MT_BATTLEBUMPER_BLAST, diff --git a/src/k_botsearch.c b/src/k_botsearch.c index 5b6f1ccca..48c5745fd 100644 --- a/src/k_botsearch.c +++ b/src/k_botsearch.c @@ -422,6 +422,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing) case MT_BALLHOG: case MT_SPB: case MT_BUBBLESHIELDTRAP: + case MT_DUELBOMB: K_AddDodgeObject(thing, side, 20); break; case MT_SHRINK_GUN: diff --git a/src/k_kart.c b/src/k_kart.c index 0b391d94d..44f7501fb 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1419,6 +1419,7 @@ fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) break; case MT_ORBINAUT: case MT_ORBINAUT_SHIELD: + case MT_DUELBOMB: if (against->player) weight = K_PlayerWeight(against, NULL); break; diff --git a/src/k_objects.h b/src/k_objects.h index 7351465d6..be287c0f4 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -40,4 +40,10 @@ void Obj_OrbinautJawzMoveHeld(player_t *player); void Obj_JawzThink(mobj_t *th); void Obj_JawzThrown(mobj_t *th, fixed_t finalSpeed, SINT8 dir); +/* Duel Bomb */ +void Obj_DuelBombThink(mobj_t *bomb); +void Obj_DuelBombReverse(mobj_t *bomb); +void Obj_DuelBombTouch(mobj_t *bomb, mobj_t *toucher); +void Obj_DuelBombInit(mobj_t *bomb); + #endif/*k_objects_H*/ diff --git a/src/objects/Sourcefile b/src/objects/Sourcefile index 339175b0c..d768232c5 100644 --- a/src/objects/Sourcefile +++ b/src/objects/Sourcefile @@ -5,3 +5,4 @@ spb.c manta-ring.c orbinaut.c jawz.c +duel-bomb.c diff --git a/src/objects/duel-bomb.c b/src/objects/duel-bomb.c new file mode 100644 index 000000000..ace75f3b2 --- /dev/null +++ b/src/objects/duel-bomb.c @@ -0,0 +1,98 @@ +// 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 duel-bomb.c +/// \brief Duel mode bombs. + +#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 bomb_dir(o) ((o)->movedir) + +static fixed_t GetBombSpeed(mobj_t *bomb) +{ + return FixedMul(bomb->info->speed, bomb->scale); +} + +static void UpdateBombMovement(mobj_t *bomb) +{ + const fixed_t spd = GetBombSpeed(bomb); + bomb->momx = FixedMul(spd, FINECOSINE(bomb_dir(bomb) >> ANGLETOFINESHIFT)); + bomb->momy = FixedMul(spd, FINESINE(bomb_dir(bomb) >> ANGLETOFINESHIFT)); +} + +void Obj_DuelBombThink(mobj_t *bomb) +{ + boolean grounded = P_IsObjectOnGround(bomb); + + if (grounded == true) + { + UpdateBombMovement(bomb); + } +} + +void Obj_DuelBombReverse(mobj_t *bomb) +{ + bomb_dir(bomb) += ANGLE_180; + UpdateBombMovement(bomb); +} + +void Obj_DuelBombTouch(mobj_t *bomb, mobj_t *toucher) +{ + player_t *player = toucher->player; + mobj_t *boom = NULL; + + if (bomb->health <= 0 || toucher->health <= 0) + { + return; + } + + if (player->flashing > 0 || player->hyudorotimer > 0 || P_PlayerInPain(player)) + { + // No interaction + return; + } + + // Create explosion + boom = P_SpawnMobjFromMobj(bomb, 0, 0, 0, MT_BOOMEXPLODE); + boom->momz = 5 * boom->scale; + boom->color = SKINCOLOR_KETCHUP; + S_StartSound(boom, bomb->info->attacksound); + + // Kill bomb + P_KillMobj(bomb, toucher, toucher, DMG_NORMAL); + + if (player->invincibilitytimer > 0 + || K_IsBigger(toucher, bomb) == true + || player->flamedash > 0) + { + // Kill without damaging. + return; + } + + P_DamageMobj(toucher, bomb, bomb, 1, DMG_TUMBLE); +} + +void Obj_DuelBombInit(mobj_t *bomb) +{ + bomb_dir(bomb) = bomb->angle + ANGLE_90; + UpdateBombMovement(bomb); +} diff --git a/src/p_inter.c b/src/p_inter.c index 19f03c664..bbfa804be 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -356,6 +356,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) Obj_SPBTouch(special, toucher); return; } + case MT_DUELBOMB: + { + Obj_DuelBombTouch(special, toucher); + return; + } case MT_EMERALD: if (!P_CanPickupItem(player, 0)) return; diff --git a/src/p_mobj.c b/src/p_mobj.c index ad280040c..5b9ea4c75 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1720,7 +1720,8 @@ void P_XYMovement(mobj_t *mo) //{ SRB2kart - Orbinaut, Ballhog // Bump sparks - if (mo->type == MT_ORBINAUT || mo->type == MT_BALLHOG) + if (mo->type == MT_ORBINAUT || mo->type == MT_BALLHOG + || mo->type == MT_DUELBOMB) { mobj_t *fx; fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP); @@ -1754,13 +1755,17 @@ void P_XYMovement(mobj_t *mo) } break; + case MT_BUBBLESHIELDTRAP: + S_StartSound(mo, sfx_s3k44); // Bubble bounce + break; + + case MT_DUELBOMB: + Obj_DuelBombReverse(mo); + break; + default: break; } - - // Bubble bounce - if (mo->type == MT_BUBBLESHIELDTRAP) - S_StartSound(mo, sfx_s3k44); } } } @@ -2190,6 +2195,7 @@ boolean P_ZMovement(mobj_t *mo) case MT_LANDMINE: case MT_DROPTARGET: case MT_BUBBLESHIELDTRAP: + case MT_DUELBOMB: // Remove stuff from death pits. if (P_CheckDeathPitCollide(mo)) { @@ -6906,6 +6912,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_SPBEXPLOSION: mobj->health--; break; + case MT_DUELBOMB: + { + Obj_DuelBombThink(mobj); + break; + } case MT_EMERALD: { if (battleovertime.enabled >= 10*TICRATE) @@ -9708,6 +9719,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_SINK: case MT_ROCKETSNEAKER: case MT_SPB: + case MT_DUELBOMB: thing->shadowscale = 3*FRACUNIT/2; break; case MT_BANANA_SHIELD: @@ -10317,6 +10329,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) // Remove before release CONS_Alert(CONS_WARNING, "Boss waypoints are deprecated. Did you forget to remove the old checkpoints, too?\n"); break; + case MT_DUELBOMB: + Obj_DuelBombInit(mobj); + break; default: break; } @@ -11553,7 +11568,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) return false; } break; - //case MT_DUELBOMB: + case MT_DUELBOMB: case MT_BANANA: case MT_EGGMANITEM: case MT_SSMINE: @@ -12787,6 +12802,11 @@ static void P_SetAmbush(mobj_t *mobj) mobj->type != MT_NIGHTSBUMPER && mobj->type != MT_STARPOST) mobj->flags2 |= MF2_AMBUSH; + + if (mobj->type == MT_DUELBOMB) + { + Obj_DuelBombReverse(mobj); + } } static void P_SetObjectSpecial(mobj_t *mobj)