From 81e880464a7b7ed9d04d87485210a4e5c97671f2 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 18 Mar 2023 00:22:44 +0000 Subject: [PATCH] CD Special Stage UFO changes - MT_CDUFO is now a valid type of Prison in Prison Break - Tracked on counter - Tracked on HUD - Tracked on minimap - P_AddBrokenPrison in p_inter.c - Generalises behaviour on breaking a Prison Break object - MT_CDUFO polish - Can now be broken with all damaging objects EXCEPT Shield Orbinaut/Shield Jawz - These two are exceptions to prevent them from denying you your on-contact item grab., which these will still give you if you touch them - Breaking the object by touching it now causes hitlag instead of fireworks - The fireworks were to make touching it feel good... but hitlag feels better :P - Now supports mapobjectscale directly. - Scaled 1.5x mapobjectscale - Hitbox now far closer to actual sprite (which was just replaced, but was inexplicably far away from the old one too) --- src/info.c | 6 +-- src/k_battle.c | 2 + src/k_hud.c | 7 ++- src/k_hud_track.cpp | 6 ++- src/k_kart.c | 3 +- src/k_rank.c | 6 ++- src/p_inter.c | 127 +++++++++++++++++++++++++------------------- src/p_mobj.c | 6 ++- 8 files changed, 100 insertions(+), 63 deletions(-) diff --git a/src/info.c b/src/info.c index b462a8ba9..355816512 100644 --- a/src/info.c +++ b/src/info.c @@ -26250,13 +26250,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_cdfm19, // deathsound 0, // speed - 70*FRACUNIT, // radius - 70*FRACUNIT, // height + 55*FRACUNIT, // radius + 95*FRACUNIT, // height 0, // display offset 0, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SPECIAL, // flags + MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SPECIAL|MF_SHOOTABLE, // flags S_NULL // raisestate }, diff --git a/src/k_battle.c b/src/k_battle.c index c2fa396e1..77a292cce 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -778,6 +778,8 @@ void K_BattleInit(boolean singleplayercontext) { if (mt->type == mobjinfo[MT_BATTLECAPSULE].doomednum) P_SpawnMapThing(mt); + else if (mt->type == mobjinfo[MT_CDUFO].doomednum) + maptargets++; } battlecapsules = true; diff --git a/src/k_hud.c b/src/k_hud.c index e5b0050b0..c963e06e8 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -76,7 +76,7 @@ patch_t *kp_facehighlight[8]; static patch_t *kp_nocontestminimap; static patch_t *kp_spbminimap; -static patch_t *kp_capsuleminimap[2]; +static patch_t *kp_capsuleminimap[3]; static patch_t *kp_ringsticker[2]; static patch_t *kp_ringstickersplit[4]; @@ -350,6 +350,7 @@ void K_LoadKartHUDGraphics(void) HU_UpdatePatch(&kp_spbminimap, "SPBMMAP"); HU_UpdatePatch(&kp_capsuleminimap[0], "MINICAP1"); HU_UpdatePatch(&kp_capsuleminimap[1], "MINICAP2"); + HU_UpdatePatch(&kp_capsuleminimap[2], "MINICAP3"); // Rings & Lives HU_UpdatePatch(&kp_ringsticker[0], "RNGBACKA"); @@ -3744,6 +3745,10 @@ static void K_drawKartMinimap(void) case MT_BATTLECAPSULE: workingPic = kp_capsuleminimap[(mobj->extravalue1 != 0 ? 1 : 0)]; break; + case MT_CDUFO: + if (battlecapsules) //!battleprisons + workingPic = kp_capsuleminimap[2]; + break; default: break; } diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index e6a7df1ed..0d39b029d 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -181,7 +181,8 @@ void K_DrawTargetTracking(const TargetTracking& target) borderDir.y = FRACUNIT; } - if (target.mobj->type == MT_BATTLECAPSULE) + if (target.mobj->type == MT_BATTLECAPSULE + || target.mobj->type == MT_CDUFO) { targetPatch = kp_capsuletarget_icon[timer & 1]; } @@ -363,6 +364,9 @@ bool is_object_tracking_target(const mobj_t* mobj) switch (mobj->type) { case MT_BATTLECAPSULE: + case MT_CDUFO: + return battlecapsules; // battleprisons + case MT_SPECIAL_UFO: return true; diff --git a/src/k_kart.c b/src/k_kart.c index 81886b60f..f44d494e4 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5891,7 +5891,8 @@ static void K_DoShrink(player_t *user) next = mobj->itnext; if (mobj->type == MT_SPB - || mobj->type == MT_BATTLECAPSULE) + || mobj->type == MT_BATTLECAPSULE + || mobj->type == MT_CDUFO) { continue; } diff --git a/src/k_rank.c b/src/k_rank.c index 0e07c33ec..7bf277e82 100644 --- a/src/k_rank.c +++ b/src/k_rank.c @@ -123,7 +123,8 @@ static void RankCapsules_LoadTextmap(void) { UINT16 type = atol(val); - if (type == mobjinfo[MT_BATTLECAPSULE].doomednum) + if (type == mobjinfo[MT_BATTLECAPSULE].doomednum + || type == mobjinfo[MT_CDUFO].doomednum) { g_rankCapsules_count++; } @@ -163,7 +164,8 @@ static void RankCapsules_LoadThingsLump(UINT8 *data) data += 2; // options - if (type == mobjinfo[MT_BATTLECAPSULE].doomednum) + if (type == mobjinfo[MT_BATTLECAPSULE].doomednum + || type == mobjinfo[MT_CDUFO].doomednum) { g_rankCapsules_count++; } diff --git a/src/p_inter.c b/src/p_inter.c index 2ef52cbb0..d9d8d96f0 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -200,7 +200,6 @@ boolean P_EmblemWasCollected(INT32 emblemID) void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { player_t *player; - INT32 i; if (objectplacing) return; @@ -444,7 +443,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) K_StartItemRoulette(player); // Karma fireworks - for (i = 0; i < 5; i++) + /*for (i = 0; i < 5; i++) { mobj_t *firework = P_SpawnMobj(special->x, special->y, special->z, MT_KARMAFIREWORK); firework->momx = toucher->momx; @@ -453,14 +452,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_Thrust(firework, FixedAngle((72*i)<scale); P_SetObjectMomZ(firework, P_RandomRange(PR_ITEM_DEBRIS, 1,8)*special->scale, false); firework->color = toucher->color; - } + }*/ - S_StartSound(toucher, sfx_cdfm73); // they don't make this sound in the original game but it's nice to have a "reward" for good play + K_SetHitLagForObjects(special, toucher, 2, true); - //special->momx = special->momy = special->momz = 0; - special->momz = -(3*special->scale)/2; - //P_SetTarget(&special->target, toucher); - special->fuse = 2*TICRATE; break; case MT_BALLOON: // SRB2kart @@ -636,6 +631,61 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) player->starpostnum = post->health; } +static void P_AddBrokenPrison(mobj_t *target, mobj_t *source) +{ + (void)target; + + if (!battlecapsules) // !battleprisons + return; + + if ((gametyperules & GTR_POINTLIMIT) && (source && source->player)) + { + /*mobj_t * ring; + for (i = 0; i < 2; i++) + { + dir += (ANGLE_MAX/3); + ring = P_SpawnMobj(target->x, target->y, target->z, MT_RING); + ring->angle = dir; + P_InstaThrust(ring, dir, 16*ring->scale); + ring->momz = 8 * target->scale * P_MobjFlip(target); + P_SetTarget(&ring->tracer, source); + source->player->pickuprings++; + }*/ + + P_AddPlayerScore(source->player, 1); + K_SpawnBattlePoints(source->player, NULL, 1); + } + + if (++numtargets >= maptargets) + { + UINT8 i; + boolean givelife = false; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + P_DoPlayerExit(&players[i]); + if (!G_GametypeUsesLives()) + continue; + P_GivePlayerLives(&players[i], 1); + givelife = true; + } + + if (givelife) + S_StartSound(NULL, sfx_cdfm73); + } + else + { + S_StartSound(NULL, sfx_s221); + if (timelimitintics) + { + extratimeintics += 10*TICRATE; + secretextratime = TICRATE/2; + } + } +} + /** Checks if the level timer is over the timelimit and the round should end, * unless you are in overtime. In which case leveltime may stretch out beyond * timelimitintics and overtime's status will be checked here each tick. @@ -1521,7 +1571,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget case MT_BATTLECAPSULE: { - UINT8 i; mobj_t *cur; angle_t dir = 0; @@ -1568,54 +1617,19 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget S_StartSound(target, sfx_mbs60); - if ((gametyperules & GTR_POINTLIMIT) && (source && source->player)) - { - /*mobj_t * ring; - for (i = 0; i < 2; i++) - { - dir += (ANGLE_MAX/3); - ring = P_SpawnMobj(target->x, target->y, target->z, MT_RING); - ring->angle = dir; - P_InstaThrust(ring, dir, 16*ring->scale); - ring->momz = 8 * target->scale * P_MobjFlip(target); - P_SetTarget(&ring->tracer, source); - source->player->pickuprings++; - }*/ - - P_AddPlayerScore(source->player, 1); - K_SpawnBattlePoints(source->player, NULL, 1); - } - - // All targets busted! - if (++numtargets >= maptargets) - { - boolean givelife = false; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; - P_DoPlayerExit(&players[i]); - if (!grandprixinfo.gp) - continue; - P_GivePlayerLives(&players[i], 1); - givelife = true; - } - - if (givelife) - S_StartSound(NULL, sfx_cdfm73); - } - else - { - S_StartSound(NULL, sfx_s221); - if (timelimitintics) - { - extratimeintics += 10*TICRATE; - secretextratime = TICRATE/2; - } - } + P_AddBrokenPrison(target, source); } break; + case MT_CDUFO: + S_StartSound(inflictor, sfx_cdfm73); // they don't make this sound in the original game but it's nice to have a "reward" for good play + + target->momz = -(3*mapobjectscale)/2; + target->fuse = 2*TICRATE; + + P_AddBrokenPrison(target, source); + break; + case MT_BATTLEBUMPER: { mobj_t *owner = target->target; @@ -2097,6 +2111,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da damage = Obj_MonitorGetDamage(target, inflictor, damagetype); Obj_MonitorOnDamage(target, inflictor, damage); break; + case MT_CDUFO: + // Make it possible to pick them up during race + if (inflictor->type == MT_ORBINAUT_SHIELD || inflictor->type == MT_JAWZ_SHIELD) + return false; + break; default: break; diff --git a/src/p_mobj.c b/src/p_mobj.c index 4e466e937..86eb0a6b2 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5260,6 +5260,7 @@ static boolean P_IsTrackerType(INT32 type) // Primarily for minimap data, handle with care case MT_SPB: case MT_BATTLECAPSULE: + case MT_CDUFO: case MT_SPECIAL_UFO: return true; @@ -8645,7 +8646,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->movecount--; break; } - else if (P_AproxDistance(mobj->x - (mobj->spawnpoint->x<y - (mobj->spawnpoint->y<x - (mobj->spawnpoint->x<y - (mobj->spawnpoint->y<movecount = 3; @@ -10817,6 +10818,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_BIGRING: P_SetScale(mobj, (mobj->destscale = 3*FRACUNIT)); break; + case MT_CDUFO: + P_SetScale(mobj, (mobj->destscale = 3*FRACUNIT/2)); + break; case MT_RANDOMAUDIENCE: { fixed_t randu = P_RandomFixed(PR_UNDEFINED);