From 7983b94cf368fc0d9f3aefec3e4b9a7cc3129603 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sun, 6 Apr 2025 12:34:50 -0400 Subject: [PATCH 01/12] Porting v1 objects part 1 --- src/doomdef.h | 2 +- src/info/actions.h | 16 +- src/info/mobjs.h | 46 +- src/info/sprites.h | 15 - src/info/states.h | 117 +---- src/p_enemy.c | 1021 +++++--------------------------------------- src/p_inter.c | 41 +- src/p_mobj.c | 25 +- src/p_setup.c | 9 - 9 files changed, 151 insertions(+), 1141 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 00c6b0a12..fd61076ce 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -101,7 +101,7 @@ extern "C" { #endif -//#define NOMD5 +#define NOMD5 // Uncheck this to compile debugging code //#define RANGECHECK diff --git a/src/info/actions.h b/src/info/actions.h index 2ae93080f..d0515684f 100644 --- a/src/info/actions.h +++ b/src/info/actions.h @@ -4,9 +4,6 @@ _(A_Fall, FALL) _(A_Look, LOOK) _(A_Chase, CHASE) _(A_FaceStabChase, FACESTABCHASE) -_(A_FaceStabRev, FACESTABREV) -_(A_FaceStabHurl, FACESTABHURL) -_(A_FaceStabMiss, FACESTABMISS) _(A_StatueBurst, STATUEBURST) _(A_FaceTarget, FACETARGET) _(A_FaceTracer, FACETRACER) @@ -69,10 +66,8 @@ _(A_JetJawRoam, JETJAWROAM) _(A_JetJawChomp, JETJAWCHOMP) _(A_PointyThink, POINTYTHINK) _(A_CheckBuddy, CHECKBUDDY) -_(A_HoodFire, HOODFIRE) _(A_HoodThink, HOODTHINK) -_(A_HoodFall, HOODFALL) -_(A_ArrowBonks, ARROWBONKS) +_(A_ArrowCheck, ARROWCHECK) _(A_SnailerThink, SNAILERTHINK) _(A_SharpChase, SHARPCHASE) _(A_SharpSpin, SHARPSPIN) @@ -83,9 +78,6 @@ _(A_CrushclawAim, CRUSHCLAWAIM) _(A_CrushclawLaunch, CRUSHCLAWLAUNCH) _(A_VultureVtol, VULTUREVTOL) _(A_VultureCheck, VULTURECHECK) -_(A_VultureHover, VULTUREHOVER) -_(A_VultureBlast, VULTUREBLAST) -_(A_VultureFly, VULTUREFLY) _(A_SkimChase, SKIMCHASE) _(A_SkullAttack, SKULLATTACK) _(A_LobShot, LOBSHOT) @@ -224,16 +216,10 @@ _(A_Boss5MakeItRain, BOSS5MAKEITRAIN) _(A_Boss5MakeJunk, BOSS5MAKEJUNK) _(A_LookForBetter, LOOKFORBETTER) _(A_Boss5BombExplode, BOSS5BOMBEXPLODE) -_(A_TNTExplode, TNTEXPLODE) -_(A_DebrisRandom, DEBRISRANDOM) -_(A_TrainCameo, TRAINCAMEO) -_(A_TrainCameo2, TRAINCAMEO2) _(A_CanarivoreGas, CANARIVOREGAS) _(A_KillSegments, KILLSEGMENTS) _(A_SnapperSpawn, SNAPPERSPAWN) _(A_SnapperThinker, SNAPPERTHINKER) -_(A_SaloonDoorSpawn, SALOONDOORSPAWN) -_(A_MinecartSparkThink, MINECARTSPARKTHINK) _(A_ModuloToState, MODULOTOSTATE) _(A_LavafallRocks, LAVAFALLROCKS) _(A_LavafallLava, LAVAFALLLAVA) diff --git a/src/info/mobjs.h b/src/info/mobjs.h index 8d48fbf21..c4204ca8d 100644 --- a/src/info/mobjs.h +++ b/src/info/mobjs.h @@ -34,7 +34,6 @@ _(POINTY) // Pointy _(POINTYBALL) // Pointy Ball _(ROBOHOOD) // Robo-Hood _(FACESTABBER) // Castlebot Facestabber -_(FACESTABBERSPEAR) // Castlebot Facestabber spear aura _(EGGGUARD) // Egg Guard _(EGGSHIELD) // Egg Guard's shield _(GSNAPPER) // Green Snapper @@ -348,7 +347,6 @@ _(CEZPOLE1) // Pole (with red banner) _(CEZPOLE2) // Pole (with blue banner) _(CEZBANNER1) // Banner (red) _(CEZBANNER2) // Banner (blue) -_(PINETREE) // Pine Tree _(CEZBUSH1) // Bush 1 _(CEZBUSH2) // Bush 2 _(CANDLE) // Candle @@ -367,42 +365,10 @@ _(BRAMBLES) // Brambles // Arid Canyon Scenery _(BIGTUMBLEWEED) _(LITTLETUMBLEWEED) -_(CACTI1) // Tiny Red Flower Cactus -_(CACTI2) // Small Red Flower Cactus -_(CACTI3) // Tiny Blue Flower Cactus -_(CACTI4) // Small Blue Flower Cactus -_(CACTI5) // Prickly Pear -_(CACTI6) // Barrel Cactus -_(CACTI7) // Tall Barrel Cactus -_(CACTI8) // Armed Cactus -_(CACTI9) // Ball Cactus -_(CACTI10) // Tiny Cactus -_(CACTI11) // Small Cactus -_(CACTITINYSEG) // Tiny Cactus Segment -_(CACTISMALLSEG) // Small Cactus Segment -_(ARIDSIGN_CAUTION) // Caution Sign -_(ARIDSIGN_CACTI) // Cacti Sign -_(ARIDSIGN_SHARPTURN) // Sharp Turn Sign -_(OILLAMP) -_(TNTBARREL) -_(PROXIMITYTNT) -_(DUSTDEVIL) -_(DUSTLAYER) -_(ARIDDUST) -_(MINECART) -_(MINECARTSEG) -_(MINECARTSPAWNER) -_(MINECARTEND) -_(MINECARTENDSOLID) -_(MINECARTSIDEMARK) -_(MINECARTSPARK) -_(SALOONDOOR) -_(SALOONDOORCENTER) -_(TRAINCAMEOSPAWNER) -_(TRAINSEG) -_(TRAINDUSTSPAWNER) -_(TRAINSTEAMSPAWNER) -_(MINECARTSWITCHPOINT) +_(CACTI1) +_(CACTI2) +_(CACTI3) +_(CACTI4) // Red Volcano Scenery _(FLAMEJET) @@ -991,8 +957,8 @@ _(CDTREEA) _(CDTREEB) // Daytona Speedway -_(DAYTONAPINETREE) -_(DAYTONAPINETREE_SIDE) +_(PINETREE) +_(PINETREE_SIDE) // Egg Zeppelin _(EZZPROPELLER) diff --git a/src/info/sprites.h b/src/info/sprites.h index 4609e4bfa..5c27aa74c 100644 --- a/src/info/sprites.h +++ b/src/info/sprites.h @@ -239,21 +239,6 @@ _(CABR) // Brambles _(BTBL) // Big tumbleweed _(STBL) // Small tumbleweed _(CACT) // Cacti -_(WWSG) // Caution Sign -_(WWS2) // Cacti Sign -_(WWS3) // Sharp Turn Sign -_(OILL) // Oil lamp -_(OILF) // Oil lamp flare -_(BARR) // TNT barrel -_(REMT) // TNT proximity shell -_(TAZD) // Dust devil -_(ADST) // Arid dust -_(MCRT) // Minecart -_(MCSP) // Minecart spark -_(SALD) // Saloon door -_(TRAE) // Train cameo locomotive -_(TRAI) // Train cameo wagon -_(STEA) // Train steam // Red Volcano Scenery _(FLME) // Flame jet diff --git a/src/info/states.h b/src/info/states.h index 5b30c3705..3a97968a7 100644 --- a/src/info/states.h +++ b/src/info/states.h @@ -258,12 +258,11 @@ _(POINTYBALL1) // Robo-Hood _(ROBOHOOD_LOOK) -_(ROBOHOOD_STAND) -_(ROBOHOOD_FIRE1) -_(ROBOHOOD_FIRE2) -_(ROBOHOOD_JUMP1) +_(ROBOHOOD_STND) +_(ROBOHOOD_SHOOT) +_(ROBOHOOD_JUMP) _(ROBOHOOD_JUMP2) -_(ROBOHOOD_JUMP3) +_(ROBOHOOD_FALL) // Castlebot Facestabber _(FACESTABBER_STND1) @@ -276,11 +275,6 @@ _(FACESTABBER_CHARGE1) _(FACESTABBER_CHARGE2) _(FACESTABBER_CHARGE3) _(FACESTABBER_CHARGE4) -_(FACESTABBER_PAIN) -_(FACESTABBER_DIE1) -_(FACESTABBER_DIE2) -_(FACESTABBER_DIE3) -_(FACESTABBERSPEAR) // Egg Guard _(EGGGUARD_STND) @@ -298,7 +292,6 @@ _(EGGGUARD_RUN4) // Egg Shield for Egg Guard _(EGGSHIELD) -_(EGGSHIELDBREAK) // Green Snapper _(SNAPPER_SPAWN) @@ -1373,7 +1366,8 @@ _(CANNONBALL1) // Arrow _(ARROW) -_(ARROWBONK) +_(ARROWUP) +_(ARROWDOWN) // Glaregoyle Demon fire _(DEMONFIRE) @@ -1561,7 +1555,6 @@ _(CEZFLOWER) _(CEZPOLE) _(CEZBANNER1) _(CEZBANNER2) -_(PINETREE) _(CEZBUSH1) _(CEZBUSH2) _(CANDLE) @@ -1605,100 +1598,6 @@ _(CACTI1) _(CACTI2) _(CACTI3) _(CACTI4) -_(CACTI5) -_(CACTI6) -_(CACTI7) -_(CACTI8) -_(CACTI9) -_(CACTI10) -_(CACTI11) -_(CACTITINYSEG) -_(CACTISMALLSEG) - -// Warning signs -_(ARIDSIGN_CAUTION) -_(ARIDSIGN_CACTI) -_(ARIDSIGN_SHARPTURN) - -// Oil lamp -_(OILLAMP) -_(OILLAMPFLARE) - -// TNT barrel -_(TNTBARREL_STND1) -_(TNTBARREL_EXPL1) -_(TNTBARREL_EXPL2) -_(TNTBARREL_EXPL3) -_(TNTBARREL_EXPL4) -_(TNTBARREL_EXPL5) -_(TNTBARREL_EXPL6) -_(TNTBARREL_EXPL7) -_(TNTBARREL_FLYING) - -// TNT proximity shell -_(PROXIMITY_TNT) -_(PROXIMITY_TNT_TRIGGER1) -_(PROXIMITY_TNT_TRIGGER2) -_(PROXIMITY_TNT_TRIGGER3) -_(PROXIMITY_TNT_TRIGGER4) -_(PROXIMITY_TNT_TRIGGER5) -_(PROXIMITY_TNT_TRIGGER6) -_(PROXIMITY_TNT_TRIGGER7) -_(PROXIMITY_TNT_TRIGGER8) -_(PROXIMITY_TNT_TRIGGER9) -_(PROXIMITY_TNT_TRIGGER10) -_(PROXIMITY_TNT_TRIGGER11) -_(PROXIMITY_TNT_TRIGGER12) -_(PROXIMITY_TNT_TRIGGER13) -_(PROXIMITY_TNT_TRIGGER14) -_(PROXIMITY_TNT_TRIGGER15) -_(PROXIMITY_TNT_TRIGGER16) -_(PROXIMITY_TNT_TRIGGER17) -_(PROXIMITY_TNT_TRIGGER18) -_(PROXIMITY_TNT_TRIGGER19) -_(PROXIMITY_TNT_TRIGGER20) -_(PROXIMITY_TNT_TRIGGER21) -_(PROXIMITY_TNT_TRIGGER22) -_(PROXIMITY_TNT_TRIGGER23) - -// Dust devil -_(DUSTDEVIL) -_(DUSTLAYER1) -_(DUSTLAYER2) -_(DUSTLAYER3) -_(DUSTLAYER4) -_(DUSTLAYER5) -_(ARIDDUST1) -_(ARIDDUST2) -_(ARIDDUST3) - -// Minecart -_(MINECART_IDLE) -_(MINECART_DTH1) -_(MINECARTEND) -_(MINECARTSEG_FRONT) -_(MINECARTSEG_BACK) -_(MINECARTSEG_LEFT) -_(MINECARTSEG_RIGHT) -_(MINECARTSIDEMARK1) -_(MINECARTSIDEMARK2) -_(MINECARTSPARK) - -// Saloon door -_(SALOONDOOR) -_(SALOONDOORCENTER) - -// Train cameo -_(TRAINCAMEOSPAWNER_1) -_(TRAINCAMEOSPAWNER_2) -_(TRAINCAMEOSPAWNER_3) -_(TRAINCAMEOSPAWNER_4) -_(TRAINCAMEOSPAWNER_5) -_(TRAINPUFFMAKER) - -// Train -_(TRAINDUST) -_(TRAINSTEAM) // Flame jet _(FLAMEJETSTND) @@ -4056,8 +3955,8 @@ _(CDTREEASP) _(CDTREEBSP) // Daytona Speedway -_(DAYTONAPINETREE) -_(DAYTONAPINETREE_SIDE) +_(PINETREE) +_(PINETREE_SIDE) // Egg Zeppelin _(EZZPROPELLER) diff --git a/src/p_enemy.c b/src/p_enemy.c index e79b11c4e..b701300e7 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -741,191 +741,6 @@ static void P_SharpDust(mobj_t *actor, mobjtype_t type, angle_t ang) P_SetObjectMomZ(dust, P_RandomRange(1, 4)<angle, actor->radius), - -P_ReturnThrustY(actor, actor->angle, actor->radius), - actor->height/3, - MT_PARTICLE); - flume->destscale = actor->scale*3; - P_SetScale(flume, flume->destscale); - P_SetTarget(&flume->target, actor); - flume->sprite = SPR_JETF; - flume->frame = FF_FULLBRIGHT; - flume->tics = 2; -} - -// Function: A_FaceStabRev -// -// Description: Facestabber rev action -// -// var1 = effective duration -// var2 = effective nextstate -// -void A_FaceStabRev(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - - if (LUA_CallAction(A_FACESTABREV, actor)) - return; - - if (!actor->target) - { - P_SetMobjState(actor, actor->info->spawnstate); - return; - } - - actor->extravalue1 = 0; - - if (!actor->reactiontime) - { - actor->reactiontime = locvar1; - S_StartSound(actor, actor->info->activesound); - } - else - { - if ((--actor->reactiontime) == 0) - { - S_StartSound(actor, actor->info->attacksound); - P_SetMobjState(actor, locvar2); - } - else - { - P_TryMove(actor, actor->x - P_ReturnThrustX(actor, actor->angle, 2<y - P_ReturnThrustY(actor, actor->angle, 2<target) - { - angle_t visang = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); - // Calculate new direction. - angle_t dirang = actor->angle; - angle_t diffang = visang - dirang; - - if (locvar1) // Allow homing? - { - if (diffang > ANGLE_180) - { - angle_t workang = locvar1*(InvAngle(diffang)>>5); - diffang += InvAngle(workang); - } - else - diffang += (locvar1*(diffang>>5)); - } - diffang += ANGLE_45; - - // Check the sight cone. - if (diffang < ANGLE_90) - { - actor->angle = dirang; - if (++actor->extravalue2 < 4) - actor->extravalue2 = 4; - else if (actor->extravalue2 > 26) - actor->extravalue2 = 26; - - if (P_TryMove(actor, - actor->x + P_ReturnThrustX(actor, dirang, actor->extravalue2<y + P_ReturnThrustY(actor, dirang, actor->extravalue2<extravalue1); - fixed_t basesize = FRACUNIT/MAXVAL; - mobj_t *hwork = actor; - INT32 dist = 113; - fixed_t xo = P_ReturnThrustX(actor, actor->angle, dist*basesize); - fixed_t yo = P_ReturnThrustY(actor, actor->angle, dist*basesize); - - while (step > 0) - { - if (!hwork->hnext) - P_SetTarget(&hwork->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_FACESTABBERSPEAR)); - hwork = hwork->hnext; - hwork->angle = actor->angle + ANGLE_90; - hwork->destscale = FixedSqrt(step*basesize); - P_SetScale(hwork, hwork->destscale); - hwork->fuse = 2; - P_MoveOrigin(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<extravalue1 >= MAXVAL) - actor->extravalue1 -= NUMGRADS; - - if ((step % 5) == 0) - P_SharpDust(actor, MT_SPINDUST, actor->angle); - - P_FaceStabFlume(actor); - return; -#undef MAXVAL -#undef NUMGRADS -#undef NUMSTEPS - } - } - } - - P_SetMobjState(actor, locvar2); - actor->reactiontime = actor->info->reactiontime; -} - -// Function: A_FaceStabMiss -// -// Description: Facestabber miss action -// -// var1 = unused -// var2 = effective nextstate -// -void A_FaceStabMiss(mobj_t *actor) -{ - INT32 locvar2 = var2; - - if (LUA_CallAction(A_FACESTABMISS, actor)) - return; - - if (++actor->extravalue1 >= 3) - { - actor->extravalue2 -= 2; - actor->extravalue1 = 0; - S_StartSound(actor, sfx_s3k47); - P_SharpDust(actor, MT_SPINDUST, actor->angle); - } - - if (actor->extravalue2 <= 0 || !P_TryMove(actor, - actor->x + P_ReturnThrustX(actor, actor->angle, actor->extravalue2<y + P_ReturnThrustY(actor, actor->angle, actor->extravalue2<extravalue2 = 0; - P_SetMobjState(actor, locvar2); - } -} - // Function: A_StatueBurst // // Description: For suspicious statues only... @@ -1173,60 +988,6 @@ void A_CheckBuddy(mobj_t *actor) P_RemoveMobj(actor); } -// Helper function for the Robo Hood. -// Don't ask me how it works. Nev3r made it with dark majyks. -static void P_ParabolicMove(mobj_t *actor, fixed_t x, fixed_t y, fixed_t z, fixed_t speed) -{ - fixed_t dh; - - x -= actor->x; - y -= actor->y; - z -= actor->z; - - dh = P_AproxDistance(x, y); - - actor->momx = FixedMul(FixedDiv(x, dh), speed); - actor->momy = FixedMul(FixedDiv(y, dh), speed); - - if (!gravity) - return; - - dh = FixedDiv(FixedMul(dh, gravity), speed); - actor->momz = (dh>>1) + FixedDiv(z, dh<<1); -} - -// Function: A_HoodFire -// -// Description: Firing Robo-Hood -// -// var1 = object type to fire -// var2 = unused -// -void A_HoodFire(mobj_t *actor) -{ - mobj_t *arrow; - INT32 locvar1 = var1; - - if (LUA_CallAction(A_HOODFIRE, actor)) - return; - - // Check target first. - if (!actor->target) - { - actor->reactiontime = actor->info->reactiontime; - P_SetMobjState(actor, actor->info->spawnstate); - return; - } - - A_FaceTarget(actor); - - if (!(arrow = P_SpawnMissile(actor, actor->target, (mobjtype_t)locvar1))) - return; - - // Set a parabolic trajectory for the arrow. - P_ParabolicMove(arrow, actor->target->x, actor->target->y, actor->target->z, arrow->info->speed); -} - // Function: A_HoodThink // // Description: Thinker for Robo-Hood @@ -1236,108 +997,94 @@ void A_HoodFire(mobj_t *actor) // void A_HoodThink(mobj_t *actor) { - fixed_t dx, dy, dz, dm; - boolean checksight; - if (LUA_CallAction(A_HOODTHINK, actor)) return; - // Check target first. + // Currently in the air... + if (!(actor->eflags & MFE_VERTICALFLIP) && actor->z > actor->floorz) + { + if (actor->momz > 0) + P_SetMobjStateNF(actor, actor->info->xdeathstate); // Rising + else + P_SetMobjStateNF(actor, actor->info->raisestate); // Falling + + return; + } + else if ((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height < actor->ceilingz) + { + if (actor->momz < 0) + P_SetMobjStateNF(actor, actor->info->xdeathstate); // Rising + else + P_SetMobjStateNF(actor, actor->info->raisestate); // Falling + + return; + } + + if (actor->state == &states[actor->info->xdeathstate] + || actor->state == &states[actor->info->raisestate]) + P_SetMobjStateNF(actor, actor->info->seestate); + if (!actor->target) { - actor->reactiontime = actor->info->reactiontime; P_SetMobjState(actor, actor->info->spawnstate); return; } - dx = (actor->target->x - actor->x), dy = (actor->target->y - actor->y), dz = (actor->target->z - actor->z); - dm = P_AproxDistance(dx, dy); - // Target dangerously close to robohood, retreat then. - if ((dm < 256<info->attacksound); - P_SetMobjState(actor, actor->info->raisestate); - return; - } + A_FaceTarget(actor); // Aiming... aiming... - // If target on sight, look at it. - if ((checksight = P_CheckSight(actor, actor->target))) - { - angle_t dang = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); - if (actor->angle >= ANGLE_180) - { - actor->angle = InvAngle(actor->angle)>>1; - actor->angle = InvAngle(actor->angle); - } - else - actor->angle >>= 1; - - if (dang >= ANGLE_180) - { - dang = InvAngle(dang)>>1; - dang = InvAngle(dang); - } - else - dang >>= 1; - - actor->angle += dang; - } - - // Check whether to do anything. - if ((--actor->reactiontime) <= 0) - { - actor->reactiontime = actor->info->reactiontime; - - // If way too far, don't shoot. - if ((dm < (3072<info->missilestate); - return; - } - } -} - -// Function: A_HoodFall -// -// Description: Falling Robo-Hood -// -// var1 = unused -// var2 = unused -// -void A_HoodFall(mobj_t *actor) -{ - if (LUA_CallAction(A_HOODFALL, actor)) + if (--actor->reactiontime > 0) return; - if (!P_IsObjectOnGround(actor)) - return; + // Shoot, if not too close (cheap shots are lame) + if ((P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) > FixedMul(192*FRACUNIT, actor->scale)) + || (actor->spawnpoint && (actor->spawnpoint->options & MTF_AMBUSH))) // If you can't jump, might as well shoot regardless of distance! + P_SetMobjState(actor, actor->info->missilestate); + else if (!(actor->spawnpoint && (actor->spawnpoint->options & MTF_AMBUSH)))// But we WILL jump! + P_SetMobjState(actor, actor->info->painstate); - actor->momx = actor->momy = 0; actor->reactiontime = actor->info->reactiontime; - P_SetMobjState(actor, actor->info->seestate); } -// Function: A_ArrowBonks +// Function: A_ArrowCheck // -// Description: Arrow momentum setting on collision +// Description: Checks arrow direction and adjusts sprite accordingly // // var1 = unused // var2 = unused // -void A_ArrowBonks(mobj_t *actor) +void A_ArrowCheck(mobj_t *actor) { - if (LUA_CallAction(A_ARROWBONKS, actor)) + fixed_t x,y,z; + angle_t angle; + fixed_t dist; + + if (LUA_CallAction(A_ARROWCHECK, actor)) return; - if (((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz) - || (!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz)) - actor->angle += ANGLE_180; + // Movement vector + x = actor->momx; + y = actor->momy; + z = actor->momz; - P_SetObjectMomZ(actor, 8*actor->scale, false); - P_InstaThrust(actor, actor->angle, -6*actor->scale); + // Calculate the angle of movement. + /* + Z + / | + / | + / | + 0------dist(X,Y) + */ - actor->flags = (actor->flags|MF_NOCLIPHEIGHT) & ~MF_NOGRAVITY; - actor->z += P_MobjFlip(actor); + dist = P_AproxDistance(x, y); + + angle = R_PointToAngle2(0, 0, dist, z); + + if (angle > ANG20 && angle <= ANGLE_180) + P_SetMobjStateNF(actor, actor->info->raisestate); + else if (angle < ANG340 && angle > ANGLE_180) + P_SetMobjStateNF(actor, actor->info->xdeathstate); + else + P_SetMobjStateNF(actor, actor->info->spawnstate); } // Function: A_SnailerThink @@ -1839,229 +1586,6 @@ void A_VultureCheck(mobj_t *actor) } } -static void P_VultureHoverParticle(mobj_t *actor) -{ - fixed_t fdist = actor->z - P_FloorzAtPos(actor->x, actor->y, actor->z, actor->height); - - if (fdist < 128*FRACUNIT) - { - mobj_t *dust; - UINT8 i; - angle_t angle = (leveltime % 2)*ANGLE_45/2; - - for (i = 0; i <= 7; i++) - { - angle_t fa = (angle >> ANGLETOFINESHIFT) & FINEMASK; - fixed_t px = actor->x + FixedMul(fdist + 64*FRACUNIT, FINECOSINE(fa)); - fixed_t py = actor->y + FixedMul(fdist + 64*FRACUNIT, FINESINE(fa)); - fixed_t pz = P_FloorzAtPos(px, py, actor->z, actor->height); - - dust = P_SpawnMobj(px, py, pz, MT_ARIDDUST); - P_SetMobjState(dust, (statenum_t)(dust->state - states + P_RandomRange(0, 2))); - P_Thrust(dust, angle, FixedDiv(12*FRACUNIT, max(FRACUNIT, fdist/2))); - dust->momx += actor->momx; - dust->momy += actor->momy; - angle += ANGLE_45; - } - } -} - -// Function: A_VultureHover -// -// Description: Vulture hovering and checking whether to attack. -// -// var1 = unused -// var2 = unused -// -void A_VultureHover(mobj_t *actor) -{ - fixed_t targetz; - fixed_t distdif; - fixed_t memz = actor->z; - SINT8 i; - - if (LUA_CallAction(A_VULTUREHOVER, actor)) - return; - - if (!actor->target || P_MobjWasRemoved(actor->target)) - { - P_SetMobjState(actor, actor->info->spawnstate); - return; - } - - actor->flags |= MF_NOGRAVITY; - - actor->momx -= actor->momx/24; - actor->momy -= actor->momy/24; - - P_VultureHoverParticle(actor); - - A_FaceTarget(actor); - targetz = actor->target->z + actor->target->height / 2; - for (i = -1; i <= 1; i++) - { - actor->z = targetz - i * 128 * FRACUNIT; - if (P_CheckSight(actor, actor->target)) - { - targetz -= i * 128 * FRACUNIT; - break; - } - } - actor->z = memz; - - distdif = (actor->z + actor->height/2) - targetz; - - if (abs(actor->momz*16) > abs(distdif)) - actor->momz -= actor->momz/16; - else if (distdif < 0) - actor->momz = min(actor->momz+FRACUNIT/8, actor->info->speed*FRACUNIT); - else - actor->momz = max(actor->momz-FRACUNIT/8, -actor->info->speed*FRACUNIT); - - if (abs(distdif) < 128*FRACUNIT && abs(actor->momz) < FRACUNIT && P_CheckSight(actor, actor->target)) - { - P_SetMobjState(actor, actor->info->missilestate); - actor->momx = 0; - actor->momy = 0; - actor->momz = 0; - actor->extravalue1 = 0; - } -} - -// Function: A_VultureBlast -// -// Description: Vulture spawning a dust cloud. -// -// var1 = unused -// var2 = unused -// -void A_VultureBlast(mobj_t *actor) -{ - mobj_t *dust; - UINT8 i; - angle_t faa; - fixed_t faacos, faasin; - - if (LUA_CallAction(A_VULTUREBLAST, actor)) - return; - - S_StartSound(actor, actor->info->attacksound); - - faa = (actor->angle >> ANGLETOFINESHIFT) & FINEMASK; - faacos = FINECOSINE(faa); - faasin = FINESINE(faa); - - for (i = 0; i <= 7; i++) - { - angle_t fa = ((i*(angle_t)ANGLE_45) >> ANGLETOFINESHIFT) & FINEMASK; - dust = P_SpawnMobj(actor->x + 48*FixedMul(FINECOSINE(fa), -faasin), actor->y + 48*FixedMul(FINECOSINE(fa), faacos), actor->z + actor->height/2 + 48*FINESINE(fa), MT_PARTICLE); - - P_SetScale(dust, 4*FRACUNIT); - dust->destscale = FRACUNIT; - dust->scalespeed = 4*FRACUNIT/TICRATE; - dust->fuse = TICRATE; - dust->momx = FixedMul(FINECOSINE(fa), -faasin)*3; - dust->momy = FixedMul(FINECOSINE(fa), faacos)*3; - dust->momz = FINESINE(fa)*6; - } -} - -// Function: A_VultureFly -// -// Description: Vulture charging towards target. -// -// var1 = unused -// var2 = unused -// -void A_VultureFly(mobj_t *actor) -{ - fixed_t speedmax = 18*FRACUNIT; - angle_t angledif; - fixed_t dx, dy, dz, dxy, dm; - mobj_t *dust; - fixed_t momm; - - if (LUA_CallAction(A_VULTUREFLY, actor)) - return; - - if (!actor->target || P_MobjWasRemoved(actor->target)) - { - P_SetMobjState(actor, actor->info->spawnstate); - return; - } - - angledif = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) - actor->angle; - dx = actor->target->x - actor->x; - dy = actor->target->y - actor->y; - dz = actor->target->z - actor->z; - dxy = FixedHypot(dx, dy); - - if (leveltime % 4 == 0) - S_StartSound(actor, actor->info->activesound); - - if (angledif > ANGLE_180) - angledif = InvAngle(angledif); - - // Tweak the target height according to the position. - if (angledif < ANGLE_45) // Centered? - { - actor->reactiontime = actor->info->reactiontime; - if (dxy > 768*FRACUNIT) - dz = max(P_FloorzAtPos(actor->target->x, actor->target->y, actor->target->z, 0) - actor->z + min(dxy/8, 128*FRACUNIT), dz); - } - else - { - actor->reactiontime--; - - if (angledif < ANGLE_90) - dz = max(P_FloorzAtPos(actor->target->x, actor->target->y, actor->target->z, 0) - actor->z + min(dxy/2, 192*FRACUNIT), dz); - else - dz = max(P_FloorzAtPos(actor->target->x, actor->target->y, actor->target->z, 0) - actor->z + 232*FRACUNIT, dz); - } - - dm = FixedHypot(dz, dxy); - - P_VultureHoverParticle(actor); - - dust = P_SpawnMobj(actor->x + P_RandomFixed() - FRACUNIT/2, actor->y + P_RandomFixed() - FRACUNIT/2, actor->z + actor->height/2 + P_RandomFixed() - FRACUNIT/2, MT_PARTICLE); - P_SetScale(dust, 2*FRACUNIT); - dust->destscale = FRACUNIT/3; - dust->scalespeed = FRACUNIT/40; - dust->fuse = TICRATE*2; - - actor->momx += FixedDiv(dx, dm)*2; - actor->momy += FixedDiv(dy, dm)*2; - actor->momz += FixedDiv(dz, dm)*2; - - momm = FixedHypot(actor->momz, FixedHypot(actor->momx, actor->momy)); - - if (momm > speedmax/2 && actor->reactiontime == 0) - { - P_SetMobjState(actor, actor->info->seestate); - return; - } - - //Hits a wall hard? - if (actor->extravalue1 - momm > 15*FRACUNIT) - { - actor->flags &= ~MF_NOGRAVITY; - P_SetMobjState(actor, actor->info->painstate); - S_StopSound(actor); - S_StartSound(actor, actor->info->painsound); - return; - } - actor->extravalue1 = momm; - - if (momm > speedmax) - { - actor->momx = FixedMul(FixedDiv(actor->momx, momm), speedmax); - actor->momy = FixedMul(FixedDiv(actor->momy, momm), speedmax); - actor->momz = FixedMul(FixedDiv(actor->momz, momm), speedmax); - } - - actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); -} - // Function: A_SkimChase // // Description: Thinker/Chase routine for Skims @@ -6355,86 +5879,47 @@ void A_GuardChase(mobj_t *actor) if (actor->reactiontime) actor->reactiontime--; - if (actor->threshold != 42) // In formation... + if ((!actor->tracer || !actor->tracer->health) && actor->threshold != 42) { - fixed_t speed; - - if (!actor->tracer || !actor->tracer->health) - { - P_SetTarget(&actor->tracer, NULL); - actor->threshold = 42; - P_SetMobjState(actor, actor->info->painstate); - actor->flags |= MF_SPECIAL|MF_SHOOTABLE; - return; - } - - speed = actor->extravalue1*actor->scale; - - if (actor->flags2 & MF2_AMBUSH) - speed <<= 1; - - if (speed - && !P_TryMove(actor, - actor->x + P_ReturnThrustX(actor, actor->angle, speed), - actor->y + P_ReturnThrustY(actor, actor->angle, speed), - false, NULL) - && speed > 0) // can't be the same check as previous so that P_TryMove gets to happen. - { - INT32 direction = actor->args[0]; - - switch (direction) - { - case TMGD_BACK: - default: - actor->angle += ANGLE_180; - break; - case TMGD_RIGHT: - actor->angle -= ANGLE_90; - break; - case TMGD_LEFT: - actor->angle += ANGLE_90; - break; - } - } - - if (actor->extravalue1 < actor->info->speed) - actor->extravalue1++; + P_SetTarget(&actor->tracer, NULL); + actor->threshold = 42; + P_SetMobjState(actor, actor->info->painstate); + actor->flags |= MF_SPECIAL|MF_SHOOTABLE; + return; } - else // Break ranks! + + // turn towards movement direction if not there yet + if (actor->movedir < NUMDIRS) { - // turn towards movement direction if not there yet - if (actor->movedir < NUMDIRS) - { - actor->angle &= (7<<29); - delta = actor->angle - (actor->movedir << 29); + actor->angle &= (7<<29); + delta = actor->angle - (actor->movedir << 29); - if (delta > 0) - actor->angle -= ANGLE_45; - else if (delta < 0) - actor->angle += ANGLE_45; - } + if (delta > 0) + actor->angle -= ANGLE_45; + else if (delta < 0) + actor->angle += ANGLE_45; + } - if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)) - { - // look for a new target - if (P_LookForPlayers(actor, true, false, 0)) - return; // got a new target - - P_SetMobjStateNF(actor, actor->info->spawnstate); - return; - } - - // possibly choose another target - if (multiplayer && (actor->target->health <= 0 || !P_CheckSight(actor, actor->target)) - && P_LookForPlayers(actor, true, false, 0)) + if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)) + { + // look for a new target + if (P_LookForPlayers(actor, true, false, 0)) return; // got a new target - // chase towards player - if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed)) - { - P_NewChaseDir(actor); - actor->movecount += 5; // Increase tics before change in direction allowed. - } + P_SetMobjStateNF(actor, actor->info->spawnstate); + return; + } + + // possibly choose another target + if (multiplayer && (actor->target->health <= 0 || !P_CheckSight(actor, actor->target)) + && P_LookForPlayers(actor, true, false, 0)) + return; // got a new target + + // chase towards player + if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed)) + { + P_NewChaseDir(actor); + actor->movecount += 5; // Increase tics before change in direction allowed. } // Now that we've moved, its time for our shield to move! @@ -11915,243 +11400,6 @@ void A_Boss5BombExplode(mobj_t *actor) quake.radius = 20*actor->radius; } -// stuff used by A_TNTExplode -static mobj_t *barrel; -static fixed_t exploderadius; -static fixed_t explodethrust; - -static BlockItReturn_t PIT_TNTExplode(mobj_t *nearby) -{ - fixed_t dx, dy, dz; - fixed_t dm; - - if (nearby == barrel) - return BMIT_CONTINUE; - - dx = nearby->x - barrel->x; - dy = nearby->y - barrel->y; - dz = nearby->z - barrel->z + (nearby->height - barrel->height/2)/2; - dm = P_AproxDistance(P_AproxDistance(dx, dy), dz); - - if (dm >= exploderadius || !P_CheckSight(barrel, nearby)) // out of range or not visible - return BMIT_CONTINUE; - - if (barrel->type == nearby->type) // nearby is also a barrel - { - if (nearby->state == &states[nearby->info->spawnstate]) - { - if (barrel->info->attacksound) - S_StartSound(nearby, barrel->info->attacksound); - nearby->momx = FixedMul(FixedDiv(dx, dm), explodethrust); - nearby->momy = FixedMul(FixedDiv(dy, dm), explodethrust); - nearby->momz = FixedMul(FixedDiv(dz, dm), explodethrust); - P_UnsetThingPosition(nearby); - if (sector_list) - { - P_DelSeclist(sector_list); - sector_list = NULL; - } - nearby->flags = MF_NOBLOCKMAP|MF_MISSILE; - P_SetThingPosition(nearby); - P_SetMobjState(nearby, nearby->info->missilestate); - } - } - else - { - if (barrel->target == nearby) - { - mobj_t *tar = barrel->target; // temporarily store barrel's target - P_SetTarget(&barrel->target, NULL); - P_DamageMobj(nearby, barrel, NULL, 1, DMG_NORMAL); - if (!P_MobjWasRemoved(barrel)) - P_SetTarget(&barrel->target, tar); - } - else - { - P_DamageMobj(nearby, - (barrel->target) ? barrel->target : barrel, - (barrel->target) ? barrel->target : barrel, - 1, DMG_NORMAL); - } - } - - return BMIT_CONTINUE; -} - -// Function: A_TNTExplode -// -// Description: Creates a TNT explosion. Used by TNT barrels and the like. -// -// var1 = Thing type to spawn as dust. -// var2 = unused -// -void A_TNTExplode(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 x, y; - INT32 xl, xh, yl, yh; - static mappoint_t epicenter = {0,0,0}; - - if (LUA_CallAction(A_TNTEXPLODE, actor)) - return; - - if (actor->tracer) - { - P_SetTarget(&actor->tracer->tracer, NULL); - P_SetTarget(&actor->tracer, NULL); - } - - P_UnsetThingPosition(actor); - if (sector_list) - { - P_DelSeclist(sector_list); - sector_list = NULL; - } - actor->flags = MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP; - P_SetThingPosition(actor); - actor->flags2 = MF2_EXPLOSION; - if (actor->info->deathsound) - S_StartSound(actor, actor->info->deathsound); - - explodethrust = 32*FRACUNIT; - exploderadius = 256*FRACUNIT; - - xl = (unsigned)(actor->x - exploderadius - bmaporgx)>>MAPBLOCKSHIFT; - xh = (unsigned)(actor->x + exploderadius - bmaporgx)>>MAPBLOCKSHIFT; - yl = (unsigned)(actor->y - exploderadius - bmaporgy)>>MAPBLOCKSHIFT; - yh = (unsigned)(actor->y + exploderadius - bmaporgy)>>MAPBLOCKSHIFT; - - BMBOUNDFIX(xl, xh, yl, yh); - - barrel = actor; - - for (x = xl; x <= xh; x++) - for (y = yl; y <= yh; y++) - P_BlockThingsIterator(x, y, PIT_TNTExplode); - - // cause a quake -- P_StartQuake does not exist yet - epicenter.x = actor->x; - epicenter.y = actor->y; - epicenter.z = actor->z; - quake.intensity = 9*FRACUNIT; - quake.time = TICRATE/6; - quake.epicenter = &epicenter; - quake.radius = 512*FRACUNIT; - - if (locvar1) - { - P_DustRing(locvar1, 4, actor->x, actor->y, actor->z+actor->height, 64, 0, FRACUNIT, actor->scale); - P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 96, FRACUNIT, FRACUNIT, actor->scale); - } - - actor->destscale *= 4; -} - -// Function: A_DebrisRandom -// -// Description: Randomizes debris frame and movement. -// -// var1 = Frame range. -// var2 = unused -// -void A_DebrisRandom(mobj_t *actor) -{ - INT32 locvar1 = var1; - - if (LUA_CallAction(A_DEBRISRANDOM, actor)) - return; - - actor->frame |= P_RandomRange(0, locvar1); - var1 = 0; - var2 = 359; - A_ChangeAngleAbsolute(actor); - P_Thrust(actor, actor->angle, FRACUNIT * 2); -} - -static mobj_t *P_TrainSeg(mobj_t *src, fixed_t x, fixed_t y, fixed_t z, angle_t ang, spritenum_t spr, UINT32 frame) -{ - mobj_t *s = P_SpawnMobj(x, y, z, MT_TRAINSEG); - s->fuse = 16*TICRATE; - s->sprite = spr; - s->frame = frame|FF_PAPERSPRITE; - s->angle = ang; - P_Thrust(s, src->angle, 7*FRACUNIT); - return s; -} - -// Function: A_TrainCameo -// -// Description: Sets up train cameo locomotive. -// -// var1 = Train width. -// var2 = Train length. -// -void A_TrainCameo(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - fixed_t x = actor->x; - fixed_t y = actor->y; - fixed_t z = actor->z; - angle_t ang = actor->angle; - mobj_t *m; - spritenum_t spr = SPR_TRAE; - fixed_t span = locvar1*FRACUNIT; - fixed_t len = locvar2*FRACUNIT; - - if (LUA_CallAction(A_TRAINCAMEO, actor)) - return; - - //Spawn sides. - P_TrainSeg(actor, x, y + span, z, ang, spr, 0); - P_TrainSeg(actor, x, y - span, z, ang, spr, 0); - - //Center. - P_TrainSeg(actor, x, y, z, ang, spr, 1); - - //Front and back. - P_TrainSeg(actor, x + len, y, z, ang + ANGLE_90, spr, 2); - P_TrainSeg(actor, x - len, y, z, ang + ANGLE_90, spr, 2); - - //Smoke spawner. - m = P_TrainSeg(actor, x - (20 * FRACUNIT), y, z + (30 * FRACUNIT), ang + ANGLE_90, spr, 0); - P_SetMobjState(m, S_TRAINPUFFMAKER); -} - -// Function: A_TrainCameo2 -// -// Description: Sets up train cameo wagon. -// -// var1 = Train width. -// var2 = Train length. -// -void A_TrainCameo2(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - fixed_t x = actor->x; - fixed_t y = actor->y; - fixed_t z = actor->z; - angle_t ang = actor->angle; - spritenum_t spr = SPR_TRAI; - fixed_t span = locvar1*FRACUNIT; - fixed_t len = locvar2*FRACUNIT; - - if (LUA_CallAction(A_TRAINCAMEO2, actor)) - return; - - //Spawn sides. - P_TrainSeg(actor, x, y + span, z, ang, spr, 0); - P_TrainSeg(actor, x, y - span, z, ang, spr, 0); - - //Center. - P_TrainSeg(actor, x, y, z, ang, spr, 1); - - //Front and back. - P_TrainSeg(actor, x + len, y, z, ang + ANGLE_90, spr, 2); - P_TrainSeg(actor, x - len, y, z, ang + ANGLE_90, spr, 2); -} - // Function: A_CanarivoreGas // // Description: Releases gas clouds. Used by the Canarivore. @@ -12420,83 +11668,6 @@ void A_SnapperThinker(mobj_t *actor) P_SnapperLegPlace(actor); } -// Function: A_SaloonDoorSpawn -// -// Description: Spawns a saloon door. -// -// var1 = mobjtype for sides -// var2 = distance sides should be placed apart -// -void A_SaloonDoorSpawn(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - angle_t ang = actor->angle; - angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK; - fixed_t c = FINECOSINE(fa)*locvar2; - fixed_t s = FINESINE(fa)*locvar2; - mobj_t *door; - mobjflag2_t ambush = (actor->flags2 & MF2_AMBUSH); - - if (LUA_CallAction(A_SALOONDOORSPAWN, actor)) - return; - - if (!locvar1) - return; - - // One door... - if (!(door = P_SpawnMobjFromMobj(actor, c, s, 0, locvar1))) return; - door->angle = ang + ANGLE_180; - door->extravalue1 = AngleFixed(door->angle); // Origin angle - door->extravalue2 = 0; // Angular speed - P_SetTarget(&door->tracer, actor); // Origin door - door->flags2 |= ambush; // Can be opened by normal players? - - // ...two door! - if (!(door = P_SpawnMobjFromMobj(actor, -c, -s, 0, locvar1))) return; - door->angle = ang; - door->extravalue1 = AngleFixed(door->angle); // Origin angle - door->extravalue2 = 0; // Angular speed - P_SetTarget(&door->tracer, actor); // Origin door - door->flags2 |= ambush; // Can be opened by normal players? -} - -// Function: A_MinecartSparkThink -// -// Description: Thinker for the minecart spark. -// -// var1 = unused -// var2 = unused -// -void A_MinecartSparkThink(mobj_t *actor) -{ - fixed_t dx = actor->momx; - fixed_t dy = actor->momy; - fixed_t dz, dm; - UINT8 i; - - if (LUA_CallAction(A_MINECARTSPARKTHINK, actor)) - return; - - if (actor->momz == 0 && P_IsObjectOnGround(actor)) - actor->momz = P_RandomRange(2, 4)*FRACUNIT; - - dz = actor->momz; - dm = FixedHypot(FixedHypot(dx, dy), dz); - dx = FixedDiv(dx, dm); - dy = FixedDiv(dy, dm); - dz = FixedDiv(dz, dm); - - for (i = 1; i <= 8; i++) - { - mobj_t *trail = P_SpawnMobj(actor->x - dx*i, actor->y - dy*i, actor->z - dz*i, MT_PARTICLE); - trail->tics = 2; - trail->sprite = actor->sprite; - P_SetScale(trail, trail->scale/4); - trail->destscale = trail->scale; - } -} - // Function: A_ModuloToState // // Description: Modulo operation to state diff --git a/src/p_inter.c b/src/p_inter.c index 1cfc1e8e1..b24946d7a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -761,6 +761,40 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(toucher, sfx_hoop3); return; + case MT_EGGSHIELD: + { + fixed_t touchx, touchy, touchspeed; + angle_t angle; + + if (P_AproxDistance(toucher->x-special->x, toucher->y-special->y) > + P_AproxDistance((toucher->x-toucher->momx)-special->x, (toucher->y-toucher->momy)-special->y)) + { + touchx = toucher->x + toucher->momx; + touchy = toucher->y + toucher->momy; + } + else + { + touchx = toucher->x; + touchy = toucher->y; + } + + angle = R_PointToAngle2(special->x, special->y, touchx, touchy) - special->angle; + touchspeed = P_AproxDistance(toucher->momx, toucher->momy); + + // Blocked by the shield? + if (!(angle > ANGLE_90 && angle < ANGLE_270)) + { + toucher->momx = P_ReturnThrustX(special, special->angle, touchspeed); + toucher->momy = P_ReturnThrustY(special, special->angle, touchspeed); + toucher->momz = -toucher->momz; + + // Play a bounce sound? + S_StartSound(toucher, special->info->painsound); + return; + } + } + return; + case MT_BIGTUMBLEWEED: case MT_LITTLETUMBLEWEED: if (toucher->momx || toucher->momy) @@ -1549,13 +1583,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->fuse = TICRATE; break; - case MT_MINECART: - A_Scream(target); - target->momx = target->momy = target->momz = 0; - if (target->target && target->target->health) - P_KillMobj(target->target, target, source, DMG_NORMAL); - break; - case MT_PLAYER: if (damagetype != DMG_SPECTATOR) { diff --git a/src/p_mobj.c b/src/p_mobj.c index e856e8e2c..5ae8430d6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2328,9 +2328,9 @@ boolean P_ZMovement(mobj_t *mo) if (!mo->player && P_CheckDeathPitCollide(mo)) { - if (mo->flags & MF_ENEMY || mo->flags & MF_BOSS || mo->type == MT_MINECART) + if (mo->flags & MF_ENEMY || mo->flags & MF_BOSS) { - // Kill enemies, bosses and minecarts that fall into death pits. + // Kill enemies and bosses. if (mo->health) { P_KillMobj(mo, NULL, NULL, DMG_NORMAL); @@ -8487,7 +8487,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s static boolean P_FuseThink(mobj_t *mobj) { - if (mobj->type == MT_SNAPPER_HEAD || mobj->type == MT_SNAPPER_LEG || mobj->type == MT_MINECARTSEG) + if (mobj->type == MT_SNAPPER_HEAD || mobj->type == MT_SNAPPER_LEG) mobj->renderflags ^= RF_DONTDRAW; if (mobj->fuse <= TICRATE && (mobj->type == MT_RANDOMITEM || mobj->type == MT_EGGMANITEM || mobj->type == MT_FALLINGROCK)) @@ -9492,21 +9492,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_FBOMB: mobj->flags2 |= MF2_EXPLOSION; break; - case MT_OILLAMP: - { - mobj_t* overlay = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); - P_SetTarget(&overlay->target, mobj); - P_SetMobjState(overlay, S_OILLAMPFLARE); - break; - } - case MT_TNTBARREL: - mobj->momx = 1; //stack hack - mobj->flags2 |= MF2_INVERTAIMABLE; - break; - case MT_MINECARTEND: - P_SetTarget(&mobj->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID)); - mobj->tracer->angle = mobj->angle + ANGLE_90; - break; case MT_TORCHFLOWER: { mobj_t *fire = P_SpawnMobjFromMobj(mobj, 0, 0, 46*FRACUNIT, MT_FLAME); @@ -9617,7 +9602,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_RUSTYLAMP_ORANGE: P_SpawnMobj(mobj->x, mobj->y, mobj->z + (69*mobj->scale), MT_MARBLELIGHT); break; - case MT_DAYTONAPINETREE: + case MT_PINETREE: { angle_t diff = FixedAngle((360/mobj->info->mass)*FRACUNIT); UINT8 i; @@ -9626,7 +9611,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) { angle_t ang = i * diff; mobj_t *side = P_SpawnMobj(mobj->x + FINECOSINE((ang>>ANGLETOFINESHIFT) & FINEMASK), - mobj->y + FINESINE((ang>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_DAYTONAPINETREE_SIDE); + mobj->y + FINESINE((ang>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_PINETREE_SIDE); side->angle = ang; side->target = mobj; side->threshold = i; diff --git a/src/p_setup.c b/src/p_setup.c index 6ebeac25f..07725538a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5047,9 +5047,6 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[2] = !!(lines[i].flags & ML_SKEWTD); P_WriteDuplicateText(sides[lines[i].sidenum[0]].text, &lines[i].stringargs[0]); break; - case 16: //Minecart parameters - lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; - break; case 20: //PolyObject first line { INT32 check = -1; @@ -7406,12 +7403,6 @@ static void P_ConvertBinaryThingTypes(void) P_WriteConstant(MT_ROCKCRUMBLE1 + id, &mapthings[i].stringargs[0], "Mapthing", i); break; } - case 1221: //Minecart saloon door - mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); - break; - case 1229: //Minecart switch point - mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); - break; case 1300: //Flame jet (horizontal) case 1301: //Flame jet (vertical) mapthings[i].args[0] = mapthings[i].angle >> 13; From 1fb07bacb72e526746e6b4ba3755ba3f472ab72f Mon Sep 17 00:00:00 2001 From: NepDisk Date: Mon, 7 Apr 2025 00:32:32 -0400 Subject: [PATCH 02/12] Port v1 objects pt 2 --- src/info/actions.h | 11 -- src/info/mobjs.h | 126 +-------------- src/info/sprites.h | 61 +------ src/info/states.h | 353 ++--------------------------------------- src/p_enemy.c | 385 --------------------------------------------- src/p_inter.c | 31 ---- src/p_mobj.c | 194 +---------------------- 7 files changed, 21 insertions(+), 1140 deletions(-) diff --git a/src/info/actions.h b/src/info/actions.h index d0515684f..67e63d039 100644 --- a/src/info/actions.h +++ b/src/info/actions.h @@ -221,17 +221,6 @@ _(A_KillSegments, KILLSEGMENTS) _(A_SnapperSpawn, SNAPPERSPAWN) _(A_SnapperThinker, SNAPPERTHINKER) _(A_ModuloToState, MODULOTOSTATE) -_(A_LavafallRocks, LAVAFALLROCKS) -_(A_LavafallLava, LAVAFALLLAVA) -_(A_FallingLavaCheck, FALLINGLAVACHECK) -_(A_FireShrink, FIRESHRINK) -_(A_SpawnPterabytes, SPAWNPTERABYTES) -_(A_PterabyteHover, PTERABYTEHOVER) -_(A_RolloutSpawn, ROLLOUTSPAWN) -_(A_RolloutRock, ROLLOUTROCK) -_(A_DragonbomberSpawn, DRAGONBOMBERSPAWN) -_(A_DragonWing, DRAGONWING) -_(A_DragonSegment, DRAGONSEGMENT) _(A_ChangeHeight, CHANGEHEIGHT) // SRB2Kart diff --git a/src/info/mobjs.h b/src/info/mobjs.h index c4204ca8d..79796d3df 100644 --- a/src/info/mobjs.h +++ b/src/info/mobjs.h @@ -45,17 +45,6 @@ _(SPRINGSHELL) // Spring Shell _(YELLOWSHELL) // Spring Shell (yellow) _(UNIDUS) // Unidus _(UNIBALL) // Unidus Ball -_(CANARIVORE) // Canarivore -_(CANARIVORE_GAS) // Canarivore gas -_(PYREFLY) // Pyre Fly -_(PYREFLY_FIRE) // Pyre Fly fire -_(PTERABYTESPAWNER) // Pterabyte spawner -_(PTERABYTEWAYPOINT) // Pterabyte waypoint -_(PTERABYTE) // Pterabyte -_(DRAGONBOMBER) // Dragonbomber -_(DRAGONWING) // Dragonbomber wing -_(DRAGONTAIL) // Dragonbomber tail segment -_(DRAGONMINE) // Dragonbomber mine // Generic Boss Items _(BOSSEXPLODE) @@ -268,62 +257,30 @@ _(CANNONBALLDECOR) // Decorative/still cannonball _(ARROW) // Arrow _(DEMONFIRE) // Glaregoyle fire -// The letter -_(LETTER) - // Greenflower Scenery _(GFZFLOWER1) _(GFZFLOWER2) _(GFZFLOWER3) - -_(BLUEBERRYBUSH) _(BERRYBUSH) _(BUSH) -// Trees (both GFZ and misc) -_(GFZTREE) -_(GFZBERRYTREE) -_(GFZCHERRYTREE) -_(CHECKERTREE) -_(CHECKERSUNSETTREE) -_(FHZTREE) // Frozen Hillside -_(FHZPINKTREE) -_(POLYGONTREE) -_(BUSHTREE) -_(BUSHREDTREE) -_(SPRINGTREE) - // Techno Hill Scenery -_(THZFLOWER1) -_(THZFLOWER2) -_(THZFLOWER3) -_(THZTREE) // Steam whistle tree/bush -_(THZTREEBRANCH) // branch of said tree +_(THZPLANT) // THZ Plant _(ALARM) // Deep Sea Scenery _(GARGOYLE) // Deep Sea Gargoyle -_(BIGGARGOYLE) // Deep Sea Gargoyle (Big) _(SEAWEED) // DSZ Seaweed _(WATERDRIP) // Dripping Water source _(WATERDROP) // Water drop from dripping water -_(CORAL1) // Coral -_(CORAL2) -_(CORAL3) -_(CORAL4) -_(CORAL5) +_(CORAL1) // Coral 1 +_(CORAL2) // Coral 2 +_(CORAL3) // Coral 3 _(BLUECRYSTAL) // Blue Crystal -_(KELP) // Kelp -_(ANIMALGAETOP) // Animated algae top -_(ANIMALGAESEG) // Animated algae segment -_(DSZSTALAGMITE) // Deep Sea 1 Stalagmite -_(DSZ2STALAGMITE) // Deep Sea 2 Stalagmite -_(LIGHTBEAM) // DSZ Light beam // Castle Eggman Scenery _(CHAIN) // CEZ Chain -_(FLAME) // Flame (has corona) -_(FLAMEPARTICLE) +_(FLAME) // Flame _(EGGSTATUE) // Eggman Statue _(MACEPOINT) // Mace rotation point _(CHAINMACEPOINT) // Combination of chains and maces point @@ -343,24 +300,6 @@ _(REDSPRINGBALL) // Red spring on a ball _(SMALLFIREBAR) // Small Firebar _(BIGFIREBAR) // Big Firebar _(CEZFLOWER) // Flower -_(CEZPOLE1) // Pole (with red banner) -_(CEZPOLE2) // Pole (with blue banner) -_(CEZBANNER1) // Banner (red) -_(CEZBANNER2) // Banner (blue) -_(CEZBUSH1) // Bush 1 -_(CEZBUSH2) // Bush 2 -_(CANDLE) // Candle -_(CANDLEPRICKET) // Candle pricket -_(FLAMEHOLDER) // Flame holder -_(FIRETORCH) // Fire torch -_(WAVINGFLAG1) // Waving flag (red) -_(WAVINGFLAG2) // Waving flag (blue) -_(WAVINGFLAGSEG1) // Waving flag segment (red) -_(WAVINGFLAGSEG2) // Waving flag segment (blue) -_(CRAWLASTATUE) // Crawla statue -_(FACESTABBERSTATUE) // Facestabber statue -_(SUSPICIOUSFACESTABBERSTATUE) // :eggthinking: -_(BRAMBLES) // Brambles // Arid Canyon Scenery _(BIGTUMBLEWEED) @@ -380,20 +319,6 @@ _(FJSPINAXISB) // Clockwise _(FLAMEJETFLAMEB) // Blade's flame -_(LAVAFALL) -_(LAVAFALL_LAVA) -_(LAVAFALLROCK) - -_(ROLLOUTSPAWN) -_(ROLLOUTROCK) - -_(BIGFERNLEAF) -_(BIGFERN) -_(JUNGLEPALM) -_(TORCHFLOWER) -_(WALLVINE_LONG) -_(WALLVINE_SHORT) - // Dark City Scenery // Egg Rock Scenery @@ -432,27 +357,6 @@ _(MISTLETOE) _(XMASBLUEBERRYBUSH) _(XMASBERRYBUSH) _(XMASBUSH) -// FHZ -_(FHZICE1) -_(FHZICE2) -_(ROSY) -_(CDLHRT) - -// Halloween Scenery -// Pumpkins -_(JACKO1) -_(JACKO2) -_(JACKO3) -// Dr Seuss Trees -_(HHZTREE_TOP) -_(HHZTREE_PART) -// Misc -_(HHZSHROOM) -_(HHZGRASS) -_(HHZTENTACLE1) -_(HHZTENTACLE2) -_(HHZSTALAGMITE_TALL) -_(HHZSTALAGMITE_SHORT) // Botanic Serenity scenery _(BSZTALLFLOWER_RED) @@ -665,26 +569,6 @@ _(NIGHTOPIANHELPER) // the actual helper object that orbits you _(PIAN) // decorative singing friend _(SHLEEP) // almost-decorative sleeping enemy -// Secret badniks and hazards, shhhh -_(PENGUINATOR) -_(POPHAT) -_(POPSHOT) -_(POPSHOT_TRAIL) - -_(HIVEELEMENTAL) -_(BUMBLEBORE) - -_(BUGGLE) - -_(SMASHINGSPIKEBALL) -_(CACOLANTERN) -_(CACOSHARD) -_(CACOFIRE) -_(SPINBOBERT) -_(SPINBOBERT_FIRE1) -_(SPINBOBERT_FIRE2) -_(HANGSTER) - // Utility Objects _(TELEPORTMAN) _(ALTVIEWMAN) diff --git a/src/info/sprites.h b/src/info/sprites.h index 5c27aa74c..6726261f9 100644 --- a/src/info/sprites.h +++ b/src/info/sprites.h @@ -174,9 +174,6 @@ _(CBLL) // Cannonball _(AROW) // Arrow _(CFIR) // Colored fire of various sorts -// The letter -_(LETR) - // Greenflower Scenery _(FWR1) _(FWR2) // GFZ Sunflower @@ -184,33 +181,19 @@ _(FWR3) // GFZ budding flower _(FWR4) _(BUS1) // GFZ Bush w/ berries _(BUS2) // GFZ Bush w/o berries -_(BUS3) // GFZ Bush w/ BLUE berries -// Trees (both GFZ and misc) -_(TRE1) // GFZ -_(TRE2) // Checker -_(TRE3) // Frozen Hillside -_(TRE4) // Polygon -_(TRE5) // Bush tree -_(TRE6) // Spring tree // Techno Hill Scenery -_(THZP) // THZ1 Steam Flower -_(FWR5) // THZ1 Spin flower (red) -_(FWR6) // THZ1 Spin flower (yellow) -_(THZT) // Steam Whistle tree/bush +_(THZP) // Techno Hill Zone Plant _(ALRM) // THZ2 Alarm // Deep Sea Scenery _(GARG) // Deep Sea Gargoyle _(SEWE) // Deep Sea Seaweed _(DRIP) // Dripping water -_(CORL) // Coral +_(CRL1) // Coral 1 +_(CRL2) // Coral 2 +_(CRL3) // Coral 3 _(BCRY) // Blue Crystal -_(KELP) // Kelp -_(ALGA) // Animated algae top -_(ALGB) // Animated algae segment -_(DSTG) // DSZ Stalagmites -_(LIBE) // DSZ Light beam // Castle Eggman Scenery _(CHAN) // CEZ Chain @@ -224,16 +207,6 @@ _(YSPB) // Yellow spring on a ball _(RSPB) // Red spring on a ball _(SFBR) // Small Firebar _(BFBR) // Big Firebar -_(BANR) // Banner/pole -_(PINE) // Pine Tree -_(CEZB) // Bush -_(CNDL) // Candle/pricket -_(FLMH) // Flame holder -_(CTRC) // Fire torch -_(CFLG) // Waving flag/segment -_(CSTA) // Crawla statue -_(CBBS) // Facestabber statue -_(CABR) // Brambles // Arid Canyon Scenery _(BTBL) // Big tumbleweed @@ -243,10 +216,6 @@ _(CACT) // Cacti // Red Volcano Scenery _(FLME) // Flame jet _(DFLM) // Blade's flame -_(LFAL) // Lavafall -_(JPLA) // Jungle palm -_(TFLO) // Torch flower -_(WVIN) // Wall vines // Dark City Scenery @@ -261,13 +230,6 @@ _(XMS5) // Hanging Star _(XMS6) // Mistletoe _(FHZI) // FHZ Ice _(ROSY) - -// Halloween Scenery -_(PUMK) // Pumpkins -_(HHPL) // Dr Seuss Trees -_(SHRM) // Mushroom -_(HHZM) // Misc - // Azure Temple Scenery _(BGAR) // ATZ Gargoyles _(RCRY) // ATZ Red Crystal (Target) @@ -424,21 +386,6 @@ _(IDYA) // Ideya _(NTPN) // Nightopian _(SHLP) // Shleep -// Secret badniks and hazards, shhhh -_(PENG) -_(POPH) -_(HIVE) -_(BUMB) -_(BBUZ) -_(FMCE) -_(HMCE) -_(CACO) -_(BAL2) -_(SBOB) -_(SBFL) -_(SBSK) -_(HBAT) - // Debris _(SPRK) // Sparkle _(BOM1) // Robot Explosion diff --git a/src/info/states.h b/src/info/states.h index 3a97968a7..b69dccda4 100644 --- a/src/info/states.h +++ b/src/info/states.h @@ -361,64 +361,6 @@ _(UNIDUS_STND) _(UNIDUS_RUN) _(UNIDUS_BALL) -// Canarivore -_(CANARIVORE_LOOK) -_(CANARIVORE_AWAKEN1) -_(CANARIVORE_AWAKEN2) -_(CANARIVORE_AWAKEN3) -_(CANARIVORE_GAS1) -_(CANARIVORE_GAS2) -_(CANARIVORE_GAS3) -_(CANARIVORE_GAS4) -_(CANARIVORE_GAS5) -_(CANARIVORE_GASREPEAT) -_(CANARIVORE_CLOSE1) -_(CANARIVORE_CLOSE2) -_(CANARIVOREGAS_1) -_(CANARIVOREGAS_2) -_(CANARIVOREGAS_3) -_(CANARIVOREGAS_4) -_(CANARIVOREGAS_5) -_(CANARIVOREGAS_6) -_(CANARIVOREGAS_7) -_(CANARIVOREGAS_8) - -// Pyre Fly -_(PYREFLY_FLY) -_(PYREFLY_BURN) -_(PYREFIRE1) -_(PYREFIRE2) - -// Pterabyte -_(PTERABYTESPAWNER) -_(PTERABYTEWAYPOINT) -_(PTERABYTE_FLY1) -_(PTERABYTE_FLY2) -_(PTERABYTE_FLY3) -_(PTERABYTE_FLY4) -_(PTERABYTE_SWOOPDOWN) -_(PTERABYTE_SWOOPUP) - -// Dragonbomber -_(DRAGONBOMBER) -_(DRAGONWING1) -_(DRAGONWING2) -_(DRAGONWING3) -_(DRAGONWING4) -_(DRAGONTAIL_LOADED) -_(DRAGONTAIL_EMPTY) -_(DRAGONTAIL_EMPTYLOOP) -_(DRAGONTAIL_RELOAD) -_(DRAGONMINE) -_(DRAGONMINE_LAND1) -_(DRAGONMINE_LAND2) -_(DRAGONMINE_SLOWFLASH1) -_(DRAGONMINE_SLOWFLASH2) -_(DRAGONMINE_SLOWLOOP) -_(DRAGONMINE_FASTFLASH1) -_(DRAGONMINE_FASTFLASH2) -_(DRAGONMINE_FASTLOOP) - // Boss Explosion _(BOSSEXPLODE) @@ -1372,51 +1314,23 @@ _(ARROWDOWN) // Glaregoyle Demon fire _(DEMONFIRE) -// The letter -_(LETTER) - // GFZ flowers _(GFZFLOWERA) -_(GFZFLOWERB) -_(GFZFLOWERC) +_(GFZFLOWERA2) + +_(GFZFLOWERB1) +_(GFZFLOWERB2) + +_(GFZFLOWERC1) -_(BLUEBERRYBUSH) _(BERRYBUSH) _(BUSH) -// Trees (both GFZ and misc) -_(GFZTREE) -_(GFZBERRYTREE) -_(GFZCHERRYTREE) -_(CHECKERTREE) -_(CHECKERSUNSETTREE) -_(FHZTREE) // Frozen Hillside -_(FHZPINKTREE) -_(POLYGONTREE) -_(BUSHTREE) -_(BUSHREDTREE) -_(SPRINGTREE) - -// THZ flowers -_(THZFLOWERA) // THZ1 Steam flower -_(THZFLOWERB) // THZ1 Spin flower (red) -_(THZFLOWERC) // THZ1 Spin flower (yellow) - -// THZ Steam Whistle tree/bush -_(THZTREE) -_(THZTREEBRANCH1) -_(THZTREEBRANCH2) -_(THZTREEBRANCH3) -_(THZTREEBRANCH4) -_(THZTREEBRANCH5) -_(THZTREEBRANCH6) -_(THZTREEBRANCH7) -_(THZTREEBRANCH8) -_(THZTREEBRANCH9) -_(THZTREEBRANCH10) -_(THZTREEBRANCH11) -_(THZTREEBRANCH12) -_(THZTREEBRANCH13) +// THZ Plant +_(THZPLANT1) +_(THZPLANT2) +_(THZPLANT3) +_(THZPLANT4) // THZ Alarm _(ALARM1) @@ -1446,38 +1360,10 @@ _(DRIPC2) _(CORAL1) _(CORAL2) _(CORAL3) -_(CORAL4) -_(CORAL5) // Blue Crystal _(BLUECRYSTAL1) -// Kelp, -_(KELP) - -// Animated algae -_(ANIMALGAETOP1) -_(ANIMALGAETOP2) -_(ANIMALGAESEG) - -// DSZ Stalagmites -_(DSZSTALAGMITE) -_(DSZ2STALAGMITE) - -// DSZ Light beam -_(LIGHTBEAM1) -_(LIGHTBEAM2) -_(LIGHTBEAM3) -_(LIGHTBEAM4) -_(LIGHTBEAM5) -_(LIGHTBEAM6) -_(LIGHTBEAM7) -_(LIGHTBEAM8) -_(LIGHTBEAM9) -_(LIGHTBEAM10) -_(LIGHTBEAM11) -_(LIGHTBEAM12) - // CEZ Chain _(CEZCHAIN) @@ -1552,24 +1438,6 @@ _(BIGFIREBAR15) _(BIGFIREBAR16) _(CEZFLOWER) -_(CEZPOLE) -_(CEZBANNER1) -_(CEZBANNER2) -_(CEZBUSH1) -_(CEZBUSH2) -_(CANDLE) -_(CANDLEPRICKET) -_(FLAMEHOLDER) -_(FIRETORCH) -_(WAVINGFLAG) -_(WAVINGFLAGSEG1) -_(WAVINGFLAGSEG2) -_(CRAWLASTATUE) -_(FACESTABBERSTATUE) -_(SUSPICIOUSFACESTABBERSTATUE_WAIT) -_(SUSPICIOUSFACESTABBERSTATUE_BURST1) -_(SUSPICIOUSFACESTABBERSTATUE_BURST2) -_(BRAMBLES) // Big Tumbleweed _(BIGTUMBLEWEED) @@ -1624,28 +1492,6 @@ _(FLAMEJETFLAMEB1) _(FLAMEJETFLAMEB2) _(FLAMEJETFLAMEB3) -// Lavafall -_(LAVAFALL_DORMANT) -_(LAVAFALL_TELL) -_(LAVAFALL_SHOOT) -_(LAVAFALL_LAVA1) -_(LAVAFALL_LAVA2) -_(LAVAFALL_LAVA3) -_(LAVAFALLROCK) - -// Rollout Rock -_(ROLLOUTSPAWN) -_(ROLLOUTROCK) - -// RVZ scenery -_(BIGFERNLEAF) -_(BIGFERN1) -_(BIGFERN2) -_(JUNGLEPALM) -_(TORCHFLOWER) -_(WALLVINE_LONG) -_(WALLVINE_SHORT) - // Glaregoyles _(GLAREGOYLE) _(GLAREGOYLE_CHARGE) @@ -1714,64 +1560,6 @@ _(MISTLETOE) _(XMASBLUEBERRYBUSH) _(XMASBERRYBUSH) _(XMASBUSH) -// FHZ -_(FHZICE1) -_(FHZICE2) -_(ROSY_IDLE1) -_(ROSY_IDLE2) -_(ROSY_IDLE3) -_(ROSY_IDLE4) -_(ROSY_JUMP) -_(ROSY_WALK) -_(ROSY_HUG) -_(ROSY_PAIN) -_(ROSY_STND) -_(ROSY_UNHAPPY) - -// Halloween Scenery -// Pumpkins -_(JACKO1) -_(JACKO1OVERLAY_1) -_(JACKO1OVERLAY_2) -_(JACKO1OVERLAY_3) -_(JACKO1OVERLAY_4) -_(JACKO2) -_(JACKO2OVERLAY_1) -_(JACKO2OVERLAY_2) -_(JACKO2OVERLAY_3) -_(JACKO2OVERLAY_4) -_(JACKO3) -_(JACKO3OVERLAY_1) -_(JACKO3OVERLAY_2) -_(JACKO3OVERLAY_3) -_(JACKO3OVERLAY_4) -// Dr Seuss Trees -_(HHZTREE_TOP) -_(HHZTREE_TRUNK) -_(HHZTREE_LEAF) -// Mushroom -_(HHZSHROOM_1) -_(HHZSHROOM_2) -_(HHZSHROOM_3) -_(HHZSHROOM_4) -_(HHZSHROOM_5) -_(HHZSHROOM_6) -_(HHZSHROOM_7) -_(HHZSHROOM_8) -_(HHZSHROOM_9) -_(HHZSHROOM_10) -_(HHZSHROOM_11) -_(HHZSHROOM_12) -_(HHZSHROOM_13) -_(HHZSHROOM_14) -_(HHZSHROOM_15) -_(HHZSHROOM_16) -// Misc -_(HHZGRASS) -_(HHZTENT1) -_(HHZTENT2) -_(HHZSTALAGMITE_TALL) -_(HHZSTALAGMITE_SHORT) // Botanic Serenity's loads of scenery states _(BSZTALLFLOWER_RED) @@ -2841,125 +2629,6 @@ _(SHLEEPBOUNCE1) _(SHLEEPBOUNCE2) _(SHLEEPBOUNCE3) -// Secret badniks and hazards, shhhh -_(PENGUINATOR_LOOK) -_(PENGUINATOR_WADDLE1) -_(PENGUINATOR_WADDLE2) -_(PENGUINATOR_WADDLE3) -_(PENGUINATOR_WADDLE4) -_(PENGUINATOR_SLIDE1) -_(PENGUINATOR_SLIDE2) -_(PENGUINATOR_SLIDE3) -_(PENGUINATOR_SLIDE4) -_(PENGUINATOR_SLIDE5) - -_(POPHAT_LOOK) -_(POPHAT_SHOOT1) -_(POPHAT_SHOOT2) -_(POPHAT_SHOOT3) -_(POPHAT_SHOOT4) -_(POPSHOT) -_(POPSHOT_TRAIL) - -_(HIVEELEMENTAL_LOOK) -_(HIVEELEMENTAL_PREPARE1) -_(HIVEELEMENTAL_PREPARE2) -_(HIVEELEMENTAL_SHOOT1) -_(HIVEELEMENTAL_SHOOT2) -_(HIVEELEMENTAL_DORMANT) -_(HIVEELEMENTAL_PAIN) -_(HIVEELEMENTAL_DIE1) -_(HIVEELEMENTAL_DIE2) -_(HIVEELEMENTAL_DIE3) - -_(BUMBLEBORE_SPAWN) -_(BUMBLEBORE_LOOK1) -_(BUMBLEBORE_LOOK2) -_(BUMBLEBORE_FLY1) -_(BUMBLEBORE_FLY2) -_(BUMBLEBORE_RAISE) -_(BUMBLEBORE_FALL1) -_(BUMBLEBORE_FALL2) -_(BUMBLEBORE_STUCK1) -_(BUMBLEBORE_STUCK2) -_(BUMBLEBORE_DIE) - -_(BUGGLEIDLE) -_(BUGGLEFLY) - -_(SMASHSPIKE_FLOAT) -_(SMASHSPIKE_EASE1) -_(SMASHSPIKE_EASE2) -_(SMASHSPIKE_FALL) -_(SMASHSPIKE_STOMP1) -_(SMASHSPIKE_STOMP2) -_(SMASHSPIKE_RISE1) -_(SMASHSPIKE_RISE2) - -_(CACO_LOOK) -_(CACO_WAKE1) -_(CACO_WAKE2) -_(CACO_WAKE3) -_(CACO_WAKE4) -_(CACO_ROAR) -_(CACO_CHASE) -_(CACO_CHASE_REPEAT) -_(CACO_RANDOM) -_(CACO_PREPARE_SOUND) -_(CACO_PREPARE1) -_(CACO_PREPARE2) -_(CACO_PREPARE3) -_(CACO_SHOOT_SOUND) -_(CACO_SHOOT1) -_(CACO_SHOOT2) -_(CACO_CLOSE) -_(CACO_DIE_FLAGS) -_(CACO_DIE_GIB1) -_(CACO_DIE_GIB2) -_(CACO_DIE_SCREAM) -_(CACO_DIE_SHATTER) -_(CACO_DIE_FALL) -_(CACOSHARD_RANDOMIZE) -_(CACOSHARD1_1) -_(CACOSHARD1_2) -_(CACOSHARD2_1) -_(CACOSHARD2_2) -_(CACOFIRE1) -_(CACOFIRE2) -_(CACOFIRE3) -_(CACOFIRE_EXPLODE1) -_(CACOFIRE_EXPLODE2) -_(CACOFIRE_EXPLODE3) -_(CACOFIRE_EXPLODE4) - -_(SPINBOBERT_MOVE_FLIPUP) -_(SPINBOBERT_MOVE_UP) -_(SPINBOBERT_MOVE_FLIPDOWN) -_(SPINBOBERT_MOVE_DOWN) -_(SPINBOBERT_FIRE_MOVE) -_(SPINBOBERT_FIRE_GHOST) -_(SPINBOBERT_FIRE_TRAIL1) -_(SPINBOBERT_FIRE_TRAIL2) -_(SPINBOBERT_FIRE_TRAIL3) - -_(HANGSTER_LOOK) -_(HANGSTER_SWOOP1) -_(HANGSTER_SWOOP2) -_(HANGSTER_ARC1) -_(HANGSTER_ARC2) -_(HANGSTER_ARC3) -_(HANGSTER_FLY1) -_(HANGSTER_FLY2) -_(HANGSTER_FLY3) -_(HANGSTER_FLY4) -_(HANGSTER_FLYREPEAT) -_(HANGSTER_ARCUP1) -_(HANGSTER_ARCUP2) -_(HANGSTER_ARCUP3) -_(HANGSTER_RETURN1) -_(HANGSTER_RETURN2) -_(HANGSTER_RETURN3) - _(CRUMBLE1) _(CRUMBLE2) diff --git a/src/p_enemy.c b/src/p_enemy.c index b701300e7..7d40a6cdb 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -11688,391 +11688,6 @@ void A_ModuloToState(mobj_t *actor) modulothing++; } -// Function: A_LavafallRocks -// -// Description: Spawn random rock particles. -// -// var1 = unused -// var2 = unused -// -void A_LavafallRocks(mobj_t *actor) -{ - UINT8 i; - - if (LUA_CallAction(A_LAVAFALLROCKS, actor)) - return; - - // Don't spawn rocks unless a player is relatively close by. - for (i = 0; i < MAXPLAYERS; ++i) - if (playeringame[i] && players[i].mo - && P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed >> 1)) - break; // Stop looking. - - if (i < MAXPLAYERS) - { - angle_t fa = (FixedAngle(P_RandomKey(360) << FRACBITS) >> ANGLETOFINESHIFT) & FINEMASK; - fixed_t offset = P_RandomRange(4, 12) << FRACBITS; - fixed_t xoffs = FixedMul(FINECOSINE(fa), actor->radius + offset); - fixed_t yoffs = FixedMul(FINESINE(fa), actor->radius + offset); - P_SpawnMobjFromMobj(actor, xoffs, yoffs, 0, MT_LAVAFALLROCK); - } -} - -// Function: A_LavafallLava -// -// Description: Spawn lava from lavafall. -// -// var1 = unused -// var2 = unused -// -void A_LavafallLava(mobj_t *actor) -{ - mobj_t *lavafall; - UINT8 i; - - if (LUA_CallAction(A_LAVAFALLLAVA, actor)) - return; - - if ((40 - actor->fuse) % (2*(actor->scale >> FRACBITS))) - return; - - // Don't spawn lava unless a player is nearby. - for (i = 0; i < MAXPLAYERS; ++i) - if (playeringame[i] && players[i].mo - && P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed)) - break; // Stop looking. - - if (i >= MAXPLAYERS) - return; - - lavafall = P_SpawnMobjFromMobj(actor, 0, 0, -8*FRACUNIT, MT_LAVAFALL_LAVA); - lavafall->momz = -P_MobjFlip(actor)*25*FRACUNIT; -} - -// Function: A_FallingLavaCheck -// -// Description: If actor hits the ground or a water surface, enter the death animation. -// -// var1 = unused -// var2 = unused -// -void A_FallingLavaCheck(mobj_t *actor) -{ - if (LUA_CallAction(A_FALLINGLAVACHECK, actor)) - return; - - if (actor->eflags & MFE_TOUCHWATER || P_IsObjectOnGround(actor)) - { - actor->flags = MF_NOGRAVITY|MF_NOCLIPTHING; - actor->momz = 0; - if (actor->eflags & MFE_TOUCHWATER) - actor->z = (actor->eflags & MFE_VERTICALFLIP) ? actor->waterbottom : actor->watertop; - P_SetMobjState(actor, actor->info->deathstate); - } -} - -// Function: A_FireShrink -// -// Description: Shrink the actor down to the specified scale at the specified speed. -// -// var1 = Scale to shrink to -// var2 = Shrinking speed -// -void A_FireShrink(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - - if (LUA_CallAction(A_FIRESHRINK, actor)) - return; - - actor->destscale = locvar1; - actor->scalespeed = FRACUNIT/locvar2; -} - -// Function: A_SpawnPterabytes -// -// Description: Spawn Pterabytes around the actor in a circle. -// -// var1 = unused -// var2 = unused -// -void A_SpawnPterabytes(mobj_t *actor) -{ - mobj_t *waypoint, *ptera; - fixed_t c, s; - fixed_t rad = 280*FRACUNIT; - angle_t ang = 0; - angle_t interval, fa; - UINT8 amount = 1; - UINT8 i; - - if (LUA_CallAction(A_SPAWNPTERABYTES, actor)) - return; - - amount = min(1, actor->args[0]); - - interval = FixedAngle(FRACUNIT*360/amount); - - for (i = 0; i < amount; i++) - { - fa = (ang >> ANGLETOFINESHIFT) & FINEMASK; - c = FINECOSINE(fa); - s = FINESINE(fa); - waypoint = P_SpawnMobjFromMobj(actor, FixedMul(c, rad), FixedMul(s, rad), 0, MT_PTERABYTEWAYPOINT); - waypoint->angle = ang + ANGLE_90; - P_SetTarget(&waypoint->tracer, actor); - ptera = P_SpawnMobjFromMobj(waypoint, 0, 0, 0, MT_PTERABYTE); - ptera->angle = waypoint->angle; - P_SetTarget(&ptera->tracer, waypoint); - ptera->extravalue1 = 0; - ang += interval; - } -} - -// Function: A_PterabyteHover -// -// Description: Hover in a circular fashion, bobbing up and down slightly. -// -// var1 = unused -// var2 = unused -// -void A_PterabyteHover(mobj_t *actor) -{ - angle_t ang, fa; - - if (LUA_CallAction(A_PTERABYTEHOVER, actor)) - return; - - P_InstaThrust(actor, actor->angle, actor->info->speed); - actor->angle += ANG1; - actor->extravalue1 = (actor->extravalue1 + 3) % 360; - ang = actor->extravalue1*ANG1; - fa = (ang >> ANGLETOFINESHIFT) & FINEMASK; - actor->z += FINESINE(fa); -} -// Function: A_RolloutSpawn -// -// Description: Spawns a new Rollout Rock when the currently spawned rock is destroyed or moves far enough away. -// -// var1 = Distance currently spawned rock should travel before spawning a new one -// var2 = Object type to spawn -// -void A_RolloutSpawn(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - - if (LUA_CallAction(A_ROLLOUTSPAWN, actor)) - return; - - if (!(actor->target) - || P_MobjWasRemoved(actor->target) - || P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) > locvar1) - { - actor->target = P_SpawnMobj(actor->x, actor->y, actor->z, locvar2); - actor->target->flags2 |= (actor->flags2 & (MF2_AMBUSH | MF2_OBJECTFLIP)) | MF2_SLIDEPUSH; - actor->target->eflags |= (actor->eflags & MFE_VERTICALFLIP); - - if (actor->target->flags2 & MF2_AMBUSH) - { - actor->target->color = SKINCOLOR_CSUPER1; - actor->target->colorized = true; - } - } -} - -// Function: A_RolloutRock -// -// Description: Thinker for Rollout Rock. -// -// var1 = Drag -// var2 = Vertical bobbing speed factor -// -void A_RolloutRock(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - UINT8 maxframes = actor->info->reactiontime; // number of frames the mobj cycles through - fixed_t pi = (22*FRACUNIT/7); - fixed_t circumference = FixedMul(2 * pi, actor->radius); // used to calculate when to change frame - fixed_t speed = P_AproxDistance(actor->momx, actor->momy), topspeed = FixedMul(actor->info->speed, actor->scale); - boolean inwater = actor->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER); - - if (LUA_CallAction(A_ROLLOUTROCK, actor)) - return; - - actor->friction = FRACUNIT; // turns out riding on solids sucks, so let's just make it easier on ourselves - - if (actor->eflags & MFE_JUSTHITFLOOR) - S_StartSound(actor, actor->info->painsound); - - if (actor->threshold) - actor->threshold--; - - if (inwater && !(actor->flags2 & MF2_AMBUSH)) // buoyancy in water (or lava) - { - UINT8 flip = P_MobjFlip(actor); - fixed_t prevmomz = actor->momz; - actor->momz = FixedMul(actor->momz, locvar2); - actor->momz += flip * FixedMul(locvar2, actor->scale); - if (flip*prevmomz < 0 && flip*actor->momz >= 0 && !actor->threshold) - { - if (actor->eflags & MFE_UNDERWATER) - S_StartSound(actor, sfx_splash); - else if (!actor->threshold) - S_StartSound(actor, sfx_splish); - actor->threshold = max((topspeed - speed) >> FRACBITS, 8); - } - } - - if (speed > topspeed) // cap speed - { - actor->momx = FixedMul(FixedDiv(actor->momx, speed), topspeed); - actor->momy = FixedMul(FixedDiv(actor->momy, speed), topspeed); - } - - if (P_IsObjectOnGround(actor) || inwater) // apply drag to speed (compensates for lack of friction but also works in liquids) - { - actor->momx = FixedMul(actor->momx, locvar1); - actor->momy = FixedMul(actor->momy, locvar1); - } - - speed = P_AproxDistance(actor->momx, actor->momy); // recalculate speed for visual rolling - - if (speed < actor->scale >> 1) // stop moving if speed is insignificant - { - actor->momx = 0; - actor->momy = 0; - } - else if (speed > actor->scale) - { - actor->movecount = 1; // rock has moved; fuse should be set so we don't have a trillion rocks lying around - actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); // set rock's angle to movement direction - actor->movefactor += speed; - if (actor->movefactor > circumference / maxframes) // if distance moved is enough to change frame, change it! - { - actor->reactiontime++; - actor->reactiontime %= maxframes; - actor->movefactor = 0; - } - } - - actor->frame = actor->reactiontime % maxframes; // set frame - - if (!actor->tracer || P_MobjWasRemoved(actor->tracer) || !actor->tracer->health) - actor->flags |= MF_PUSHABLE; - - if (!(actor->flags & MF_PUSHABLE) || (actor->movecount != 1)) // if being ridden or haven't moved, don't disappear - actor->fuse = actor->info->painchance; - else if (actor->fuse < 2*TICRATE) - actor->renderflags ^= RF_DONTDRAW; - -} - -// Function: A_DragonbomberSpawn -// -// Description: Spawns the body parts for Dragonbomber -// -// var1 = Tail segments to spawn -// var2 = unused -// -void A_DragonbomberSpawn(mobj_t *actor) -{ - UINT8 i; - mobj_t *mo = actor; - - if (LUA_CallAction(A_DRAGONBOMBERSPAWN, actor)) - return; - - for (i = 0; i < var1; i++) // spawn tail segments - { - mobj_t *segment; - fixed_t x, y; - x = P_ReturnThrustX(mo, mo->angle, -mo->radius << 1); - y = P_ReturnThrustY(mo, mo->angle, -mo->radius << 1); - segment = P_SpawnMobjFromMobj(mo, x, y, 0, MT_DRAGONTAIL); - P_SetTarget(&segment->target, mo); - P_SetTarget(&mo->tracer, segment); - segment->angle = mo->angle; - mo = segment; - } - for (i = 0; i < 2; i++) // spawn wings - { - mo = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_DRAGONWING); - P_SetTarget(&mo->target, actor); - mo->movedir = ANGLE_90 + i * ANGLE_180; - } -} - -// Function: A_DragonWing -// -// Description: Moves actor such that it is placed away from its target at a distance equal to the target's radius in the direction of its target's angle. -// The actor's movedir can be used to offset the angle. -// -// var1 = unused -// var2 = unused -// -void A_DragonWing(mobj_t *actor) -{ - mobj_t *target = actor->target; - fixed_t x, y; - - if (LUA_CallAction(A_DRAGONWING, actor)) - return; - - if (target == NULL || !target->health) - { - P_RemoveMobj(actor); - return; - } - actor->angle = target->angle + actor->movedir; - x = target->x + P_ReturnThrustX(actor, actor->angle, -target->radius); - y = target->y + P_ReturnThrustY(actor, actor->angle, -target->radius); - P_MoveOrigin(actor, x, y, target->z); -} - -// Function: A_DragonSegment -// -// Description: Moves actor such that it is placed away from its target at an absolute distance equal to the sum of the two mobjs' radii. -// -// var1 = unused -// var2 = unused -// -void A_DragonSegment(mobj_t *actor) -{ - mobj_t *target = actor->target; - fixed_t dist; - fixed_t radius; - angle_t hangle; - angle_t zangle; - fixed_t hdist; - fixed_t xdist; - fixed_t ydist; - fixed_t zdist; - - if (LUA_CallAction(A_DRAGONSEGMENT, actor)) - return; - - if (target == NULL || !target->health) - { - P_RemoveMobj(actor); - return; - } - - dist = P_AproxDistance(P_AproxDistance(actor->x - target->x, actor->y - target->y), actor->z - target->z); - radius = actor->radius + target->radius; - hangle = R_PointToAngle2(target->x, target->y, actor->x, actor->y); - zangle = R_PointToAngle2(0, target->z, dist, actor->z); - hdist = P_ReturnThrustX(target, zangle, radius); - xdist = P_ReturnThrustX(target, hangle, hdist); - ydist = P_ReturnThrustY(target, hangle, hdist); - zdist = P_ReturnThrustY(target, zangle, radius); - - actor->angle = hangle; - P_MoveOrigin(actor, target->x + xdist, target->y + ydist, target->z + zdist); -} - // Function: A_ChangeHeight // // Description: Changes the actor's height by var1 diff --git a/src/p_inter.c b/src/p_inter.c index b24946d7a..52172f940 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1456,19 +1456,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->fuse = target->info->damage; break; - case MT_BUGGLE: - if (inflictor && inflictor->player // did a player kill you? Spawn relative to the player so they're bound to get it - && P_AproxDistance(inflictor->x - target->x, inflictor->y - target->y) <= inflictor->radius + target->radius + FixedMul(8*FRACUNIT, inflictor->scale) // close enough? - && inflictor->z <= target->z + target->height + FixedMul(8*FRACUNIT, inflictor->scale) - && inflictor->z + inflictor->height >= target->z - FixedMul(8*FRACUNIT, inflictor->scale)) - mo = P_SpawnMobj(inflictor->x + inflictor->momx, inflictor->y + inflictor->momy, inflictor->z + (inflictor->height / 2) + inflictor->momz, MT_EXTRALARGEBUBBLE); - else - mo = P_SpawnMobj(target->x, target->y, target->z, MT_EXTRALARGEBUBBLE); - mo->destscale = target->scale; - P_SetScale(mo, mo->destscale); - P_SetMobjState(mo, mo->info->raisestate); - break; - case MT_YELLOWSHELL: P_SpawnMobjFromMobj(target, 0, 0, 0, MT_YELLOWSPRING); break; @@ -1506,17 +1493,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->flags = (target->flags|MF_NOCLIPHEIGHT) & ~MF_NOGRAVITY; break; - case MT_DRAGONBOMBER: - { - mobj_t *segment = target; - while (segment->tracer != NULL) - { - P_KillMobj(segment->tracer, NULL, NULL, DMG_NORMAL); - segment = segment->tracer; - } - break; - } - case MT_EGGMOBILE3: { mobj_t *mo2; @@ -1571,13 +1547,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget P_LinedefExecute(target->spawnpoint->angle, (source ? source : inflictor), target->subsector->sector); break; - case MT_SPINBOBERT: - if (target->hnext) - P_KillMobj(target->hnext, inflictor, source, damagetype); - if (target->hprev) - P_KillMobj(target->hprev, inflictor, source, damagetype); - break; - case MT_EGGTRAP: // Time for birdies! Yaaaaaaaay! target->fuse = TICRATE; diff --git a/src/p_mobj.c b/src/p_mobj.c index 5ae8430d6..e2042870b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1906,7 +1906,7 @@ void P_XYMovement(mobj_t *mo) if (mo->flags & MF_NOCLIPHEIGHT) return; // no frictions for objects that can pass through floors - if (mo->flags & MF_MISSILE || mo->flags2 & MF2_SKULLFLY || mo->type == MT_SHELL || mo->type == MT_VULTURE || mo->type == MT_PENGUINATOR) + if (mo->flags & MF_MISSILE || mo->flags2 & MF2_SKULLFLY || mo->type == MT_SHELL || mo->type == MT_VULTURE) return; // no friction for missiles ever if ((mo->type == MT_BIGTUMBLEWEED || mo->type == MT_LITTLETUMBLEWEED) @@ -6558,43 +6558,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->tracer->z += mobj->height; } break; - case MT_WAVINGFLAG1: - case MT_WAVINGFLAG2: - { - fixed_t base = (leveltime << (FRACBITS + 1)); - mobj_t *seg = mobj->tracer, *prev = mobj; - mobj->movedir = mobj->angle - + ((((FINESINE((FixedAngle(base << 1) >> ANGLETOFINESHIFT) & FINEMASK) - + FINESINE((FixedAngle(base << 4) >> ANGLETOFINESHIFT) & FINEMASK)) >> 1) - + FINESINE((FixedAngle(base*9) >> ANGLETOFINESHIFT) & FINEMASK) - + FINECOSINE(((FixedAngle(base*9)) >> ANGLETOFINESHIFT) & FINEMASK)) << 12); //*2^12 - while (seg) - { - seg->movedir = seg->angle; - seg->angle = prev->movedir; - P_UnsetThingPosition(seg); - seg->x = prev->x + P_ReturnThrustX(prev, prev->angle, prev->radius); - seg->y = prev->y + P_ReturnThrustY(prev, prev->angle, prev->radius); - seg->z = prev->z + prev->height - (seg->scale >> 1); - P_SetThingPosition(seg); - prev = seg; - seg = seg->tracer; - } - } - break; - case MT_SMASHINGSPIKEBALL: - mobj->momx = mobj->momy = 0; - if (mobj->state - states == S_SMASHSPIKE_FALL && P_IsObjectOnGround(mobj)) - { - P_SetMobjState(mobj, S_SMASHSPIKE_STOMP1); - S_StartSound(mobj, sfx_spsmsh); - } - else if (mobj->state - states == S_SMASHSPIKE_RISE2 && P_MobjFlip(mobj)*(mobj->z - mobj->movecount) >= 0) - { - mobj->momz = 0; - P_SetMobjState(mobj, S_SMASHSPIKE_FLOAT); - } - break; case MT_PLAYER: if (mobj->player) P_PlayerMobjThinker(mobj); @@ -8513,27 +8476,6 @@ static boolean P_FuseThink(mobj_t *mobj) P_SetMobjState(mobj, mobj->state->nextstate); mobj->fuse = mobj->args[0]; break; - case MT_LAVAFALL: - if (mobj->state - states == S_LAVAFALL_DORMANT) - { - mobj->fuse = 30; - P_SetMobjState(mobj, S_LAVAFALL_TELL); - S_StartSound(mobj, mobj->info->seesound); - } - else if (mobj->state - states == S_LAVAFALL_TELL) - { - mobj->fuse = 40; - P_SetMobjState(mobj, S_LAVAFALL_SHOOT); - S_StopSound(mobj); - S_StartSound(mobj, mobj->info->attacksound); - } - else - { - mobj->fuse = 30; - P_SetMobjState(mobj, S_LAVAFALL_DORMANT); - S_StopSound(mobj); - } - return false; case MT_RANDOMITEM: if (mobj->flags2 & MF2_DONTRESPAWN) { @@ -9381,20 +9323,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_BIGMINE: mobj->extravalue1 = FixedHypot(mobj->x, mobj->y)>>FRACBITS; break; - case MT_WAVINGFLAG1: - case MT_WAVINGFLAG2: - { - mobj_t *prev = mobj, *cur; - UINT8 i; - for (i = 0; i <= 16; i++) // probably should be < but staying authentic to the Lua version - { - cur = P_SpawnMobjFromMobj(mobj, 0, 0, 0, ((mobj->type == MT_WAVINGFLAG1) ? MT_WAVINGFLAGSEG1 : MT_WAVINGFLAGSEG2));; - P_SetTarget(&prev->tracer, cur); - cur->extravalue1 = i; - prev = cur; - } - } - break; case MT_EGGMOBILE2: // Special condition for the 2nd boss. mobj->watertop = mobj->info->speed; @@ -9429,23 +9357,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->movecount = P_RandomKey(13); mobj->color = FIRSTRAINBOWCOLOR + P_RandomKey(FIRSTSUPERCOLOR - FIRSTRAINBOWCOLOR); break; - case MT_HIVEELEMENTAL: - mobj->extravalue1 = 5; - break; - case MT_SMASHINGSPIKEBALL: - mobj->movecount = mobj->z; - break; - case MT_SPINBOBERT: - { - mobj_t *fire; - fire = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_SPINBOBERT_FIRE1); - P_SetTarget(&fire->target, mobj); - P_SetTarget(&mobj->hnext, fire); - fire = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_SPINBOBERT_FIRE2); - P_SetTarget(&fire->target, mobj); - P_SetTarget(&mobj->hprev, fire); - } - break; case MT_REDRING: // Make MT_REDRING red by default mobj->color = skincolor_redring; break; @@ -9483,26 +9394,12 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_FANG: sc = 4; break; - case MT_ROSY: - sc = 3; - break; case MT_CORK: mobj->flags2 |= MF2_SUPERFIRE; break; case MT_FBOMB: mobj->flags2 |= MF2_EXPLOSION; break; - case MT_TORCHFLOWER: - { - mobj_t *fire = P_SpawnMobjFromMobj(mobj, 0, 0, 46*FRACUNIT, MT_FLAME); - P_SetTarget(&mobj->target, fire); - break; - } - case MT_PYREFLY: - mobj->extravalue1 = (FixedHypot(mobj->x, mobj->y)/FRACUNIT) % 360; - mobj->extravalue2 = 0; - mobj->fuse = 100; - break; // SRB2Kart case MT_ITEMCAPSULE: { @@ -11552,35 +11449,6 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean P_SetTarget(&mobj->tracer, corona); } break; - case MT_FLAMEHOLDER: - if (!(mthing->args[0] & TMFH_NOFLAME)) // Spawn the fire - { - mobj_t *flame = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_FLAME); - P_SetTarget(&flame->target, mobj); - flame->flags2 |= MF2_BOSSNOTRAP; - if (mthing->args[0] & TMFH_CORONA) - { - mobj_t *corona = P_MakeSoftwareCorona(flame, 20); - P_SetScale(corona, (corona->destscale = flame->scale*3)); - P_SetTarget(&flame->tracer, corona); - } - } - break; - case MT_CANDLE: - case MT_CANDLEPRICKET: - if (mthing->args[0]) - P_MakeSoftwareCorona(mobj, ((mobj->type == MT_CANDLE) ? 42 : 176)); - break; - case MT_JACKO1: - case MT_JACKO2: - case MT_JACKO3: - if (!(mthing->args[0])) // take the torch out of the crafting recipe - { - mobj_t *overlay = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY); - P_SetTarget(&overlay->target, mobj); - P_SetMobjState(overlay, mobj->info->raisestate); - } - break; case MT_WATERDRIP: mobj->tics = 3*TICRATE + mthing->args[0]; break; @@ -11619,67 +11487,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean P_AddTubeWaypoint(sequence, id, mobj); break; } - case MT_DSZSTALAGMITE: - case MT_DSZ2STALAGMITE: - case MT_KELP: - if (mthing->args[0]) { // make mobj twice as big as normal - P_SetScale(mobj, 2*mobj->scale); // not 2*FRACUNIT in case of something like the old ERZ3 mode - mobj->destscale = mobj->scale; - } - break; - case MT_THZTREE: - { // Spawn the branches - angle_t mobjangle = FixedAngle((mthing->angle % 113) << FRACBITS); - P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_22h; - P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_157h; - P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270; - } break; - case MT_CEZPOLE1: - case MT_CEZPOLE2: - { // Spawn the banner - angle_t mobjangle = FixedAngle(mthing->angle << FRACBITS); - P_SpawnMobjFromMobj(mobj, - P_ReturnThrustX(mobj, mobjangle, 4 << FRACBITS), - P_ReturnThrustY(mobj, mobjangle, 4 << FRACBITS), - 0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2))->angle = mobjangle + ANGLE_90; - } - break; - case MT_HHZTREE_TOP: - { // Spawn the branches - angle_t mobjangle = FixedAngle(mthing->angle << FRACBITS) & (ANGLE_90 - 1); - mobj_t* leaf; -#define doleaf(x, y) \ - leaf = P_SpawnMobjFromMobj(mobj, x, y, 0, MT_HHZTREE_PART);\ - leaf->angle = mobjangle;\ - P_SetMobjState(leaf, leaf->info->seestate);\ - mobjangle += ANGLE_90 - doleaf(FRACUNIT, 0); - doleaf(0, FRACUNIT); - doleaf(-FRACUNIT, 0); - doleaf(0, -FRACUNIT); -#undef doleaf - } - break; - case MT_SMASHINGSPIKEBALL: - if (mthing->args[0] > 0) - mobj->tics += mthing->args[0]; - break; - case MT_BIGFERN: - { - angle_t angle = FixedAngle(mthing->angle << FRACBITS); - UINT8 j; - for (j = 0; j < 8; j++) - { - angle_t fa = (angle >> ANGLETOFINESHIFT) & FINEMASK; - fixed_t xoffs = FINECOSINE(fa); - fixed_t yoffs = FINESINE(fa); - mobj_t* leaf = P_SpawnMobjFromMobj(mobj, xoffs, yoffs, 0, MT_BIGFERNLEAF); - leaf->angle = angle; - angle += ANGLE_45; - } - break; - } case MT_REDBOOSTER: case MT_YELLOWBOOSTER: if (!P_SetupBooster(mthing, mobj, mobj->type == MT_REDBOOSTER)) From 32b9b82dc25fd8aff10cc594d571fb09bbbdd6ff Mon Sep 17 00:00:00 2001 From: NepDisk Date: Mon, 7 Apr 2025 17:20:26 -0400 Subject: [PATCH 03/12] Port v1 objects pt 3 --- src/info/actions.h | 18 - src/info/mobjs.h | 21 +- src/info/sprites.h | 13 +- src/info/states.h | 197 +-------- src/p_enemy.c | 1027 -------------------------------------------- src/p_inter.c | 23 - src/p_mobj.c | 44 +- src/p_setup.c | 10 - 8 files changed, 11 insertions(+), 1342 deletions(-) diff --git a/src/info/actions.h b/src/info/actions.h index 67e63d039..48cae73ca 100644 --- a/src/info/actions.h +++ b/src/info/actions.h @@ -191,35 +191,17 @@ _(A_FlickyHeightCheck, FLICKYHEIGHTCHECK) _(A_FlickyFlutter, FLICKYFLUTTER) _(A_FlameParticle, FLAMEPARTICLE) _(A_FadeOverlay, FADEOVERLAY) -_(A_Boss5Jump, BOSS5JUMP) -_(A_LightBeamReset, LIGHTBEAMRESET) _(A_MineExplode, MINEEXPLODE) _(A_MineRange, MINERANGE) _(A_ConnectToGround, CONNECTTOGROUND) _(A_SpawnParticleRelative, SPAWNPARTICLERELATIVE) _(A_ParticleSpawn, PARTICLESPAWN) _(A_MultiShotDist, MULTISHOTDIST) -_(A_WhoCaresIfYourSonIsABee,WHOCARESIFYOURSONISABEE) -_(A_ParentTriesToSleep, PARENTTRIESTOSLEEP) -_(A_CryingToMomma, CRYINGTOMOMMA) _(A_CheckFlags2, CHECKFLAGS2) -_(A_Boss5FindWaypoint, BOSS5FINDWAYPOINT) _(A_DoNPCSkid, DONPCSKID) _(A_DoNPCPain, DONPCPAIN) _(A_PrepareRepeat, PREPAREREPEAT) -_(A_Boss5ExtraRepeat, BOSS5EXTRAREPEAT) -_(A_Boss5Calm, BOSS5CALM) -_(A_Boss5CheckOnGround, BOSS5CHECKONGROUND) -_(A_Boss5CheckFalling, BOSS5CHECKFALLING) -_(A_Boss5PinchShot, BOSS5PINCHSHOT) -_(A_Boss5MakeItRain, BOSS5MAKEITRAIN) -_(A_Boss5MakeJunk, BOSS5MAKEJUNK) _(A_LookForBetter, LOOKFORBETTER) -_(A_Boss5BombExplode, BOSS5BOMBEXPLODE) -_(A_CanarivoreGas, CANARIVOREGAS) -_(A_KillSegments, KILLSEGMENTS) -_(A_SnapperSpawn, SNAPPERSPAWN) -_(A_SnapperThinker, SNAPPERTHINKER) _(A_ModuloToState, MODULOTOSTATE) _(A_ChangeHeight, CHANGEHEIGHT) diff --git a/src/info/mobjs.h b/src/info/mobjs.h index 79796d3df..156830034 100644 --- a/src/info/mobjs.h +++ b/src/info/mobjs.h @@ -21,12 +21,7 @@ _(DETON) // Deton _(SKIM) // Skim mine dropper _(TURRET) // Industrial Turret _(POPUPTURRET) // Pop-Up Turret -_(SPINCUSHION) // Spincushion -_(CRUSHSTACEAN) // Crushstacean -_(CRUSHCLAW) // Big meaty claw -_(CRUSHCHAIN) // Chain -_(BANPYURA) // Banpyura -_(BANPSPRING) // Banpyura spring +_(SHARP) // SHARP _(JETJAW) // Jet Jaw _(SNAILER) // Snailer _(VULTURE) // BASH @@ -37,8 +32,6 @@ _(FACESTABBER) // Castlebot Facestabber _(EGGGUARD) // Egg Guard _(EGGSHIELD) // Egg Guard's shield _(GSNAPPER) // Green Snapper -_(SNAPPER_LEG) // Green Snapper leg -_(SNAPPER_HEAD) // Green Snapper head _(MINUS) // Minus _(MINUSDIRT) // Minus dirt _(SPRINGSHELL) // Spring Shell @@ -80,18 +73,6 @@ _(JETFLAME) _(EGGROBO1) _(EGGROBO1JET) -// Boss 5 -_(FANG) -_(BROKENROBOT) -_(VWREF) -_(VWREB) -_(PROJECTORLIGHT) -_(FBOMB) -_(TNTDUST) // also used by barrel -_(FSGNA) -_(FSGNB) -_(FANGWAYPOINT) - // Black Eggman (Boss 7) _(BLACKEGGMAN) _(BLACKEGGMAN_HELPER) diff --git a/src/info/sprites.h b/src/info/sprites.h index 6726261f9..adf03818a 100644 --- a/src/info/sprites.h +++ b/src/info/sprites.h @@ -24,30 +24,19 @@ _(SKIM) // Skim mine dropper _(TRET) // Industrial Turret _(TURR) // Pop-Up Turret _(SHRP) // Sharp -//_(CRAB) // Crushstacean -_(CR2B) // Banpyura -_(CSPR) // Banpyura spring _(JJAW) // Jet Jaw _(SNLR) // Snailer _(VLTR) // BASH _(PNTY) // Pointy _(ARCH) // Robo-Hood _(CBFS) // Castlebot Facestabber -_(STAB) // Castlebot Facestabber spear aura _(SPSH) // Egg Guard _(ESHI) // Egg Guard's shield _(GSNP) // Green Snapper -_(GSNL) // Green Snapper leg -_(GSNH) // Green Snapper head _(MNUS) // Minus _(MNUD) // Minus dirt _(SSHL) // Spring Shell _(UNID) // Unidus -_(CANA) // Canarivore -_(CANG) // Canarivore gas -_(PYRE) // Pyre Fly -_(PTER) // Pterabyte -_(DRAB) // Dragonbomber // Generic Boss Items _(JETF) // Boss jet fumes @@ -588,7 +577,7 @@ _(CDMO) _(CDBU) // Daytona Speedway -_(DPIN) +_(PINE) // Egg Zeppelin _(PPLR) diff --git a/src/info/states.h b/src/info/states.h index b69dccda4..daa934a27 100644 --- a/src/info/states.h +++ b/src/info/states.h @@ -164,55 +164,14 @@ _(TURRETPOPDOWN6) _(TURRETPOPDOWN7) _(TURRETPOPDOWN8) -// Spincushion -_(SPINCUSHION_LOOK) -_(SPINCUSHION_CHASE1) -_(SPINCUSHION_CHASE2) -_(SPINCUSHION_CHASE3) -_(SPINCUSHION_CHASE4) -_(SPINCUSHION_AIM1) -_(SPINCUSHION_AIM2) -_(SPINCUSHION_AIM3) -_(SPINCUSHION_AIM4) -_(SPINCUSHION_AIM5) -_(SPINCUSHION_SPIN1) -_(SPINCUSHION_SPIN2) -_(SPINCUSHION_SPIN3) -_(SPINCUSHION_SPIN4) -_(SPINCUSHION_STOP1) -_(SPINCUSHION_STOP2) -_(SPINCUSHION_STOP3) -_(SPINCUSHION_STOP4) - -// Crushstacean -_(CRUSHSTACEAN_ROAM1) -_(CRUSHSTACEAN_ROAM2) -_(CRUSHSTACEAN_ROAM3) -_(CRUSHSTACEAN_ROAM4) -_(CRUSHSTACEAN_ROAMPAUSE) -_(CRUSHSTACEAN_PUNCH1) -_(CRUSHSTACEAN_PUNCH2) -_(CRUSHCLAW_AIM) -_(CRUSHCLAW_OUT) -_(CRUSHCLAW_STAY) -_(CRUSHCLAW_IN) -_(CRUSHCLAW_WAIT) -_(CRUSHCHAIN) - -// Banpyura -_(BANPYURA_ROAM1) -_(BANPYURA_ROAM2) -_(BANPYURA_ROAM3) -_(BANPYURA_ROAM4) -_(BANPYURA_ROAMPAUSE) -_(CDIAG1) -_(CDIAG2) -_(CDIAG3) -_(CDIAG4) -_(CDIAG5) -_(CDIAG6) -_(CDIAG7) -_(CDIAG8) +// Sharp +_(SHARP_ROAM1) +_(SHARP_ROAM2) +_(SHARP_AIM1) +_(SHARP_AIM2) +_(SHARP_AIM3) +_(SHARP_AIM4) +_(SHARP_SPIN) // Jet Jaw _(JETJAW_ROAM1) @@ -294,17 +253,11 @@ _(EGGGUARD_RUN4) _(EGGSHIELD) // Green Snapper -_(SNAPPER_SPAWN) -_(SNAPPER_SPAWN2) _(GSNAPPER_STND) _(GSNAPPER1) _(GSNAPPER2) _(GSNAPPER3) _(GSNAPPER4) -_(SNAPPER_XPLD) -_(SNAPPER_LEG) -_(SNAPPER_LEGRAISE) -_(SNAPPER_HEAD) // Minus _(MINUS_INIT) @@ -533,140 +486,6 @@ _(EGGROBO1_PISSED) // Boss 4 Spectator Eggrobo jet flame _(EGGROBOJET) -// Boss 5 -_(FANG_SETUP) -_(FANG_INTRO0) -_(FANG_INTRO1) -_(FANG_INTRO2) -_(FANG_INTRO3) -_(FANG_INTRO4) -_(FANG_INTRO5) -_(FANG_INTRO6) -_(FANG_INTRO7) -_(FANG_INTRO8) -_(FANG_INTRO9) -_(FANG_INTRO10) -_(FANG_INTRO11) -_(FANG_INTRO12) -_(FANG_CLONE1) -_(FANG_CLONE2) -_(FANG_CLONE3) -_(FANG_CLONE4) -_(FANG_IDLE0) -_(FANG_IDLE1) -_(FANG_IDLE2) -_(FANG_IDLE3) -_(FANG_IDLE4) -_(FANG_IDLE5) -_(FANG_IDLE6) -_(FANG_IDLE7) -_(FANG_IDLE8) -_(FANG_PAIN1) -_(FANG_PAIN2) -_(FANG_PATHINGSTART1) -_(FANG_PATHINGSTART2) -_(FANG_PATHING) -_(FANG_BOUNCE1) -_(FANG_BOUNCE2) -_(FANG_BOUNCE3) -_(FANG_BOUNCE4) -_(FANG_FALL1) -_(FANG_FALL2) -_(FANG_CHECKPATH1) -_(FANG_CHECKPATH2) -_(FANG_PATHINGCONT1) -_(FANG_PATHINGCONT2) -_(FANG_PATHINGCONT3) -_(FANG_SKID1) -_(FANG_SKID2) -_(FANG_SKID3) -_(FANG_CHOOSEATTACK) -_(FANG_FIRESTART1) -_(FANG_FIRESTART2) -_(FANG_FIRE1) -_(FANG_FIRE2) -_(FANG_FIRE3) -_(FANG_FIRE4) -_(FANG_FIREREPEAT) -_(FANG_LOBSHOT0) -_(FANG_LOBSHOT1) -_(FANG_LOBSHOT2) -_(FANG_WAIT1) -_(FANG_WAIT2) -_(FANG_WALLHIT) -_(FANG_PINCHPATHINGSTART1) -_(FANG_PINCHPATHINGSTART2) -_(FANG_PINCHPATHING) -_(FANG_PINCHBOUNCE0) -_(FANG_PINCHBOUNCE1) -_(FANG_PINCHBOUNCE2) -_(FANG_PINCHBOUNCE3) -_(FANG_PINCHBOUNCE4) -_(FANG_PINCHFALL0) -_(FANG_PINCHFALL1) -_(FANG_PINCHFALL2) -_(FANG_PINCHSKID1) -_(FANG_PINCHSKID2) -_(FANG_PINCHLOBSHOT0) -_(FANG_PINCHLOBSHOT1) -_(FANG_PINCHLOBSHOT2) -_(FANG_PINCHLOBSHOT3) -_(FANG_PINCHLOBSHOT4) -_(FANG_DIE1) -_(FANG_DIE2) -_(FANG_DIE3) -_(FANG_DIE4) -_(FANG_DIE5) -_(FANG_DIE6) -_(FANG_DIE7) -_(FANG_DIE8) -_(FANG_FLEEPATHING1) -_(FANG_FLEEPATHING2) -_(FANG_FLEEBOUNCE1) -_(FANG_FLEEBOUNCE2) -_(FANG_KO) - -_(BROKENROBOTRANDOM) -_(BROKENROBOTA) -_(BROKENROBOTB) -_(BROKENROBOTC) -_(BROKENROBOTD) -_(BROKENROBOTE) -_(BROKENROBOTF) - -_(ALART1) -_(ALART2) - -_(VWREF) -_(VWREB) - -_(PROJECTORLIGHT1) -_(PROJECTORLIGHT2) -_(PROJECTORLIGHT3) -_(PROJECTORLIGHT4) -_(PROJECTORLIGHT5) - -_(FBOMB1) -_(FBOMB2) -_(FBOMB_EXPL1) -_(FBOMB_EXPL2) -_(FBOMB_EXPL3) -_(FBOMB_EXPL4) -_(FBOMB_EXPL5) -_(FBOMB_EXPL6) -_(TNTDUST_1) -_(TNTDUST_2) -_(TNTDUST_3) -_(TNTDUST_4) -_(TNTDUST_5) -_(TNTDUST_6) -_(TNTDUST_7) -_(TNTDUST_8) -_(FSGNA) -_(FSGNB) -_(FSGNC) -_(FSGND) - // Black Eggman (Boss 7) _(BLACKEGG_STND) _(BLACKEGG_STND2) diff --git a/src/p_enemy.c b/src/p_enemy.c index 7d40a6cdb..9f9e2eefb 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -10237,122 +10237,6 @@ void A_FadeOverlay(mobj_t *actor) P_SetTarget(&actor->tracer, fade); } -// Function: A_Boss5Jump -// -// Description: Makes an object jump in an arc to land on their tracer precicely. -// Adapted from A_BrakLobShot, see there for explanation. -// -// var1 = unused -// var2 = unused -// -void A_Boss5Jump(mobj_t *actor) -{ - fixed_t v; // Velocity to jump at - fixed_t a1, a2, aToUse; // Velocity squared - fixed_t g; // Gravity - fixed_t x; // Horizontal difference - INT32 x_int; // x! But in integer form! - fixed_t y; // Vertical difference (yes that's normally z in SRB2 shut up) - INT32 y_int; // y! But in integer form! - INT32 intHypotenuse; // x^2 + y^2. Frequently overflows fixed point, hence why we need integers proper. - fixed_t fixedHypotenuse; // However, we can work around that and still get a fixed-point number. - angle_t theta; // Angle of attack - // INT32 locvar1 = var1; - // INT32 locvar2 = var2; - - if (LUA_CallAction(A_BOSS5JUMP, actor)) - return; - - if (!actor->tracer) - return; // Don't even bother if we've got nothing to aim at. - - // Look up actor's current gravity situation - g = FixedMul(gravity, P_GetSectorGravityFactor(actor->subsector->sector)); - - // Look up distance between actor and its tracer - x = FixedHypot(actor->tracer->x - actor->x, actor->tracer->y - actor->y); - // Look up height difference between actor and its tracer - y = actor->tracer->z - actor->z; - - // Get x^2 + y^2. Have to do it in a roundabout manner, because this overflows fixed_t way too easily otherwise. - x_int = x>>FRACBITS; - y_int = y>>FRACBITS; - intHypotenuse = (x_int*x_int) + (y_int*y_int); - fixedHypotenuse = FixedSqrt(intHypotenuse) *256; - - // a = g(y+/-sqrt(x^2+y^2)). a1 can be +, a2 can be -. - a1 = FixedMul(g,y+fixedHypotenuse); - a2 = FixedMul(g,y-fixedHypotenuse); - - // Determine which one isn't actually an imaginary number (or the smaller of the two, if both are real), and use that for v. - if (a1 < 0 || a2 < 0) - { - if (a1 < 0 && a2 < 0) - { - //Somehow, v^2 is negative in both cases. v is therefore imaginary and something is horribly wrong. Abort! - return; - } - // Just find which one's NOT negative, and use that - aToUse = max(a1,a2); - } - else - { - // Both are positive; use whichever's smaller so it can decay faster - aToUse = min(a1,a2); - } - v = FixedSqrt(aToUse); - // Okay, so we know the velocity. Let's actually find theta. - // We can cut the "+/- sqrt" part out entirely, since v was calculated specifically for it to equal zero. So: - //theta = tantoangle[FixedDiv(aToUse,FixedMul(g,x)) >> DBITS]; - theta = tantoangle[SlopeDiv(aToUse,FixedMul(g,x))]; - - // Okay, complicated math done. Let's make this object jump already. - A_FaceTracer(actor); - - if (actor->eflags & MFE_VERTICALFLIP) - actor->z--; - else - actor->z++; - - // Horizontal axes first. First parameter is initial horizontal impulse, second is to correct its angle. - fixedHypotenuse = FixedMul(v, FINECOSINE(theta >> ANGLETOFINESHIFT)); // variable reuse - actor->momx = FixedMul(fixedHypotenuse, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)); - actor->momy = FixedMul(fixedHypotenuse, FINESINE(actor->angle >> ANGLETOFINESHIFT)); - // Then the vertical axis. No angle-correction needed here. - actor->momz = FixedMul(v, FINESINE(theta >> ANGLETOFINESHIFT)); - // I hope that's all that's needed, ugh -} - -// Function: A_LightBeamReset -// Description: Resets momentum and position for DSZ's projecting light beams -// -// var1 = unused -// var2 = unused -// -void A_LightBeamReset(mobj_t *actor) -{ - // INT32 locvar1 = var1; - // INT32 locvar2 = var2; - - if (LUA_CallAction(A_LIGHTBEAMRESET, actor)) - return; - - actor->destscale = FRACUNIT + P_SignedRandom()*FRACUNIT/256; - P_SetScale(actor, actor->destscale); - - if (!actor->spawnpoint) - return; // this can't work properly welp - - actor->momx = -(P_SignedRandom()*FINESINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/128; - actor->momy = (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/128; - actor->momz = (P_SignedRandom()*FRACUNIT)/128; - - P_SetOrigin(actor, - actor->spawnpoint->x*FRACUNIT - (P_SignedRandom()*FINESINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2, - actor->spawnpoint->y*FRACUNIT + (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2, - actor->spawnpoint->z*FRACUNIT + (P_SignedRandom()*FRACUNIT)/2); -} - // Function: A_MineExplode // Description: Handles the explosion of a DSZ mine. // @@ -10596,105 +10480,6 @@ void A_MultiShotDist(mobj_t *actor) A_MultiShot(actor); } -// Function: A_WhoCaresIfYourSonIsABee -// -// Description: Makes a child object, storing the number of created children in the parent's extravalue1. -// -// var1 = mobjtype of child -// var2 >> 16 = mobjtype of child -// var2 & 65535 = vertical momentum -// var2: -// var2 >> 16 = forward offset -// var2 & 65535 = vertical offset -// -void A_WhoCaresIfYourSonIsABee(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - fixed_t foffsetx; - fixed_t foffsety; - mobj_t *son; - - if (LUA_CallAction(A_WHOCARESIFYOURSONISABEE, actor)) - return; - - A_FaceTarget(actor); - - if (actor->extravalue1) - actor->extravalue1--; - - if (actor->info->attacksound) - S_StartSound(actor, actor->info->attacksound); - - foffsetx = P_ReturnThrustX(actor, actor->angle, FixedMul((locvar2 >> 16)*FRACUNIT, actor->scale)); - foffsety = P_ReturnThrustY(actor, actor->angle, FixedMul((locvar2 >> 16)*FRACUNIT, actor->scale)); - - if (!(son = P_SpawnMobjFromMobj(actor, foffsetx, foffsety, (locvar2&65535)*FRACUNIT, (mobjtype_t)(locvar1 >> 16)))) - return; - - P_SetObjectMomZ(son, (locvar1 & 65535)<tracer, actor); - P_SetTarget(&son->target, actor->target); -} - -// Function: A_ParentTriesToSleep -// -// Description: If extravalue1 is less than or equal to var1, go to var2. -// -// var1 = state to go to when extravalue1 -// var2 = unused -// -void A_ParentTriesToSleep(mobj_t *actor) -{ - INT32 locvar1 = var1; - - if (LUA_CallAction(A_PARENTTRIESTOSLEEP, actor)) - return; - - if (actor->extravalue1) - { - if (actor->info->seesound) - S_StartSound(actor, actor->info->seesound); - actor->reactiontime = 0; - P_SetMobjState(actor, locvar1); - } - else if (!actor->reactiontime) - { - actor->reactiontime = 1; - if (actor->info->activesound) // more like INactivesound doy hoy hoy - S_StartSound(actor, actor->info->activesound); - } -} - - -// Function: A_CryingToMomma -// -// Description: If you're a child, let your parent know something's happened to you through extravalue1. Also, prepare to die. -// -// var1 = unused -// var2 = unused -// -void A_CryingToMomma(mobj_t *actor) -{ - if (LUA_CallAction(A_CRYINGTOMOMMA, actor)) - return; - - if (actor->tracer) - actor->tracer->extravalue1++; - - actor->momx = actor->momy = actor->momz = 0; - - P_UnsetThingPosition(actor); - if (sector_list) - { - P_DelSeclist(sector_list); - sector_list = NULL; - } - actor->flags = MF_NOBLOCKMAP|MF_NOCLIPTHING; - P_SetThingPosition(actor); -} - // Function: A_CheckFlags2 // // Description: If actor->flags2 & var1, goto var2. @@ -10714,196 +10499,6 @@ void A_CheckFlags2(mobj_t *actor) P_SetMobjState(actor, (statenum_t)locvar2); } -// Function: A_Boss5FindWaypoint -// -// Description: Finds the next waypoint in sequence and sets it as its tracer. -// -// var1 = if 1, always go to ambush-marked waypoint. if 2, go to MT_BOSSFLYPOINT. -// var2 = unused -// -void A_Boss5FindWaypoint(mobj_t *actor) -{ - INT32 locvar1 = var1; - boolean avoidcenter; - INT32 i; - INT32 bossid = actor->args[0]; - - if (LUA_CallAction(A_BOSS5FINDWAYPOINT, actor)) - return; - - avoidcenter = !actor->tracer || (actor->health == actor->info->damage+1); - - if (locvar1 == 2) // look for the boss flypoint - { - P_SetTarget(&actor->tracer, P_FindBossFlyPoint(actor, bossid)); - - if (!actor->tracer) - return; // no boss flypoints found - } - else if (locvar1 == 1) // always go to ambush-marked waypoint - { - boolean found = false; - - if (avoidcenter) - goto nowaypoints; // if we can't go the center, why on earth are we doing this? - - TAG_ITER_THINGS(bossid, i) - { - if (!mapthings[i].mobj) - continue; - if (mapthings[i].mobj->type != MT_FANGWAYPOINT) - continue; - if (!(mapthings[i].args[0])) - continue; - - P_SetTarget(&actor->tracer, mapthings[i].mobj); - found = true; - break; - } - - if (!found) - goto nowaypoints; - } - else // locvar1 == 0 - { - fixed_t hackoffset = P_MobjFlip(actor)*56*FRACUNIT; - INT32 numfangwaypoints = 0; - mobj_t **fangwaypoints; - INT32 key; - - actor->z += hackoffset; - - // first, count how many waypoints we have - TAG_ITER_THINGS(bossid, i) - { - if (!mapthings[i].mobj) - continue; - if (mapthings[i].mobj->type != MT_FANGWAYPOINT) - continue; - if (actor->tracer == mapthings[i].mobj) // this was your tracer last time - continue; - if (mapthings[i].args[0]) - { - if (avoidcenter) - continue; - } - else if (mapthings[i].mobj->reactiontime > 0) - continue; - if (!P_CheckSight(actor, mapthings[i].mobj)) - continue; - numfangwaypoints++; - } - - // players also count as waypoints apparently - if (actor->extravalue2 > 1) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - if (!players[i].mo) - continue; - if (players[i].spectator) - continue; - if (players[i].mo->health <= 0) - continue; - if (players[i].flashing) - continue; - if (actor->tracer == players[i].mo) // this was your tracer last time - continue; - if (!P_CheckSight(actor, players[i].mo)) - continue; - numfangwaypoints++; - } - } - - if (!numfangwaypoints) - { - // restore z position - actor->z -= hackoffset; - goto nowaypoints; // no waypoints :( - } - - // allocate the table and reset count to zero - fangwaypoints = Z_Calloc(sizeof(*tubewaypoints)*numfangwaypoints, PU_STATIC, NULL); - numfangwaypoints = 0; - - // now find them again and add them to the table! - TAG_ITER_THINGS(bossid, i) - { - if (!mapthings[i].mobj) - continue; - if (mapthings[i].mobj->type != MT_FANGWAYPOINT) - continue; - if (actor->tracer == mapthings[i].mobj) // this was your tracer last time - continue; - if (mapthings[i].args[0]) - { - if (avoidcenter) - continue; - } - else if (mapthings[i].mobj->reactiontime > 0) - { - mapthings[i].mobj->reactiontime--; - continue; - } - if (!P_CheckSight(actor, mapthings[i].mobj)) - continue; - fangwaypoints[numfangwaypoints++] = mapthings[i].mobj; - } - - if (actor->extravalue2 > 1) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - if (!players[i].mo) - continue; - if (players[i].spectator) - continue; - if (players[i].mo->health <= 0) - continue; - if (players[i].flashing) - continue; - if (actor->tracer == players[i].mo) // this was your tracer last time - continue; - if (!P_CheckSight(actor, players[i].mo)) - continue; - fangwaypoints[numfangwaypoints++] = players[i].mo; - } - } - - // restore z position - actor->z -= hackoffset; - - if (!numfangwaypoints) - { - Z_Free(fangwaypoints); // free table - goto nowaypoints; // ??? - } - - key = P_RandomKey(numfangwaypoints); - - P_SetTarget(&actor->tracer, fangwaypoints[key]); - if (actor->tracer->type == MT_FANGWAYPOINT) - actor->tracer->reactiontime = numfangwaypoints/4; // Monster Iestyn: is this how it should be? I count center waypoints as waypoints unlike the original Lua script - Z_Free(fangwaypoints); // free table - } - - // now face the tracer you just set! - A_FaceTracer(actor); - return; - -nowaypoints: - // no waypoints at all, guess the mobj has to disappear - if (actor->health) - P_KillMobj(actor, NULL, NULL, DMG_NORMAL); - else - P_RemoveMobj(actor); - return; -} - // Function: A_DoNPCSkid // // Description: Something that looks like a player is skidding. @@ -11027,281 +10622,6 @@ void A_PrepareRepeat(mobj_t *actor) actor->extravalue2 = locvar1; } -// Function: A_Boss5ExtraRepeat -// -// Description: Simple way to prepare A_Repeat. -// -// var1 = maximum value to setextravalue2 to (normally) -// var2 = pinch annoyance -// -void A_Boss5ExtraRepeat(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - INT32 calc; - INT32 locspawn; - INT32 lochealth; - - if (LUA_CallAction(A_BOSS5EXTRAREPEAT, actor)) - return; - - if (actor->extravalue2 > 0 && !(actor->flags2 & MF2_FRET)) - return; - - locspawn = actor->info->spawnhealth - actor->info->damage; - lochealth = actor->health - actor->info->damage; - - if (locspawn <= 0 || lochealth <= 0) - calc = locvar1; - else - calc = (locvar1*(locspawn - lochealth))/locspawn; - - if (calc > 2) - actor->extravalue2 = 1 + calc/2 + P_RandomKey(calc/2); - else - actor->extravalue2 = 1 + calc; - - if (lochealth <= 0) - actor->extravalue2 += locvar2; -} - -// Function: A_Boss5Calm -// -// Description: Simple way to disable MF2_FRET (and enable MF_SHOOTABLE the first time it's called) -// -// var1 = unused -// var2 = unused -// -void A_Boss5Calm(mobj_t *actor) -{ - if (LUA_CallAction(A_BOSS5CALM, actor)) - return; - - actor->flags |= MF_SHOOTABLE; - actor->flags2 &= ~MF2_FRET; -} - -// Function: A_Boss5CheckOnGround -// -// Description: Ground checker. -// -// var1 = state to change to upon hitting ground. -// var2 = state to change to upon hitting ground if health == pinchhealth, assuming it exists -// -void A_Boss5CheckOnGround(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - - if (LUA_CallAction(A_BOSS5CHECKONGROUND, actor)) - return; - - if ((!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz) - || (actor->eflags & MFE_VERTICALFLIP && actor->z + actor->height >= actor->ceilingz)) - { - if (locvar2 && (!actor->health || (actor->health == actor->info->damage && !(actor->flags2 & MF2_STRONGBOX)))) - P_SetMobjState(actor, locvar2); - else - P_SetMobjState(actor, locvar1); - } - - if (actor->tracer && P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y) < 2*actor->radius) - { - actor->momx = (4*actor->momx)/5; - actor->momy = (4*actor->momy)/5; - } -} - -// Function: A_Boss5CheckFalling -// -// Description: Falling checker. -// -// var1 = state to change to when hitting ground. -// var2 = state to change to when falling. -// -void A_Boss5CheckFalling(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - - if (LUA_CallAction(A_BOSS5CHECKFALLING, actor)) - return; - - if (actor->health && actor->extravalue2 > 1) - { - var1 = locvar1; - var2 = 0; - A_Boss5CheckOnGround(actor); - return; - } - - if (P_MobjFlip(actor)*actor->momz <= 0) - P_SetMobjState(actor, locvar2); -} - -// Function: A_Boss5PinchShot -// -// Description: Fires a missile directly upwards if in pinch. -// -// var1 = object # to shoot -// var2 = height offset (from default of +48 FU) -// -void A_Boss5PinchShot(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - fixed_t zoffset; - mobj_t *missile; - - if (LUA_CallAction(A_BOSS5PINCHSHOT, actor)) - return; - - if (actor->health > actor->info->damage) - return; - - if (actor->eflags & MFE_VERTICALFLIP) - zoffset = actor->z + actor->height - FixedMul((48 + locvar2)*FRACUNIT, actor->scale); - else - zoffset = actor->z + FixedMul((48 + locvar2)*FRACUNIT, actor->scale); - - missile = P_SpawnPointMissile(actor, actor->x, actor->y, zoffset, locvar1, - actor->x, actor->y, zoffset); - - if (!missile) - return; - - missile->momx = missile->momy = 0; - missile->momz = P_MobjFlip(actor)*missile->info->speed/2; -} - -// Function: A_Boss5MakeItRain -// -// Description: Pinch crisis. -// -// var1 = object # to shoot -// var2 = height offset (from default of +48 FU) -// -void A_Boss5MakeItRain(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - INT32 offset = (48 + locvar2)<<16; // upper 16 bits, not fixed_t! - INT32 i; - - if (LUA_CallAction(A_BOSS5MAKEITRAIN, actor)) - return; - - actor->flags2 |= MF2_STRONGBOX; - - var1 = locvar1; - var2 = offset + 90; - A_TrapShot(actor); - - for (i = 0; i < 8; i++) - { - actor->angle += ANGLE_45; - - var1 = locvar1; - var2 = offset + (i & 1) ? 80 : 85; - A_TrapShot(actor); - } - - actor->extravalue2 = 0; -} - -// Function: A_Boss5MakeJunk -// -// Description: Make a mess. -// -// var1 = state # to set on MT_BROKENROBOT (if 0 do nothing, if -1 go to if colorized) -// var2 = mode (-1 = spin, 0 = make 1, & 1 make 8, & 2 alart mode) -// -void A_Boss5MakeJunk(mobj_t *actor) -{ - INT32 locvar1 = var1; - INT32 locvar2 = var2; - mobj_t *broked = NULL; - angle_t ang; - INT32 i = ((locvar2 & 1) ? 8 : 1); - - if (LUA_CallAction(A_BOSS5MAKEJUNK, actor)) - return; - - if (locvar1 < 0 && (actor->flags2 & MF2_SLIDEPUSH)) // this entire action is a hack, don't judge me - { - INT32 curextravalue2 = actor->extravalue2; - P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_PROJECTORLIGHT); - actor->z += P_MobjFlip(actor)*actor->height; - actor->flags |= MF_NOGRAVITY; - S_StartSound(actor, sfx_vwre); - actor->extravalue2 = 49; - P_SetMobjState(actor, -locvar1); - actor->extravalue2 = curextravalue2; - actor->angle -= FixedAngle((49*45)<extravalue2)/50; - if (trans > 9) - trans = 9; - if (trans < 0) - trans = 0; - if (!(actor->extravalue2 & 1)) - { - if (actor->extravalue2 > 10) - { - mobj_t *front = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_VWREF); - broked = P_SpawnMobjFromMobj(front, 0, 0, 0, MT_VWREB); - front->z = broked->z = front->z - broked->height; - P_SetObjectMomZ(front, (4<momz = front->momz; - broked->fuse = front->fuse = (actor->height+(2*front->height))/front->momz; - } - if (!(actor->colorized = !actor->colorized)) - actor->frame |= FF_FULLBRIGHT; - } - actor->angle += ANGLE_45; - actor->frame = (actor->frame & ~FF_TRANSMASK)|(trans<fuse = TICRATE; - else - broked->fuse = (((locvar2 & 1) ? 4 : 2)*TICRATE)/3; - broked->angle = ang; - P_InstaThrust(broked, ang, ((locvar2 & 2) ? 8 : 5)*actor->scale); - P_SetObjectMomZ(broked, (((locvar2) ? 4 : 0) + P_RandomRange(2, 5))< 0) - P_SetMobjState(broked, locvar1); - if (!P_MobjWasRemoved(broked)) - P_MoveOrigin(broked, broked->x + broked->momx, broked->y + broked->momy, broked->z); - ang += ANGLE_45; - } - - if (locvar2 & 2) - { - broked = P_SpawnMobjFromMobj(actor, 0, 0, 64<fuse = states[S_FANG_INTRO12].tics+10; - P_SetMobjState(broked, S_ALART1); - } - else if (locvar2 & 1) - { - broked->z += broked->momz; - S_StartSound(actor, sfx_s3kccs); - actor->flags &= ~MF_NOCLIPTHING; - } - else - S_StartSound(actor, sfx_s3kd3s); -} - // Function: A_LookForBetter // // Description: A_Look, except it finds a better target in multiplayer, and doesn't lose the target in singleplayer. @@ -11321,353 +10641,6 @@ void A_LookForBetter(mobj_t *actor) A_FaceTarget(actor); } -/* * Spawns a dust ring. - * The dust ring behaves slightly randomly so it doesn't look too uniform. - * - * \param mobjtype Thing type to make a ring of. - * \param div Amount of things to spawn on the ring. - * \param x Center X coordinates. - * \param y Center Y coordinates. - * \param z Center Z coordinates. - * \param radius Radius. - * \param speed Additional thrust on particles. - * \param initscale Initial scale when spawning. - * \param scale "Default" scale. - */ -static void P_DustRing(mobjtype_t mobjtype, UINT32 div, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t speed, fixed_t initscale, fixed_t scale) -{ - angle_t ang = FixedAngle(FixedDiv(360*FRACUNIT, div*FRACUNIT)); //(ANGLE_180/div)*2; - UINT32 i; - - // it turned out the radius was effectively nullified thanks to errors in the original script - // BUT people preferred how it looked before I "fixed" it, so I got rid of the radius calculations altogether - // this was a bit of a mess to sort out, but at least it's probably somewhat fine now? - // -- Monster Iestyn (21/05/19) - (void)radius; - - for (i = 0; i < div; i++) - { - mobj_t *dust = P_SpawnMobj( - x, //+ FixedMul(radius, FINECOSINE((ang*i) >> ANGLETOFINESHIFT)), - y, //+ FixedMul(radius, FINESINE((ang*i) >> ANGLETOFINESHIFT)), - z, - mobjtype - ); - - dust->angle = ang*i + ANGLE_90; - P_SetScale(dust, FixedMul(initscale, scale)); - dust->destscale = FixedMul(4*FRACUNIT + P_RandomFixed(), scale); - dust->scalespeed = scale/24; - P_Thrust(dust, ang*i, speed + FixedMul(P_RandomFixed(), scale)); - dust->momz = P_SignedRandom()*scale/64; - } -} - -// Function: A_Boss5BombExplode -// -// Description: Boss 5's bomb exploding. -// -// var1 = Thing type to spawn as dust -// var2 = unused -// -void A_Boss5BombExplode(mobj_t *actor) -{ - INT32 locvar1 = var1; - - if (LUA_CallAction(A_BOSS5BOMBEXPLODE, actor)) - return; - - // The original Lua script did not use |= to add flags but just set these flags exactly apparently? - // (I may modify this later) - // -- Monster Iestyn (21/05/19) - actor->flags = MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP; - actor->flags2 = MF2_EXPLOSION; - - if (actor->target) - P_RadiusAttack(actor, actor->target, 7*actor->radius, 0, true); - - P_DustRing(locvar1, 4, actor->x, actor->y, actor->z+actor->height, 2*actor->radius, 0, FRACUNIT, actor->scale); - P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 3*actor->radius, FRACUNIT, FRACUNIT, actor->scale); - //P_StartQuake(9*FRACUNIT, TICRATE/6, {actor->x, actor->y, actor->z}, 20*actor->radius); - // the above does not exist, so we set the quake values directly instead - quake.intensity = 9*FRACUNIT; - quake.time = TICRATE/6; - // the following quake values have no effect atm? ah well, may as well set them anyway - { - mappoint_t q_epicenter = {actor->x, actor->y, actor->z}; - quake.epicenter = &q_epicenter; - } - quake.radius = 20*actor->radius; -} - -// Function: A_CanarivoreGas -// -// Description: Releases gas clouds. Used by the Canarivore. -// -// var1 = Mobj type. -// var2 = Unused -// -void A_CanarivoreGas(mobj_t *actor) -{ - INT32 locvar1 = var1; - - if (LUA_CallAction(A_CANARIVOREGAS, actor)) - return; - - P_DustRing(locvar1, 4, actor->x, actor->y, actor->z + actor->height / 5, 18, 0, FRACUNIT/10, actor->scale); - P_DustRing(locvar1, 6, actor->x, actor->y, actor->z + actor->height / 5, 28, FRACUNIT, FRACUNIT/10, actor->scale); -} - -// -// Function: A_KillSegments -// -// Description: Causes segments attached via tracer chain to be killed. -// -// var1 = Fuse (if 0, default to TICRATE/2). -// var2 = Unused -// -void A_KillSegments(mobj_t *actor) -{ - INT32 locvar1 = var1; - mobj_t *seg = actor->tracer; - INT32 fuse = locvar1 ? locvar1 : TICRATE/2; - - if (LUA_CallAction(A_KILLSEGMENTS, actor)) - return; - - while (seg) - { - mobj_t *kseg = seg; - seg = seg->tracer; - - kseg->flags = MF_NOBLOCKMAP; - kseg->flags2 = 0; - kseg->fuse = fuse; - P_Thrust(kseg, R_PointToAngle2(actor->x, actor->y, kseg->x, kseg->y), 3*actor->scale); - kseg->momz = 3*actor->scale; - } -} - -static void P_SnapperLegPlace(mobj_t *mo) -{ - mobj_t *seg = mo->tracer; - angle_t a = mo->angle; - angle_t fa = (a >> ANGLETOFINESHIFT) & FINEMASK; - fixed_t c = FINECOSINE(fa); - fixed_t s = FINESINE(fa); - fixed_t x, y; - INT32 o1, o2; - INT32 woffset = mo->extravalue1; - INT32 side = mo->extravalue2; - INT32 alt; - - // Move head first. - fixed_t rad = mo->radius; - INT32 necklen = (32*(mo->info->reactiontime - mo->reactiontime))/mo->info->reactiontime; // Not in FU - - seg->z = mo->z + ((mo->eflags & MFE_VERTICALFLIP) ? (((mo->height<<1)/3) - seg->height) : mo->height/3); - P_TryMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, true, NULL); - seg->angle = a; - - // Move as many legs as available. - seg = seg->tracer; - do - { - o1 = seg->extravalue1; - o2 = seg->extravalue2; - alt = seg->cusval; - - if (alt == 1) - o2 += woffset; - else - o2 -= woffset; - - if (alt != side) - { - x = c*o2 + s*o1; - y = s*o2 - c*o1; - seg->z = mo->z + (((mo->eflags & MFE_VERTICALFLIP) ? (mo->height - seg->height) : 0)); - P_TryMove(seg, mo->x + x, mo->y + y, true, NULL); - P_SetMobjState(seg, seg->info->raisestate); - } - else - P_SetMobjState(seg, seg->info->spawnstate); - - seg->angle = R_PointToAngle2(mo->x, mo->y, seg->x, seg->y); - - seg = seg->tracer; - } while (seg); -} - -// -// Function: A_SnapperSpawn -// -// Description: Sets up Green Snapper legs and head. -// -// var1 = Leg mobj type. -// var2 = Head mobj type. -// -void A_SnapperSpawn(mobj_t *actor) -{ - mobjtype_t legtype = (mobjtype_t)var1; - mobjtype_t headtype = (mobjtype_t)var2; - mobj_t *ptr = actor; - INT32 i; - mobj_t *seg; - - if (LUA_CallAction(A_SNAPPERSPAWN, actor)) - return; - - // It spawns 1 head. - seg = P_SpawnMobjFromMobj(actor, 0, 0, 0, headtype); - P_SetTarget(&ptr->tracer, seg); - ptr = seg; - - // It spawns 4 legs which will be handled in the thinker function. - for (i = 1; i <= 4; i++) - { - seg = P_SpawnMobjFromMobj(actor, 0, 0, 0, legtype); - P_SetTarget(&ptr->tracer, seg); - ptr = seg; - - // The legs' base offsets are stored as extravalues, as relative coordinates in xy space. - seg->extravalue1 = 28; - seg->extravalue2 = 28; - if (i % 2) - seg->extravalue1 = -seg->extravalue1; - - if ((i/2) % 2) - seg->extravalue2 = -seg->extravalue2; - - // Alternating motion stuff. - seg->cusval = ((i + 1)/2) % 2; - } - - actor->extravalue1 = 0; - actor->extravalue2 = 0; - P_SnapperLegPlace(actor); -} - -// -// Function: A_SnapperThinker -// -// Description: Thinker for Green Snapper. -// -// var1 = Unused -// var2 = Unused -// -void A_SnapperThinker(mobj_t *actor) -{ - fixed_t x0 = actor->x; - fixed_t y0 = actor->y; - fixed_t xs, ys; - fixed_t x1, y1; - fixed_t dist; - boolean chasing; - - if (LUA_CallAction(A_SNAPPERTHINKER, actor)) - return; - - // We make a check just in case there's no spawnpoint. - if (actor->spawnpoint) - { - xs = actor->spawnpoint->x*FRACUNIT; - ys = actor->spawnpoint->y*FRACUNIT; - } - else - { - xs = x0; - ys = y0; - } - - // Look for nearby, valid players to chase angrily at. - if ((actor->target || P_LookForPlayers(actor, true, false, 1024*FRACUNIT)) - && P_AproxDistance(actor->target->x - xs, actor->target->y - ys) < 2048*FRACUNIT - && abs(actor->target->z - actor->z) < 80*FRACUNIT - && P_CheckSight(actor, actor->target)) - { - chasing = true; - x1 = actor->target->x; - y1 = actor->target->y; - } - else - { - chasing = false; - x1 = xs; - y1 = ys; - } - - dist = P_AproxDistance(x1 - x0, y1 - y0); - - // The snapper either chases what it considers to be a nearby player, or instead decides to go back to its spawnpoint. - if (chasing || dist > 32*FRACUNIT) - { - INT32 speed = actor->info->speed + actor->info->reactiontime - actor->reactiontime; - - angle_t maxang = FixedAngle(speed*FRACUNIT/2); - angle_t ang = actor->angle; - angle_t realang = R_PointToAngle2(x0, y0, x1, y1); - angle_t dif = realang - ang; - angle_t fa; - fixed_t c, s; - - if (dif < ANGLE_180 && dif > maxang) - actor->angle += maxang; - else if (dif >= ANGLE_180 && dif < InvAngle(maxang)) - actor->angle -= maxang; - else - actor->angle = realang; - - fa = (actor->angle >> ANGLETOFINESHIFT) & FINEMASK; - c = FINECOSINE(fa); - s = FINESINE(fa); - - P_TryMove(actor, actor->x + c*speed, actor->y + s*speed, false, NULL); - - // The snapper spawns dust if going fast! - if (actor->reactiontime < 4) - { - mobj_t *dust = P_SpawnMobj(x0, y0, actor->z, MT_SPINDUST); - P_Thrust(dust, ang + ANGLE_180 + FixedAngle(P_RandomRange(-20, 20)*FRACUNIT), speed*FRACUNIT); - } - - if (actor->extravalue2 == 0) - { - if (actor->extravalue1 > 16) - { - A_PlayActiveSound(actor); - actor->extravalue2 = 1; - - // If the snapper is chasing, accelerate; otherwise, decelerate. - if (chasing) - actor->reactiontime = max(0, actor->reactiontime - 1); - else - actor->reactiontime = min(actor->info->reactiontime, actor->reactiontime + 1); - } - else - actor->extravalue1 += speed; - } - else - { - if (actor->extravalue1 < -16) - { - A_PlayActiveSound(actor); - actor->extravalue2 = 0; - - // If the snapper is chasing, accelerate; otherwise, decelerate. - if (chasing) - actor->reactiontime = max(0, actor->reactiontime - 1); - else - actor->reactiontime = min(actor->info->reactiontime, actor->reactiontime + 1); - } - else - actor->extravalue1 -= speed; - } - } - - P_SnapperLegPlace(actor); -} - // Function: A_ModuloToState // // Description: Modulo operation to state diff --git a/src/p_inter.c b/src/p_inter.c index 52172f940..3b4b14a57 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1464,29 +1464,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->momx = target->momy = target->momz = 0; break; - case MT_CRUSHSTACEAN: - if (target->tracer) - { - mobj_t *chain = target->tracer->target, *chainnext; - while (chain) - { - chainnext = chain->target; - P_RemoveMobj(chain); - chain = chainnext; - } - S_StopSound(target->tracer); - P_KillMobj(target->tracer, inflictor, source, damagetype); - } - break; - - case MT_BANPYURA: - if (target->tracer) - { - S_StopSound(target->tracer); - P_KillMobj(target->tracer, inflictor, source, damagetype); - } - break; - case MT_EGGSHIELD: P_SetObjectMomZ(target, 4*target->scale, false); P_InstaThrust(target, target->angle, 3*target->scale); diff --git a/src/p_mobj.c b/src/p_mobj.c index e2042870b..e8df336f2 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5657,9 +5657,8 @@ static void P_MobjSceneryThink(mobj_t *mobj) case MT_ROCKCRUMBLE16: case MT_WOODDEBRIS: case MT_BRICKDEBRIS: - case MT_BROKENROBOT: if (mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height) - && mobj->state != &states[mobj->info->deathstate]) + && mobj->state != &states[mobj->info->deathstate]) { P_SetMobjState(mobj, mobj->info->deathstate); return; @@ -5669,10 +5668,6 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (!P_ParticleGenSceneryThink(mobj)) return; break; - case MT_FSGNA: - if (mobj->movedir) - mobj->angle += mobj->movedir; - break; case MT_ORBINAUT_SHIELD: // Kart orbit/trail items case MT_JAWZ_SHIELD: case MT_BANANA_SHIELD: @@ -6231,16 +6226,6 @@ static void P_MobjSceneryThink(mobj_t *mobj) break; } - case MT_VWREF: - case MT_VWREB: - { - INT32 strength; - ++mobj->movedir; - mobj->frame &= ~FF_TRANSMASK; - strength = min(mobj->fuse, (INT32)mobj->movedir)*3; - if (strength < 10) - mobj->frame |= ((10 - strength) << (FF_TRANSSHIFT)); - } /* FALLTHRU */ default: if (mobj->fuse) @@ -8450,9 +8435,6 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s static boolean P_FuseThink(mobj_t *mobj) { - if (mobj->type == MT_SNAPPER_HEAD || mobj->type == MT_SNAPPER_LEG) - mobj->renderflags ^= RF_DONTDRAW; - if (mobj->fuse <= TICRATE && (mobj->type == MT_RANDOMITEM || mobj->type == MT_EGGMANITEM || mobj->type == MT_FALLINGROCK)) mobj->renderflags ^= RF_DONTDRAW; @@ -9302,24 +9284,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) } } break; - case MT_CRUSHSTACEAN: - { - mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_CRUSHCLAW); - bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270); - P_SetTarget(&mobj->tracer, bigmeatyclaw); - P_SetTarget(&bigmeatyclaw->tracer, mobj); - mobj->reactiontime >>= 1; - } - break; - case MT_BANPYURA: - { - mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BANPSPRING); - bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270); - P_SetTarget(&mobj->tracer, bigmeatyclaw); - P_SetTarget(&bigmeatyclaw->tracer, mobj); - mobj->reactiontime >>= 1; - } - break; case MT_BIGMINE: mobj->extravalue1 = FixedHypot(mobj->x, mobj->y)>>FRACBITS; break; @@ -9391,15 +9355,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->color = skins[5].prefcolor; sc = 5; break; - case MT_FANG: - sc = 4; - break; case MT_CORK: mobj->flags2 |= MF2_SUPERFIRE; break; - case MT_FBOMB: - mobj->flags2 |= MF2_EXPLOSION; - break; // SRB2Kart case MT_ITEMCAPSULE: { diff --git a/src/p_setup.c b/src/p_setup.c index 3b7a3d3df..ec68f5bdd 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7022,13 +7022,6 @@ static void P_ConvertBinaryThingTypes(void) case 203: //Egg Colosseum mapthings[i].args[5] = LE_BOSS4DROP + mapthings[i].extrainfo * LE_PARAMWIDTH; break; - case 204: //Fang - mapthings[i].args[4] = LE_BOSS4DROP + mapthings[i].extrainfo*LE_PARAMWIDTH; - if (mapthings[i].options & MTF_EXTRA) - mapthings[i].args[5] |= TMF_GRAYSCALE; - if (mapthings[i].options & MTF_AMBUSH) - mapthings[i].args[5] |= TMF_SKIPINTRO; - break; case 206: //Brak Eggman (Old) mapthings[i].args[5] = LE_BRAKPLATFORM + mapthings[i].extrainfo*LE_PARAMWIDTH; break; @@ -7050,9 +7043,6 @@ static void P_ConvertBinaryThingTypes(void) mapthings[i].args[0] = mapthings[i].angle; mapthings[i].args[1] = mapthings[i].options & 7; break; - case 294: //Fang waypoint - mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); - break; case 300: //Ring case 301: //Bounce ring case 302: //Rail ring From daf5fdf748ca6cc601500d3a49dd12ce5b7a7c53 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Mon, 7 Apr 2025 21:00:43 -0400 Subject: [PATCH 04/12] Remove Bumper Death animation --- src/info/mobjs.h | 2 - src/info/states.h | 38 -------------- src/k_battle.c | 2 +- src/k_collide.c | 14 ----- src/p_inter.c | 4 ++ src/p_mobj.c | 130 +++------------------------------------------- src/p_setup.c | 1 - 7 files changed, 12 insertions(+), 179 deletions(-) diff --git a/src/info/mobjs.h b/src/info/mobjs.h index 156830034..d46d3e983 100644 --- a/src/info/mobjs.h +++ b/src/info/mobjs.h @@ -685,8 +685,6 @@ _(SINK_SHIELD) _(SINKTRAIL) _(BATTLEBUMPER) // Battle Mode bumpers -_(BATTLEBUMPER_DEBRIS) -_(BATTLEBUMPER_BLAST) _(DEZLASER) diff --git a/src/info/states.h b/src/info/states.h index daa934a27..b47b954dc 100644 --- a/src/info/states.h +++ b/src/info/states.h @@ -3003,44 +3003,6 @@ _(BATTLEBUMPER1) _(BATTLEBUMPER2) _(BATTLEBUMPER3) -_(BATTLEBUMPER_EXCRYSTALA1) -_(BATTLEBUMPER_EXCRYSTALA2) -_(BATTLEBUMPER_EXCRYSTALA3) -_(BATTLEBUMPER_EXCRYSTALA4) - -_(BATTLEBUMPER_EXCRYSTALB1) -_(BATTLEBUMPER_EXCRYSTALB2) -_(BATTLEBUMPER_EXCRYSTALB3) -_(BATTLEBUMPER_EXCRYSTALB4) - -_(BATTLEBUMPER_EXCRYSTALC1) -_(BATTLEBUMPER_EXCRYSTALC2) -_(BATTLEBUMPER_EXCRYSTALC3) -_(BATTLEBUMPER_EXCRYSTALC4) - -_(BATTLEBUMPER_EXSHELLA1) -_(BATTLEBUMPER_EXSHELLA2) - -_(BATTLEBUMPER_EXSHELLB1) -_(BATTLEBUMPER_EXSHELLB2) - -_(BATTLEBUMPER_EXSHELLC1) -_(BATTLEBUMPER_EXSHELLC2) - -_(BATTLEBUMPER_EXDEBRIS1) -_(BATTLEBUMPER_EXDEBRIS2) - -_(BATTLEBUMPER_EXBLAST1) -_(BATTLEBUMPER_EXBLAST2) -_(BATTLEBUMPER_EXBLAST3) -_(BATTLEBUMPER_EXBLAST4) -_(BATTLEBUMPER_EXBLAST5) -_(BATTLEBUMPER_EXBLAST6) -_(BATTLEBUMPER_EXBLAST7) -_(BATTLEBUMPER_EXBLAST8) -_(BATTLEBUMPER_EXBLAST9) -_(BATTLEBUMPER_EXBLAST10) - // DEZ Laser respawn _(DEZLASER) diff --git a/src/k_battle.c b/src/k_battle.c index e164b08ba..fc8f6ab45 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -255,7 +255,7 @@ void K_CheckBumpers(void) } else if (numingame <= 1) { - if (!itembreaker) + if (!itembreaker && cv_kartitembreaker.value) { // Reset map to turn on battle capsules D_MapChange(gamemap, gametype, encoremode, true, 0, false, false); diff --git a/src/k_collide.c b/src/k_collide.c index 5709f587b..88adcabff 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -584,20 +584,6 @@ boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2) ghost->destscale = 15*ghost->destscale/2; ghost->fuse = 10; ghost->scalespeed = (ghost->destscale - ghost->scale)/ghost->fuse; - - for (i = 0; i < 2; i++) - { - mobj_t *blast = P_SpawnMobjFromMobj(t1, 0, 0, FixedDiv(t1->height, t1->scale), MT_BATTLEBUMPER_BLAST); - P_SetScale(blast, 5*blast->scale/2); - - blast->angle = R_PointToAngle2(0, 0, t1->momx, t1->momy) + ANGLE_45; - if (i & 1) - { - blast->angle += ANGLE_90; - } - - blast->destscale *= 10; - } } t1->flags |= MF_SHOOTABLE; diff --git a/src/p_inter.c b/src/p_inter.c index 3b4b14a57..402d715ab 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2227,6 +2227,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da K_TryHurtSoundExchange(target, source); } + else if (source && source == player->mo && source->player) + { + K_DestroyBumpers(player, 1); + } if (!(type == DMG_NORMAL || type == DMG_WIPEOUT || type == DMG_VOLTAGE)) { diff --git a/src/p_mobj.c b/src/p_mobj.c index e8df336f2..3e22ac8ff 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5726,117 +5726,6 @@ static void P_MobjSceneryThink(mobj_t *mobj) } break; case MT_BATTLEBUMPER: - if (mobj->health <= 0) - { - mobj->fuse--; - - if (!S_SoundPlaying(mobj, sfx_cdfm71)) - { - S_StartSound(mobj, sfx_cdfm71); - } - - if (mobj->fuse <= 0) - { - statenum_t curState = (mobj->state - states); - - if (curState == S_BATTLEBUMPER1) - { - P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALA1); - - if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) - { - P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLA1); - } - - mobj->shadowscale *= 2; - mobj->fuse = 12; - } - else if (curState >= S_BATTLEBUMPER_EXCRYSTALA1 && curState <= S_BATTLEBUMPER_EXCRYSTALA4) - { - P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALB1); - - if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) - { - P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLB1); - } - - mobj->shadowscale *= 2; - mobj->fuse = 24; - break; - } - else if (curState >= S_BATTLEBUMPER_EXCRYSTALB1 && curState <= S_BATTLEBUMPER_EXCRYSTALB4) - { - P_SetMobjState(mobj, S_BATTLEBUMPER_EXCRYSTALC1); - - if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) - { - P_SetMobjState(mobj->tracer, S_BATTLEBUMPER_EXSHELLC1); - } - - mobj->shadowscale *= 2; - mobj->fuse = 32; - break; - } - else - { - const INT16 spacing = 64; - UINT8 i; - - for (i = 0; i < 10; i++) - { - mobj_t *debris = P_SpawnMobjFromMobj( - mobj, - P_RandomRange(-spacing, spacing) * FRACUNIT, - P_RandomRange(-spacing, spacing) * FRACUNIT, - P_RandomRange(-spacing, spacing) * FRACUNIT, - MT_BATTLEBUMPER_DEBRIS - ); - - P_SetScale(debris, (debris->destscale *= 2)); - debris->color = mobj->color; - - debris->momz = -debris->scale * P_MobjFlip(debris); - } - - for (i = 0; i < 2; i++) - { - mobj_t *blast = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BATTLEBUMPER_BLAST); - - blast->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy) + ANGLE_45; - if (i & 1) - { - blast->angle += ANGLE_90; - S_StartSound(blast, sfx_cdfm64); - } - blast->angle = blast->angle; - - blast->destscale *= 4; - } - - for (i = 0; i < 10; i++) - { - mobj_t *puff = P_SpawnMobjFromMobj( - mobj, - P_RandomRange(-spacing, spacing) * FRACUNIT, - P_RandomRange(-spacing, spacing) * FRACUNIT, - P_RandomRange(-spacing, spacing) * FRACUNIT, - MT_DUST - ); - - P_SetScale(puff, (puff->destscale *= 5)); - puff->momz = puff->scale * P_MobjFlip(puff); - - P_Thrust(puff, R_PointToAngle2(mobj->x, mobj->y, puff->x, puff->y), puff->scale); - } - - P_RemoveMobj(mobj); - return; - } - } - - break; - } - if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player && mobj->target->health > 0 && !mobj->target->player->spectator) { @@ -5908,29 +5797,24 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SetThingPosition(mobj); } + // Was this so hard? if (mobj->target->player->bumper <= mobj->threshold) { - // Do bumper destruction - P_KillMobj(mobj, NULL, NULL, DMG_NORMAL); - break; + P_RemoveMobj(mobj); + return; } } - else + else if ((mobj->health > 0 + && (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->health <= 0 || mobj->target->player->spectator)) + || (mobj->health <= 0 && P_IsObjectOnGround(mobj)) + || P_CheckDeathPitCollide(mobj)) // When in death state { - // Sliently remove P_RemoveMobj(mobj); return; } break; - case MT_BATTLEBUMPER_DEBRIS: - if (mobj->state == states + S_BATTLEBUMPER_EXDEBRIS2) - { - mobj->renderflags ^= RF_DONTDRAW; - } - break; - // see also K_drawKartItem in k_hud.c case MT_PLAYERARROW: if (mobj->target && mobj->target->health diff --git a/src/p_setup.c b/src/p_setup.c index ec68f5bdd..7dc209f93 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7865,7 +7865,6 @@ static void P_InitLevelSettings(boolean reloadinggamestate) stackingactive = false; chainingactive = false; slipdashactive = false; - if (cv_kartrings.value) ringsactive = true; From f0a6a112acb913c1ba7fea5fe800fd9cce53e8e6 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Wed, 9 Apr 2025 13:45:35 -0400 Subject: [PATCH 05/12] Port v1 objects pt 4 --- src/doomdef.h | 4 - src/info/actions.h | 1 + src/info/mobjs.h | 115 ++++++-------- src/info/sprites.h | 49 +++--- src/info/states.h | 367 ++++++++++++++++++++++++--------------------- src/p_enemy.c | 307 ++++++++++++++++++++++--------------- src/p_floor.c | 8 + src/p_inter.c | 26 ++++ src/p_local.h | 2 + src/p_mobj.c | 113 ++++++++++++-- 10 files changed, 588 insertions(+), 404 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index fd61076ce..92dcc9986 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -492,10 +492,6 @@ extern int compuncommitted; /// Dumps the contents of a network save game upon consistency failure for debugging. //#define DUMPCONSISTENCY -/// Who put weights on my recycler? ... Inuyasha did. -/// \note XMOD port. -//#define WEIGHTEDRECYCLER - /// Allow loading of savegames between different versions of the game. /// \note XMOD port. /// Most modifications should probably enable this. diff --git a/src/info/actions.h b/src/info/actions.h index 48cae73ca..676e0caac 100644 --- a/src/info/actions.h +++ b/src/info/actions.h @@ -1,3 +1,4 @@ +_(A_MonitorPop, MONITORPOP) _(A_Explode, EXPLODE) _(A_Pain, PAIN) _(A_Fall, FALL) diff --git a/src/info/mobjs.h b/src/info/mobjs.h index d46d3e983..9458fe8de 100644 --- a/src/info/mobjs.h +++ b/src/info/mobjs.h @@ -14,6 +14,7 @@ _(REDCRAWLA) // Crawla (Red) _(GFZFISH) // SDURF _(GOLDBUZZ) // Buzz (Gold) _(REDBUZZ) // Buzz (Red) +_(AQUABUZZ) _(JETTBOMBER) // Jetty-Syn Bomber _(JETTGUNNER) // Jetty-Syn Gunner _(CRAWLACOMMANDER) // Crawla Commander @@ -33,7 +34,6 @@ _(EGGGUARD) // Egg Guard _(EGGSHIELD) // Egg Guard's shield _(GSNAPPER) // Green Snapper _(MINUS) // Minus -_(MINUSDIRT) // Minus dirt _(SPRINGSHELL) // Spring Shell _(YELLOWSHELL) // Spring Shell (yellow) _(UNIDUS) // Unidus @@ -106,6 +106,7 @@ _(FLINGBLUESPHERE) // Lost blue sphere _(BOMBSPHERE) _(REDTEAMRING) // Rings collectable by red team. _(BLUETEAMRING) // Rings collectable by blue team. +_(EMMY) // Special Stage token for special stage _(TOKEN) // Special Stage token for special stage _(REDFLAG) // Red CTF Flag _(BLUEFLAG) // Blue CTF Flag @@ -156,73 +157,51 @@ _(WALLSPIKE) _(WALLSPIKEBASE) _(STARPOST) _(BIGMINE) +_(BIGAIRMINE) _(BLASTEXECUTOR) _(CANNONLAUNCHER) +// Monitor Boxes +_(SUPERRINGBOX) +_(REDRINGBOX) +_(BLUERINGBOX) +_(SNEAKERTV) +_(INV) +_(PRUP) // 1up Box +_(YELLOWTV) +_(BLUETV) +_(BLACKTV) // Bomb shield TV +_(WHITETV) // Jump shield TV +_(GREENTV) +_(PITYTV) // Pity Shield TV +_(EGGMANBOX) +_(MIXUPBOX) +_(RECYCLETV) +_(RECYCLEICO) +_(QUESTIONBOX) +_(GRAVITYBOX) +_(SCORETVSMALL) +_(SCORETVLARGE) + // Monitor miscellany -_(BOXSPARKLE) - -// Monitor boxes -- regular -_(RING_BOX) -_(PITY_BOX) -_(ATTRACT_BOX) -_(FORCE_BOX) -_(ARMAGEDDON_BOX) -_(WHIRLWIND_BOX) -_(ELEMENTAL_BOX) -_(SNEAKERS_BOX) -_(INVULN_BOX) -_(1UP_BOX) -_(EGGMAN_BOX) -_(MIXUP_BOX) -_(MYSTERY_BOX) -_(GRAVITY_BOX) -_(RECYCLER_BOX) -_(SCORE1K_BOX) -_(SCORE10K_BOX) -_(FLAMEAURA_BOX) -_(BUBBLEWRAP_BOX) -_(THUNDERCOIN_BOX) - -// Monitor boxes -- repeating (big) boxes -_(PITY_GOLDBOX) -_(ATTRACT_GOLDBOX) -_(FORCE_GOLDBOX) -_(ARMAGEDDON_GOLDBOX) -_(WHIRLWIND_GOLDBOX) -_(ELEMENTAL_GOLDBOX) -_(SNEAKERS_GOLDBOX) -_(INVULN_GOLDBOX) -_(EGGMAN_GOLDBOX) -_(GRAVITY_GOLDBOX) -_(FLAMEAURA_GOLDBOX) -_(BUBBLEWRAP_GOLDBOX) -_(THUNDERCOIN_GOLDBOX) - -// Monitor boxes -- special -_(RING_REDBOX) -_(RING_BLUEBOX) - -// Monitor icons -_(RING_ICON) -_(PITY_ICON) -_(ATTRACT_ICON) -_(FORCE_ICON) -_(ARMAGEDDON_ICON) -_(WHIRLWIND_ICON) -_(ELEMENTAL_ICON) -_(SNEAKERS_ICON) -_(INVULN_ICON) -_(1UP_ICON) -_(EGGMAN_ICON) -_(MIXUP_ICON) -_(GRAVITY_ICON) -_(RECYCLER_ICON) -_(SCORE1K_ICON) -_(SCORE10K_ICON) -_(FLAMEAURA_ICON) -_(BUBBLEWRAP_ICON) -_(THUNDERCOIN_ICON) +_(MONITOREXPLOSION) +_(REDMONITOREXPLOSION) +_(BLUEMONITOREXPLOSION) +_(RINGICO) +_(SHOESICO) +_(INVCICO) +_(1UPICO) +_(YSHIELDICO) +_(BSHIELDICO) +_(KSHIELDICO) +_(WSHIELDICO) +_(GSHIELDICO) +_(PITYSHIELDICO) +_(EGGMANICO) +_(MIXUPICO) +_(GRAVITYICO) +_(SCOREICOSMALL) +_(SCOREICOLARGE) // Projectiles _(ROCKET) @@ -305,10 +284,10 @@ _(FLAMEJETFLAMEB) // Blade's flame // Egg Rock Scenery // Azure Temple Scenery -_(GLAREGOYLE) -_(GLAREGOYLEUP) -_(GLAREGOYLEDOWN) -_(GLAREGOYLELONG) +_(TRAPGOYLE) +_(TRAPGOYLEUP) +_(TRAPGOYLEDOWN) +_(TRAPGOYLELONG) _(TARGET) // AKA Red Crystal _(GREENFLAME) _(BLUEGARGOYLE) diff --git a/src/info/sprites.h b/src/info/sprites.h index adf03818a..210902f9d 100644 --- a/src/info/sprites.h +++ b/src/info/sprites.h @@ -34,7 +34,6 @@ _(SPSH) // Egg Guard _(ESHI) // Egg Guard's shield _(GSNP) // Green Snapper _(MNUS) // Minus -_(MNUD) // Minus dirt _(SSHL) // Spring Shell _(UNID) // Unidus @@ -98,6 +97,7 @@ _(MSCB) // Collectible Items _(RING) _(TRNG) // Team Rings +_(EMMY) // Special Stage Token _(TOKE) // Special Stage Token _(RFLG) // Red CTF Flag _(BFLG) // Blue CTF Flag @@ -122,33 +122,27 @@ _(BMNE) // Big floating mine _(PUMI) // Rollout Rock // Monitor Boxes -_(MSTV) // MiSc TV sprites -_(XLTV) // eXtra Large TV sprites +_(SRBX) +_(RRBX) +_(BRBX) +_(SHTV) +_(PINV) +_(YLTV) +_(BLTV) // Force shield +_(BKTV) // Bomb shield TV +_(WHTV) // Jump shield TV +_(GRTV) // Pity shield TV +_(ELTV) // Elemental shield TV +_(EGGB) // Eggman box +_(MIXU) // Player mixing monitor +_(RECY) // Recycler (power mixing) monitor +_(QUES) // Random monitor +_(GBTV) // Gravity boots TV +_(PRUP) // 1up +_(PTTV) // Score TVs -_(TRRI) // Red team: 10 RIngs -_(TBRI) // Blue team: 10 RIngs - -_(TVRI) // 10 RIng -_(TVPI) // PIty shield -_(TVAT) // ATtraction shield -_(TVFO) // FOrce shield -_(TVAR) // ARmageddon shield -_(TVWW) // WhirlWind shield -_(TVEL) // ELemental shield -_(TVSS) // Super Sneakers -_(TVIV) // InVincibility -_(TV1U) // 1Up -_(TV1P) // 1uP (textless) -_(TVEG) // EGgman -_(TVMX) // MiXup -_(TVMY) // MYstery -_(TVGV) // GraVity boots -_(TVRC) // ReCycler -_(TV1K) // 1,000 points (1 K) -_(TVTK) // 10,000 points (Ten K) -_(TVFL) // FLame shield -_(TVBB) // BuBble shield -_(TVZP) // Thunder shield (ZaP) +// Monitor Miscellany +_(MTEX) // Exploding monitor // Projectiles _(MISL) @@ -220,7 +214,6 @@ _(XMS6) // Mistletoe _(FHZI) // FHZ Ice _(ROSY) // Azure Temple Scenery -_(BGAR) // ATZ Gargoyles _(RCRY) // ATZ Red Crystal (Target) _(CFLM) // Green torch flame diff --git a/src/info/states.h b/src/info/states.h index f2fd095a7..1524c4efa 100644 --- a/src/info/states.h +++ b/src/info/states.h @@ -87,6 +87,10 @@ _(RBUZZLOOK2) _(RBUZZFLY1) _(RBUZZFLY2) +// AquaBuzz +_(BBUZZFLY1) +_(BBUZZFLY2) + // Jetty-Syn Bomber _(JETBLOOK1) _(JETBLOOK2) @@ -260,32 +264,25 @@ _(GSNAPPER3) _(GSNAPPER4) // Minus -_(MINUS_INIT) _(MINUS_STND) -_(MINUS_DIGGING1) -_(MINUS_DIGGING2) -_(MINUS_DIGGING3) -_(MINUS_DIGGING4) -_(MINUS_BURST0) -_(MINUS_BURST1) -_(MINUS_BURST2) -_(MINUS_BURST3) -_(MINUS_BURST4) -_(MINUS_BURST5) +_(MINUS_DIGGING) _(MINUS_POPUP) -_(MINUS_AERIAL1) -_(MINUS_AERIAL2) -_(MINUS_AERIAL3) -_(MINUS_AERIAL4) - -// Minus dirt -_(MINUSDIRT1) -_(MINUSDIRT2) -_(MINUSDIRT3) -_(MINUSDIRT4) -_(MINUSDIRT5) -_(MINUSDIRT6) -_(MINUSDIRT7) +_(MINUS_UPWARD1) +_(MINUS_UPWARD2) +_(MINUS_UPWARD3) +_(MINUS_UPWARD4) +_(MINUS_UPWARD5) +_(MINUS_UPWARD6) +_(MINUS_UPWARD7) +_(MINUS_UPWARD8) +_(MINUS_DOWNWARD1) +_(MINUS_DOWNWARD2) +_(MINUS_DOWNWARD3) +_(MINUS_DOWNWARD4) +_(MINUS_DOWNWARD5) +_(MINUS_DOWNWARD6) +_(MINUS_DOWNWARD7) +_(MINUS_DOWNWARD8) // Spring Shell _(SSHELL_STND) @@ -814,7 +811,9 @@ _(GRAVWELLRED) _(TEAMRING) // Special Stage Token +_(EMMY) _(TOKEN) +_(MOVINGTOKEN) // CTF Flags _(REDFLAG) @@ -945,148 +944,184 @@ _(STARPOST_SPIN) _(STARPOST_ENDSPIN) // Big floating mine -_(BIGMINE_IDLE) -_(BIGMINE_ALERT1) -_(BIGMINE_ALERT2) -_(BIGMINE_ALERT3) -_(BIGMINE_SET1) -_(BIGMINE_SET2) -_(BIGMINE_SET3) -_(BIGMINE_BLAST1) -_(BIGMINE_BLAST2) -_(BIGMINE_BLAST3) -_(BIGMINE_BLAST4) -_(BIGMINE_BLAST5) +_(BIGMINE1) +_(BIGMINE2) +_(BIGMINE3) +_(BIGMINE4) +_(BIGMINE5) +_(BIGMINE6) +_(BIGMINE7) +_(BIGMINE8) // Cannon Launcher _(CANNONLAUNCHER1) _(CANNONLAUNCHER2) _(CANNONLAUNCHER3) -// Monitor Miscellany -_(BOXSPARKLE1) -_(BOXSPARKLE2) -_(BOXSPARKLE3) -_(BOXSPARKLE4) +// Super Ring Box +_(SUPERRINGBOX) +_(SUPERRINGBOX1) +_(SUPERRINGBOX2) +_(SUPERRINGBOX3) +_(SUPERRINGBOX4) +_(SUPERRINGBOX5) +_(SUPERRINGBOX6) -_(BOX_FLICKER) -_(BOX_POP1) -_(BOX_POP2) +// Red Team Ring Box +_(REDRINGBOX) +_(REDRINGBOX1) -_(GOLDBOX_FLICKER) -_(GOLDBOX_OFF1) -_(GOLDBOX_OFF2) -_(GOLDBOX_OFF3) -_(GOLDBOX_OFF4) -_(GOLDBOX_OFF5) -_(GOLDBOX_OFF6) -_(GOLDBOX_OFF7) +// Blue Team Ring Box +_(BLUERINGBOX) +_(BLUERINGBOX1) -// Monitor States (one per box) -_(MYSTERY_BOX) -_(RING_BOX) -_(PITY_BOX) -_(ATTRACT_BOX) -_(FORCE_BOX) -_(ARMAGEDDON_BOX) -_(WHIRLWIND_BOX) -_(ELEMENTAL_BOX) -_(SNEAKERS_BOX) -_(INVULN_BOX) -_(1UP_BOX) -_(EGGMAN_BOX) -_(MIXUP_BOX) -_(GRAVITY_BOX) -_(RECYCLER_BOX) -_(SCORE1K_BOX) -_(SCORE10K_BOX) -_(FLAMEAURA_BOX) -_(BUBBLEWRAP_BOX) -_(THUNDERCOIN_BOX) +// Super Sneakers Box +_(SHTV) +_(SHTV1) +_(SHTV2) +_(SHTV3) +_(SHTV4) +_(SHTV5) +_(SHTV6) -// Gold Repeat Monitor States (one per box) -_(PITY_GOLDBOX) -_(ATTRACT_GOLDBOX) -_(FORCE_GOLDBOX) -_(ARMAGEDDON_GOLDBOX) -_(WHIRLWIND_GOLDBOX) -_(ELEMENTAL_GOLDBOX) -_(SNEAKERS_GOLDBOX) -_(INVULN_GOLDBOX) -_(EGGMAN_GOLDBOX) -_(GRAVITY_GOLDBOX) -_(FLAMEAURA_GOLDBOX) -_(BUBBLEWRAP_GOLDBOX) -_(THUNDERCOIN_GOLDBOX) +// Invincibility Box +_(PINV) +_(PINV1) +_(PINV2) +_(PINV3) +_(PINV4) +_(PINV5) +_(PINV6) -// Team Ring Boxes (these are special) -_(RING_REDBOX1) -_(RING_REDBOX2) -_(REDBOX_POP1) -_(REDBOX_POP2) +// 1up Box +_(PRUP) +_(PRUP1) +_(PRUP2) +_(PRUP3) +_(PRUP4) +_(PRUP5) +_(PRUP6) -_(RING_BLUEBOX1) -_(RING_BLUEBOX2) -_(BLUEBOX_POP1) -_(BLUEBOX_POP2) +// Ring Shield Box +_(YLTV) +_(YLTV1) +_(YLTV2) +_(YLTV3) +_(YLTV4) +_(YLTV5) +_(YLTV6) -// Box Icons -- 2 states each, animation and action -_(RING_ICON1) -_(RING_ICON2) +// Force Shield Box +_(BLTV1) +_(BLTV2) +_(BLTV3) +_(BLTV4) +_(BLTV5) +_(BLTV6) +_(BLTV7) -_(PITY_ICON1) -_(PITY_ICON2) +// Bomb Shield Box +_(BKTV1) +_(BKTV2) +_(BKTV3) +_(BKTV4) +_(BKTV5) +_(BKTV6) +_(BKTV7) -_(ATTRACT_ICON1) -_(ATTRACT_ICON2) +// Jump Shield Box +_(WHTV1) +_(WHTV2) +_(WHTV3) +_(WHTV4) +_(WHTV5) +_(WHTV6) +_(WHTV7) -_(FORCE_ICON1) -_(FORCE_ICON2) +// Water Shield Box +_(GRTV) +_(GRTV1) +_(GRTV2) +_(GRTV3) +_(GRTV4) +_(GRTV5) +_(GRTV6) -_(ARMAGEDDON_ICON1) -_(ARMAGEDDON_ICON2) +// Pity Shield Box +_(PITV1) +_(PITV2) +_(PITV3) +_(PITV4) +_(PITV5) +_(PITV6) +_(PITV7) -_(WHIRLWIND_ICON1) -_(WHIRLWIND_ICON2) +// Eggman Box +_(EGGTV1) +_(EGGTV2) +_(EGGTV3) +_(EGGTV4) +_(EGGTV5) +_(EGGTV6) +_(EGGTV7) -_(ELEMENTAL_ICON1) -_(ELEMENTAL_ICON2) +// Teleport Box +_(MIXUPBOX1) +_(MIXUPBOX2) +_(MIXUPBOX3) +_(MIXUPBOX4) +_(MIXUPBOX5) +_(MIXUPBOX6) +_(MIXUPBOX7) -_(SNEAKERS_ICON1) -_(SNEAKERS_ICON2) +// Recycler Box +_(RECYCLETV1) +_(RECYCLETV2) +_(RECYCLETV3) +_(RECYCLETV4) +_(RECYCLETV5) +_(RECYCLETV6) +_(RECYCLETV7) -_(INVULN_ICON1) -_(INVULN_ICON2) +// Question Box +_(RANDOMBOX1) +_(RANDOMBOX2) +_(RANDOMBOX3) -_(1UP_ICON1) -_(1UP_ICON2) +// Gravity Boots Box +_(GBTV1) +_(GBTV2) +_(GBTV3) +_(GBTV4) +_(GBTV5) +_(GBTV6) +_(GBTV7) -_(EGGMAN_ICON1) -_(EGGMAN_ICON2) +// Score boxes +_(SCORETVA1) +_(SCORETVA2) +_(SCORETVA3) +_(SCORETVA4) +_(SCORETVA5) +_(SCORETVA6) +_(SCORETVA7) +_(SCORETVB1) +_(SCORETVB2) +_(SCORETVB3) +_(SCORETVB4) +_(SCORETVB5) +_(SCORETVB6) +_(SCORETVB7) -_(MIXUP_ICON1) -_(MIXUP_ICON2) +// Monitor Explosion +_(MONITOREXPLOSION1) +_(MONITOREXPLOSION2) -_(GRAVITY_ICON1) -_(GRAVITY_ICON2) +_(REDMONITOREXPLOSION1) +_(REDMONITOREXPLOSION2) -_(RECYCLER_ICON1) -_(RECYCLER_ICON2) - -_(SCORE1K_ICON1) -_(SCORE1K_ICON2) - -_(SCORE10K_ICON1) -_(SCORE10K_ICON2) - -_(FLAMEAURA_ICON1) -_(FLAMEAURA_ICON2) - -_(BUBBLEWRAP_ICON1) -_(BUBBLEWRAP_ICON2) - -_(THUNDERCOIN_ICON1) -_(THUNDERCOIN_ICON2) +_(BLUEMONITOREXPLOSION1) +_(BLUEMONITOREXPLOSION2) // --- @@ -1311,35 +1346,29 @@ _(FLAMEJETFLAMEB1) _(FLAMEJETFLAMEB2) _(FLAMEJETFLAMEB3) -// Glaregoyles -_(GLAREGOYLE) -_(GLAREGOYLE_CHARGE) -_(GLAREGOYLE_BLINK) -_(GLAREGOYLE_HOLD) -_(GLAREGOYLE_FIRE) -_(GLAREGOYLE_LOOP) -_(GLAREGOYLE_COOLDOWN) -_(GLAREGOYLEUP) -_(GLAREGOYLEUP_CHARGE) -_(GLAREGOYLEUP_BLINK) -_(GLAREGOYLEUP_HOLD) -_(GLAREGOYLEUP_FIRE) -_(GLAREGOYLEUP_LOOP) -_(GLAREGOYLEUP_COOLDOWN) -_(GLAREGOYLEDOWN) -_(GLAREGOYLEDOWN_CHARGE) -_(GLAREGOYLEDOWN_BLINK) -_(GLAREGOYLEDOWN_HOLD) -_(GLAREGOYLEDOWN_FIRE) -_(GLAREGOYLEDOWN_LOOP) -_(GLAREGOYLEDOWN_COOLDOWN) -_(GLAREGOYLELONG) -_(GLAREGOYLELONG_CHARGE) -_(GLAREGOYLELONG_BLINK) -_(GLAREGOYLELONG_HOLD) -_(GLAREGOYLELONG_FIRE) -_(GLAREGOYLELONG_LOOP) -_(GLAREGOYLELONG_COOLDOWN) +// Trapgoyles +_(TRAPGOYLE) +_(TRAPGOYLE_CHECK) +_(TRAPGOYLE_FIRE1) +_(TRAPGOYLE_FIRE2) +_(TRAPGOYLE_FIRE3) +_(TRAPGOYLEUP) +_(TRAPGOYLEUP_CHECK) +_(TRAPGOYLEUP_FIRE1) +_(TRAPGOYLEUP_FIRE2) +_(TRAPGOYLEUP_FIRE3) +_(TRAPGOYLEDOWN) +_(TRAPGOYLEDOWN_CHECK) +_(TRAPGOYLEDOWN_FIRE1) +_(TRAPGOYLEDOWN_FIRE2) +_(TRAPGOYLEDOWN_FIRE3) +_(TRAPGOYLELONG) +_(TRAPGOYLELONG_CHECK) +_(TRAPGOYLELONG_FIRE1) +_(TRAPGOYLELONG_FIRE2) +_(TRAPGOYLELONG_FIRE3) +_(TRAPGOYLELONG_FIRE4) +_(TRAPGOYLELONG_FIRE5) // ATZ's Red Crystal/Target _(TARGET_IDLE) diff --git a/src/p_enemy.c b/src/p_enemy.c index 9f9e2eefb..5179c90ce 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -505,6 +505,55 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed //return false; } +void P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target +{ + fixed_t dist; + fixed_t ns = 0; + + if (!enemy) + return; + + if (!(enemy->health)) + return; + + // change angle + source->angle = R_PointToAngle2(source->x, source->y, enemy->x, enemy->y); + if (source->player) + { + for (SINT8 j = 0; j <= r_splitscreen; j++) + { + if (source->player == &players[displayplayers[j]]) + { + localangle[j] = source->angle; + break; + } + } + } + + // change slope + dist = P_AproxDistance(P_AproxDistance(enemy->x - source->x, enemy->y - source->y), + enemy->z - source->z); + + if (dist < 1) + dist = 1; + + if (source->type == MT_DETON && enemy->player) // For Deton Chase (Unused) + ns = FixedDiv(FixedMul(K_GetKartSpeed(enemy->player, false, true), enemy->scale), FixedDiv(20*FRACUNIT,17*FRACUNIT)); + else if (source->type != MT_PLAYER) + { + if (source->threshold == 32000) + ns = FixedMul(source->info->speed/2, source->scale); + else + ns = FixedMul(source->info->speed, source->scale); + } + else if (source->player) + ns = FixedDiv(FixedMul(K_GetKartSpeed(source->player, false, true), source->scale), 3*FRACUNIT/2); + + source->momx = FixedMul(FixedDiv(enemy->x - source->x, dist), ns); + source->momy = FixedMul(FixedDiv(enemy->y - source->y, dist), ns); + source->momz = FixedMul(FixedDiv(enemy->z - source->z, dist), ns); +} + // // ACTION ROUTINES // @@ -2628,6 +2677,102 @@ void A_Fall(mobj_t *actor) actor->extravalue2 = locvar1; } +// Function: A_MonitorPop +// +// Description: Used by monitors when they explode. +// +// var1 = unused +// var2 = unused +// +void A_MonitorPop(mobj_t *actor) +{ + mobj_t *remains; + mobjtype_t explode; + mobjtype_t item = 0; + //mobjtype_t newbox; + + if (LUA_CallAction(A_MONITORPOP, actor)) + return; + + // de-solidify + actor->health = 0; + P_UnsetThingPosition(actor); + actor->flags &= ~MF_SOLID; + actor->flags |= MF_NOCLIP; + P_SetThingPosition(actor); + + // Monitor explosion + explode = mobjinfo[actor->info->speed].mass; + remains = P_SpawnMobj(actor->x, actor->y, + ((actor->eflags & MFE_VERTICALFLIP) ? (actor->z + 3*(actor->height/4) - FixedMul(mobjinfo[explode].height, actor->scale)) : (actor->z + actor->height/4)), explode); + if (actor->eflags & MFE_VERTICALFLIP) + { + remains->eflags |= MFE_VERTICALFLIP; + remains->flags2 |= MF2_OBJECTFLIP; + } + remains->destscale = actor->destscale; + P_SetScale(remains, actor->scale); + + remains = P_SpawnMobj(actor->x, actor->y, + ((actor->eflags & MFE_VERTICALFLIP) ? (actor->z + actor->height - FixedMul(mobjinfo[actor->info->speed].height, actor->scale)) : actor->z), + actor->info->speed); + remains->type = actor->type; // Transfer type information + P_UnsetThingPosition(remains); + if (sector_list) + { + P_DelSeclist(sector_list); + sector_list = NULL; + } + P_SetThingPosition(remains); + remains->destscale = actor->destscale; + P_SetScale(remains, actor->scale); + remains->flags = actor->flags; // Transfer flags + remains->flags2 = actor->flags2; // Transfer flags2 + remains->fuse = actor->fuse; // Transfer respawn timer + remains->threshold = 68; + remains->skin = NULL; + + P_SetTarget(&g_tm.thing, remains); + + if (actor->info->deathsound) + S_StartSound(remains, actor->info->deathsound); + + switch (actor->type) + { + default: + item = actor->info->damage; + break; + } + + if (item != 0) + { + mobj_t *newmobj; + + if (actor->eflags & MFE_VERTICALFLIP) + { + newmobj = P_SpawnMobj(actor->x, actor->y, actor->z + actor->height - FixedMul(13*FRACUNIT + mobjinfo[item].height, actor->scale), item); + newmobj->eflags |= MFE_VERTICALFLIP; + } + else + newmobj = P_SpawnMobj(actor->x, actor->y, actor->z + FixedMul(13*FRACUNIT, actor->scale), item); + + newmobj->destscale = actor->destscale; + P_SetScale(newmobj, actor->scale); + P_SetTarget(&newmobj->target, actor->target); // Transfer target + if (item == MT_1UPICO && newmobj->target->player) + { + if (actor->tracer) // Remove the old lives icon. + P_RemoveMobj(actor->tracer); + + newmobj->frame -= 2; // No lives icon for this player, use the default. + } + } + else + CONS_Debug(DBG_GAMELOGIC, "Powerup item not defined in 'damage' field for A_MonitorPop\n"); + + P_RemoveMobj(actor); +} + // Function: A_Explode // // Description: Explodes an object, doing damage to any objects nearby. The target is used as the cause of the explosion. Damage value is used as explosion range. @@ -3738,114 +3883,55 @@ void A_ShootBullet(mobj_t *actor) S_StartSound(actor, actor->info->attacksound); } -static mobj_t *minus; - -static BlockItReturn_t PIT_MinusCarry(mobj_t *thing) -{ - if (minus->tracer) - return BMIT_CONTINUE; - - if (minus->type == thing->type) - return BMIT_CONTINUE; - - if (!(thing->flags & (MF_PUSHABLE|MF_ENEMY))) - return BMIT_CONTINUE; - - if (P_AproxDistance(minus->x - thing->x, minus->y - thing->y) >= minus->radius*3) - return BMIT_CONTINUE; - - if (abs(thing->z - minus->z) > minus->height) - return BMIT_CONTINUE; - - P_SetTarget(&minus->tracer, thing); - - return BMIT_CONTINUE; -} - // Function: A_MinusDigging // // Description: Minus digging in the ground. // -// var1 = If 1, play digging sound. +// var1 = unused // var2 = unused // void A_MinusDigging(mobj_t *actor) { - INT32 locvar1 = var1; - INT32 rad = 32; - angle_t fa = (actor->angle >> ANGLETOFINESHIFT) & FINEMASK; - fixed_t dis = actor->info->speed*4; - fixed_t x = FINECOSINE(fa)*dis + actor->x + FRACUNIT*P_RandomRange(-rad, rad); - fixed_t y = FINESINE(fa)*dis + actor->y + FRACUNIT*P_RandomRange(-rad, rad); - fixed_t mz = (actor->eflags & MFE_VERTICALFLIP) ? actor->ceilingz : actor->floorz; - mobj_t *par; - if (LUA_CallAction(A_MINUSDIGGING, actor)) return; + actor->flags &= ~MF_SPECIAL; + actor->flags &= ~MF_SHOOTABLE; + if (!actor->target) { - P_SetMobjState(actor, actor->info->spawnstate); + A_Look(actor); return; } - par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT); - if (actor->eflags & MFE_VERTICALFLIP) - par->eflags |= MFE_VERTICALFLIP; - P_TryMove(par, x, y, false, NULL); - - // If close enough, prepare to attack - if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < actor->radius*2) + if (actor->reactiontime) { - P_SetMobjState(actor, actor->info->meleestate); - P_TryMove(actor, actor->target->x, actor->target->y, false, NULL); - S_StartSound(actor, actor->info->attacksound); - - // Spawn growing dirt pile. - par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT); - P_SetMobjState(par, actor->info->raisestate); - P_SetScale(par, actor->scale*2); - if (actor->eflags & MFE_VERTICALFLIP) - par->eflags |= MFE_VERTICALFLIP; + actor->reactiontime--; return; } - // Play digging sound - if (locvar1 == 1) - A_PlayActiveSound(actor); + // Dirt trail + P_SpawnGhostMobj(actor); - // Move + actor->flags |= MF_NOCLIPTHING; var1 = 3; A_Chase(actor); + actor->flags &= ~MF_NOCLIPTHING; - // Carry over shit, maybe - if (P_MobjWasRemoved(actor->tracer) || !actor->tracer->health) - P_SetTarget(&actor->tracer, NULL); + // Play digging sound + if (!(leveltime & 15)) + S_StartSound(actor, actor->info->activesound); - if (!actor->tracer) - { - fixed_t radius = 3*actor->radius; - fixed_t yh = (unsigned)(actor->y + radius - bmaporgy) >> MAPBLOCKSHIFT; - fixed_t yl = (unsigned)(actor->y - radius - bmaporgy) >> MAPBLOCKSHIFT; - fixed_t xh = (unsigned)(actor->x + radius - bmaporgx) >> MAPBLOCKSHIFT; - fixed_t xl = (unsigned)(actor->x - radius - bmaporgx) >> MAPBLOCKSHIFT; - fixed_t bx, by; + // If we're close enough to our target, pop out of the ground + if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) < actor->radius + && abs(actor->target->z - actor->z) < actor->height) + P_SetMobjState(actor, actor->info->missilestate); - BMBOUNDFIX(xl, xh, yl, yh); - - minus = actor; - - for (bx = xl; bx <= xh; bx++) - for (by = yl; by <= yh; by++) - P_BlockThingsIterator(bx, by, PIT_MinusCarry); - } + // Snap to ground + if (actor->eflags & MFE_VERTICALFLIP) + actor->z = actor->ceilingz - actor->height; else - { - if (P_TryMove(actor->tracer, actor->x, actor->y, false, NULL)) - actor->tracer->z = mz; - else - P_SetTarget(&actor->tracer, NULL); - } + actor->z = actor->floorz; } // Function: A_MinusPopup @@ -3857,65 +3943,44 @@ void A_MinusDigging(mobj_t *actor) // void A_MinusPopup(mobj_t *actor) { - INT32 num = 6; - angle_t ani = FixedAngle(FRACUNIT*360/num); - INT32 i; if (LUA_CallAction(A_MINUSPOPUP, actor)) return; - if (actor->eflags & MFE_VERTICALFLIP) - actor->momz = -10*FRACUNIT; - else - actor->momz = 10*FRACUNIT; + P_SetObjectMomZ(actor, 10*FRACUNIT, false); - S_StartSound(actor, sfx_s3k82); - for (i = 1; i <= num; i++) - { - mobj_t *rock = P_SpawnMobjFromMobj(actor, 0, 0, actor->height/4, MT_ROCKCRUMBLE1); - P_Thrust(rock, ani*i, FRACUNIT); - P_SetObjectMomZ(rock, 3*FRACUNIT, false); - P_SetScale(rock, rock->scale/3); - } - P_RadiusAttack(actor, actor, 2*actor->radius, 0, true); - if (actor->tracer) - P_DamageMobj(actor->tracer, actor, actor, 1, DMG_NORMAL); + actor->flags |= MF_SPECIAL; + actor->flags |= MF_SHOOTABLE; - actor->flags = (actor->flags & ~MF_NOCLIPTHING)|MF_SPECIAL|MF_SHOOTABLE; + // Sound for busting out of the ground. + S_StartSound(actor, actor->info->attacksound); } // Function: A_MinusCheck // // Description: If the minus hits the floor, dig back into the ground. // -// var1 = State to switch to (if 0, use seestate). -// var2 = If not 0, spawn debris when hitting the floor. +// var1 = unused +// var2 = unused // void A_MinusCheck(mobj_t *actor) { - INT32 locvar1 = var1; - INT32 locvar2 = var2; - if (LUA_CallAction(A_MINUSCHECK, actor)) return; - if (((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz) || (!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz)) + if ((!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz) + || ((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz)) { - P_SetMobjState(actor, locvar1 ? (statenum_t)locvar1 : actor->info->seestate); - actor->flags = actor->info->flags; - if (locvar2) - { - INT32 i, num = 6; - angle_t ani = FixedAngle(FRACUNIT*360/num); - for (i = 1; i <= num; i++) - { - mobj_t *rock = P_SpawnMobjFromMobj(actor, 0, 0, actor->height/4, MT_ROCKCRUMBLE1); - P_Thrust(rock, ani*i, FRACUNIT); - P_SetObjectMomZ(rock, 3*FRACUNIT, false); - P_SetScale(rock, rock->scale/3); - } - } + actor->flags &= ~MF_SPECIAL; + actor->flags &= ~MF_SHOOTABLE; + actor->reactiontime = TICRATE; + P_SetMobjState(actor, actor->info->seestate); + return; } + + // 'Falling' animation + if (P_MobjFlip(actor)*actor->momz < 0 && actor->state < &states[actor->info->meleestate]) + P_SetMobjState(actor, actor->info->meleestate); } // Function: A_ChickenCheck @@ -11515,7 +11580,7 @@ void A_MementosTPParticles(mobj_t *actor) particle->frame = 0; particle->color = ((i%2) ? (SKINCOLOR_RED) : (SKINCOLOR_BLACK)); particle->destscale = 1; - //P_HomingAttack(particle, actor); // Really now, Lat... + P_HomingAttack(particle, actor); // Really now, Lat... } // Although this is mostly used to spawn particles, we will also save the OTHER teleport inside actor->target. That way teleporting doesn't require a thinker iteration. diff --git a/src/p_floor.c b/src/p_floor.c index bd7104b35..05cfe8191 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2456,6 +2456,14 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) } else { + if (thing->type == MT_EMMY && thing->spawnpoint && (thing->spawnpoint->options & MTF_OBJECTSPECIAL)) + { + mobj_t *tokenobj = P_SpawnMobj(thing->x, thing->y, topheight, MT_TOKEN); + P_SetTarget(&thing->tracer, tokenobj); + P_SetTarget(&tokenobj->target, thing); + P_SetMobjState(tokenobj, mobjinfo[MT_TOKEN].seestate); + } + // "Powerup rise" sound S_StartSound(puncher, sfx_mario9); // Puncher is "close enough" } diff --git a/src/p_inter.c b/src/p_inter.c index 402d715ab..68aae9b73 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -689,6 +689,23 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) player->pickuprings++; return; + // Special Stage Token + case MT_EMMY: + if (player->bot) + return; + tokenlist += special->health; + + if (ALL7EMERALDS(emeralds)) // Got all 7 + { + P_GivePlayerRings(player, 50); + nummaprings += 50; // no cheating towards Perfect! + } + else + token++; + + if (special->tracer) // token BG + P_RemoveMobj(special->tracer); + break; // Secret emblem thingy case MT_EMBLEM: @@ -825,6 +842,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) Obj_LoopEndpointCollide(special, toucher); return; + case MT_BIGMINE: + case MT_BIGAIRMINE: + // Spawn explosion! + P_SpawnMobj(special->x, special->y, special->z, special->info->mass); + P_RadiusAttack(special, special, special->info->damage, DMG_NORMAL, true); + S_StartSound(special, special->info->deathsound); + P_SetMobjState(special, special->info->deathstate); + return; + case MT_NIGHTSBUMPER: // Don't trigger if the stage is ended/failed if (player->exiting) diff --git a/src/p_local.h b/src/p_local.h index 25c9c94c4..8df94fe9e 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -397,6 +397,8 @@ boolean P_CheckMissileRange(mobj_t *actor); void P_NewChaseDir(mobj_t *actor); boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed_t dist); +void P_HomingAttack(mobj_t *source, mobj_t *enemy); + mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers, SINT8 moveforward); void P_InternalFlickySetColor(mobj_t *actor, UINT8 color); #define P_IsFlickyCenter(type) (type > MT_FLICKY_01 && type < MT_SEED && (type - MT_FLICKY_01) % 2 ? 1 : 0) diff --git a/src/p_mobj.c b/src/p_mobj.c index 3e22ac8ff..b4cd4438d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6406,6 +6406,61 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } P_MobjCheckWater(mobj); break; + case MT_AQUABUZZ: + case MT_BIGAIRMINE: + { + if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0 + && P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius * 16) + { + // Home in on the target. + P_HomingAttack(mobj, mobj->tracer); + + if (mobj->z < mobj->floorz) + mobj->z = mobj->floorz; + + if (leveltime % mobj->info->painchance == 0) + S_StartSound(mobj, mobj->info->activesound); + } + else + { + // Try to find a player + P_LookForPlayers(mobj, true, true, mobj->radius * 16); + mobj->momx >>= 1; + mobj->momy >>= 1; + mobj->momz >>= 1; + } + } + break; + case MT_BIGMINE: + { + if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0 + && P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius * 16) + { + P_MobjCheckWater(mobj); + + // Home in on the target. + P_HomingAttack(mobj, mobj->tracer); + + // Don't let it go out of water + if (mobj->z + mobj->height > mobj->watertop) + mobj->z = mobj->watertop - mobj->height; + + if (mobj->z < mobj->floorz) + mobj->z = mobj->floorz; + + if (leveltime % mobj->info->painchance == 0) + S_StartSound(mobj, mobj->info->activesound); + } + else + { + // Try to find a player + P_LookForPlayers(mobj, true, true, mobj->radius * 16); + mobj->momx >>= 1; + mobj->momy >>= 1; + mobj->momz >>= 1; + } + } + break; case MT_FLAME: if (mobj->flags2 & MF2_BOSSNOTRAP) { @@ -8288,21 +8343,21 @@ static void P_MonitorFuseThink(mobj_t *mobj) // This define should make it a lot easier to organize and change monitor weights #define SETMONITORCHANCES(type, strongboxamt, weakboxamt) \ -for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) spawnchance[numchoices++] = type + for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) spawnchance[numchoices++] = type - // Type SRM WRM - SETMONITORCHANCES(MT_SNEAKERS_BOX, 0, 10); // Super Sneakers - SETMONITORCHANCES(MT_INVULN_BOX, 2, 0); // Invincibility - SETMONITORCHANCES(MT_WHIRLWIND_BOX, 3, 8); // Whirlwind Shield - SETMONITORCHANCES(MT_ELEMENTAL_BOX, 3, 8); // Elemental Shield - SETMONITORCHANCES(MT_ATTRACT_BOX, 2, 0); // Attraction Shield - SETMONITORCHANCES(MT_FORCE_BOX, 3, 3); // Force Shield - SETMONITORCHANCES(MT_ARMAGEDDON_BOX, 2, 0); // Armageddon Shield - SETMONITORCHANCES(MT_MIXUP_BOX, 0, 1); // Teleporters - SETMONITORCHANCES(MT_RECYCLER_BOX, 0, 1); // Recycler - SETMONITORCHANCES(MT_1UP_BOX, 1, 1); // 1-Up - // ======================================= - // Total 16 32 + // Type SRM WRM + SETMONITORCHANCES(MT_SNEAKERTV, 0, 10); // Super Sneakers + SETMONITORCHANCES(MT_INV, 2, 0); // Invincibility + SETMONITORCHANCES(MT_WHITETV, 3, 8); // Whirlwind Shield + SETMONITORCHANCES(MT_GREENTV, 3, 8); // Elemental Shield + SETMONITORCHANCES(MT_YELLOWTV, 2, 0); // Attraction Shield + SETMONITORCHANCES(MT_BLUETV, 3, 3); // Force Shield + SETMONITORCHANCES(MT_BLACKTV, 2, 0); // Armageddon Shield + SETMONITORCHANCES(MT_MIXUPBOX, 0, 1); // Teleporters + SETMONITORCHANCES(MT_RECYCLETV, 0, 1); // Recycler + SETMONITORCHANCES(MT_PRUP, 1, 1); // 1-Up + // ====================================== + // Total 16 32 #undef SETMONITORCHANCES @@ -10556,6 +10611,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt case MT_EMBLEM: case MT_RING: case MT_BLUESPHERE: + case MT_EMMY: offset += mthing->args[0] ? 0 : 24*FRACUNIT; break; @@ -11615,6 +11671,35 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean Obj_InitLoopCenter(mobj); break; } + case MT_EMMY: + { + if (mthing->options & MTF_OBJECTSPECIAL) // Mario Block version + mobj->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); + else + { + fixed_t zheight = mobj->z; + mobj_t *tokenobj; + + if (mthing->options & MTF_OBJECTFLIP) + zheight += mobj->height-FixedMul(mobjinfo[MT_TOKEN].height, mobj->scale); // align with emmy properly! + + tokenobj = P_SpawnMobj(mobj->x, mobj->y, zheight, MT_TOKEN); + P_SetTarget(&mobj->tracer, tokenobj); + tokenobj->destscale = mobj->scale; + P_SetScale(tokenobj, mobj->scale); + if (mthing->options & MTF_OBJECTFLIP) // flip token to match emmy + { + tokenobj->eflags |= MFE_VERTICALFLIP; + tokenobj->flags2 |= MF2_OBJECTFLIP; + } + } + + // We advanced tokenbits earlier due to the return check. + // Subtract 1 here for the correct value. + mobj->health = 1 << (tokenbits - 1); + break; + + } case MT_REDDIAG: case MT_YELLOWDIAG: case MT_BLUEDIAG: From a580bc94330d795aa4ba78f0a9cde46235ccf42c Mon Sep 17 00:00:00 2001 From: NepDisk Date: Wed, 9 Apr 2025 16:39:25 -0400 Subject: [PATCH 06/12] Port v1 objects pt 4.5: extra stuff --- src/deh_lua.c | 7 +++++++ src/deh_tables.c | 12 +++++++++++- src/deh_tables.h | 1 + src/doomstat.h | 1 - src/g_game.c | 1 - src/info/mobjs.h | 9 --------- src/info/sprites.h | 1 - src/info/states.h | 13 ------------- src/p_floor.c | 1 - src/p_local.h | 2 +- src/p_mobj.c | 2 -- src/p_mobj.h | 2 +- 12 files changed, 21 insertions(+), 31 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 516f9e2be..c9b750c0b 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -479,6 +479,13 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) CacheAndPushConstant(L, word, i); return 1; } + + if (lua_compatmode) + for (i = 0; MOBJ_ALIASES[i].n; i++) + if (fastcmp(p, MOBJ_ALIASES[i].n)) { + CacheAndPushConstant(L, word, MOBJ_ALIASES[i].v); + return 1; + } return luaL_error(L, "mobjtype '%s' does not exist.\n", word); } else if (fastncmp("SPR_",word,4)) { diff --git a/src/deh_tables.c b/src/deh_tables.c index d8b904ab1..0107d7431 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -128,6 +128,16 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t #undef _ }; +struct int_const_s const MOBJ_ALIASES[] = { + {"BIRD", MT_FLICKY_01}, + {"BUNNY" , MT_FLICKY_02}, + {"MOUSE" , MT_FLICKY_12}, + {"CHICKEN" , MT_FLICKY_03}, + {"REDBIRD", MT_FLICKY_10}, + {"COW", MT_FLICKY_11}, + { NULL, 0 } +}; + const char *const MOBJFLAG_LIST[] = { "SPECIAL", "SOLID", @@ -944,13 +954,13 @@ struct int_const_s const INT_CONST[] = { {"PRECIP_NONE",PRECIP_NONE}, {"PRECIP_RAIN",PRECIP_RAIN}, {"PRECIP_SNOW",PRECIP_SNOW}, - {"PRECIP_BLIZZARD",PRECIP_BLIZZARD}, {"PRECIP_STORM",PRECIP_STORM}, {"PRECIP_STORM_NORAIN",PRECIP_STORM_NORAIN}, {"PRECIP_STORM_NOSTRIKES",PRECIP_STORM_NOSTRIKES}, // Carrying {"CR_NONE",CR_NONE}, + {"CR_SLIDING",CR_SLIDING}, {"CR_ZOOMTUBE",CR_ZOOMTUBE}, // Character flags (skinflags_t) diff --git a/src/deh_tables.h b/src/deh_tables.h index 65f05b0d3..4451f6b51 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -74,6 +74,7 @@ extern actionpointer_t actionpointers[]; // Array mapping action names to action extern const char *const STATE_LIST[]; extern struct int_const_s const STATE_ALIASES[]; extern const char *const MOBJTYPE_LIST[]; +extern struct int_const_s const MOBJ_ALIASES[]; extern const char *const MOBJFLAG_LIST[]; extern const char *const MOBJFLAG2_LIST[]; // \tMF2_(\S+).*// (.+) --> \t"\1", // \2 extern const char *const MOBJEFLAG_LIST[]; diff --git a/src/doomstat.h b/src/doomstat.h index 90ec96e2e..63a368d77 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -76,7 +76,6 @@ typedef enum PRECIP_RAIN, PRECIP_SNOW, - PRECIP_BLIZZARD, PRECIP_STORM, PRECIP_STORM_NORAIN, PRECIP_STORM_NOSTRIKES, diff --git a/src/g_game.c b/src/g_game.c index 62876415b..f0dc9e830 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -107,7 +107,6 @@ precipprops_t precipprops[MAXPRECIP] = {"NONE", MT_NULL, 0}, // PRECIP_NONE {"RAIN", MT_RAIN, 0}, // PRECIP_RAIN {"SNOW", MT_SNOWFLAKE, 0}, // PRECIP_SNOW - {"BLIZZARD", MT_BLIZZARDSNOW, 0}, // PRECIP_BLIZZARD {"STORM", MT_RAIN, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM {"STORM_NORAIN", MT_NULL, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM_NORAIN {"STORM_NOSTRIKES", MT_RAIN, PRECIPFX_THUNDER} // PRECIP_STORM_NOSTRIKES diff --git a/src/info/mobjs.h b/src/info/mobjs.h index 9458fe8de..0eca5525f 100644 --- a/src/info/mobjs.h +++ b/src/info/mobjs.h @@ -426,7 +426,6 @@ _(SEED) // Environmental Effects _(RAIN) // Rain _(SNOWFLAKE) // Snowflake -_(BLIZZARDSNOW) // Blizzard Snowball _(SPLISH) // Water splish! _(LAVASPLISH) // Lava splish! _(SMOKE) @@ -569,14 +568,6 @@ _(ROCKCRUMBLE14) _(ROCKCRUMBLE15) _(ROCKCRUMBLE16) -// Level debris -_(GFZDEBRIS) -_(BRICKDEBRIS) -_(WOODDEBRIS) -_(REDBRICKDEBRIS) // for CEZ3 -_(BLUEBRICKDEBRIS) // for CEZ3 -_(YELLOWBRICKDEBRIS) // for CEZ3 - // SRB1 Badniks _(SRB1_CRAWLA) _(SRB1_BAT) diff --git a/src/info/sprites.h b/src/info/sprites.h index 210902f9d..b8328f6ab 100644 --- a/src/info/sprites.h +++ b/src/info/sprites.h @@ -292,7 +292,6 @@ _(BSTR) // Red Booster // Environmental Effects _(RAIN) // Rain _(SNO1) // Snowflake -_(SNO2) // Blizzard Snowball _(SPLH) // Water Splish _(LSPL) // Lava Splish _(SPLA) // Water Splash diff --git a/src/info/states.h b/src/info/states.h index 1524c4efa..cbeb41bb4 100644 --- a/src/info/states.h +++ b/src/info/states.h @@ -2026,11 +2026,6 @@ _(SNOW1) _(SNOW2) _(SNOW3) -// Blizzard Snowball -_(BLIZZARDSNOW1) -_(BLIZZARDSNOW2) -_(BLIZZARDSNOW3) - // Water Splish _(SPLISH1) _(SPLISH2) @@ -2527,14 +2522,6 @@ _(ROCKCRUMBLEN) _(ROCKCRUMBLEO) _(ROCKCRUMBLEP) -// Level debris -_(GFZDEBRIS) -_(BRICKDEBRIS) -_(WOODDEBRIS) -_(REDBRICKDEBRIS) // for CEZ3 -_(BLUEBRICKDEBRIS) // for CEZ3 -_(YELLOWBRICKDEBRIS) // for CEZ3 - // SRB1 Badniks _(SRB1_CRAWLA1) _(SRB1_CRAWLA2) diff --git a/src/p_floor.c b/src/p_floor.c index 05cfe8191..cbd3bfded 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1030,7 +1030,6 @@ static mobj_t *SearchMarioNode(msecnode_t *node) case MT_SUPERSPARK: case MT_RAIN: case MT_SNOWFLAKE: - case MT_BLIZZARDSNOW: case MT_SPLISH: case MT_LAVASPLISH: case MT_SMOKE: diff --git a/src/p_local.h b/src/p_local.h index 8df94fe9e..dd0980b32 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -577,7 +577,7 @@ struct BasicFF_t #define DMG_SPECTATOR 0x83 #define DMG_TIMEOVER 0x84 // Masks -//free 0x10 // Flag - setting this flag allows objects to damage you if you're already in spinout. The effect is reversed on objects with MF_MISSILE (setting it prevents them from comboing in spinout) +//free 0x10 #define DMG_STEAL 0x20 // Flag - can steal bumpers, will only deal damage to players, and will not deal damage outside Battle Mode. #define DMG_CANTHURTSELF 0x40 // Flag - cannot hurt your self or your team #define DMG_DEATHMASK DMG_INSTAKILL // if bit 7 is set, this is a death type instead of a damage type diff --git a/src/p_mobj.c b/src/p_mobj.c index b4cd4438d..4e8933e12 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5655,8 +5655,6 @@ static void P_MobjSceneryThink(mobj_t *mobj) case MT_ROCKCRUMBLE14: case MT_ROCKCRUMBLE15: case MT_ROCKCRUMBLE16: - case MT_WOODDEBRIS: - case MT_BRICKDEBRIS: if (mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height) && mobj->state != &states[mobj->info->deathstate]) { diff --git a/src/p_mobj.h b/src/p_mobj.h index 32edf7dde..ae887a9f0 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -173,7 +173,7 @@ typedef enum typedef enum { MF2_AXIS = 1, // It's a NiGHTS axis! (For faster checking) - MF2_SHADOW = 1<<3, // DO NOT USE: for lua compatibility only + MF2_SHADOW = 1<<1, // DO NOT USE: for lua compatibility only MF2_DONTRESPAWN = 1<<2, // Don't respawn this object! MF2_DONTDRAW = 1<<3, // DO NOT USE: for lua compatibility only MF2_AUTOMATIC = 1<<4, // Thrown ring has automatic properties From 94cc3ac59f6444e3cac1863463551057c1ceabc5 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Thu, 10 Apr 2025 11:56:54 -0400 Subject: [PATCH 07/12] Remove some confcliting objects --- src/info/mobjs.h | 6 ------ src/info/states.h | 15 --------------- src/p_mobj.c | 46 ---------------------------------------------- 3 files changed, 67 deletions(-) diff --git a/src/info/mobjs.h b/src/info/mobjs.h index 0eca5525f..0783cd339 100644 --- a/src/info/mobjs.h +++ b/src/info/mobjs.h @@ -125,7 +125,6 @@ _(FLINGEMERALD) // Lost emerald // Springs and others _(FAN) _(STEAM) -_(BUMPER) _(BALLOON) _(YELLOWSPRING) @@ -142,11 +141,6 @@ _(REDHORIZ) // Red Horizontal Spring _(BLUEHORIZ) // Blue Horizontal Spring _(GREYHORIZ) // Grey Horizontal Spring -_(BOOSTERSEG) -_(BOOSTERROLLER) -_(YELLOWBOOSTER) -_(REDBOOSTER) - // Interactive Objects _(BUBBLES) // Bubble source _(SIGN) // Level end sign diff --git a/src/info/states.h b/src/info/states.h index cbeb41bb4..c284ab3c0 100644 --- a/src/info/states.h +++ b/src/info/states.h @@ -1918,10 +1918,6 @@ _(STEAM6) _(STEAM7) _(STEAM8) -// Bumpers -_(BUMPER) -_(BUMPERHIT) - // Balloons _(BALLOON) _(BALLOONPOP1) @@ -2006,17 +2002,6 @@ _(GHORIZ2) _(GHORIZ3) _(GHORIZ4) -// Booster -_(BOOSTERSOUND) -_(YELLOWBOOSTERROLLER) -_(YELLOWBOOSTERSEG_LEFT) -_(YELLOWBOOSTERSEG_RIGHT) -_(YELLOWBOOSTERSEG_FACE) -_(REDBOOSTERROLLER) -_(REDBOOSTERSEG_LEFT) -_(REDBOOSTERSEG_RIGHT) -_(REDBOOSTERSEG_FACE) - // Rain _(RAIN1) _(RAINRETURN) diff --git a/src/p_mobj.c b/src/p_mobj.c index 020022cda..4af901fb6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11179,47 +11179,6 @@ static boolean P_SetupParticleGen(mapthing_t *mthing, mobj_t *mobj) return true; } -static boolean P_SetupBooster(mapthing_t* mthing, mobj_t* mobj, boolean strong) -{ - angle_t angle = FixedAngle(mthing->angle << FRACBITS); - fixed_t x1 = FINECOSINE((angle >> ANGLETOFINESHIFT) & FINEMASK); - fixed_t y1 = FINESINE((angle >> ANGLETOFINESHIFT) & FINEMASK); - fixed_t x2 = FINECOSINE(((angle + ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK); - fixed_t y2 = FINESINE(((angle + ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK); - statenum_t facestate = strong ? S_REDBOOSTERSEG_FACE : S_YELLOWBOOSTERSEG_FACE; - statenum_t leftstate = strong ? S_REDBOOSTERSEG_LEFT : S_YELLOWBOOSTERSEG_LEFT; - statenum_t rightstate = strong ? S_REDBOOSTERSEG_RIGHT : S_YELLOWBOOSTERSEG_RIGHT; - statenum_t rollerstate = strong ? S_REDBOOSTERROLLER : S_YELLOWBOOSTERROLLER; - - mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG); - seg->angle = angle - ANGLE_90; - P_SetMobjState(seg, facestate); - seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG); - seg->angle = angle + ANGLE_90; - P_SetMobjState(seg, facestate); - seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG); - seg->angle = angle; - P_SetMobjState(seg, leftstate); - seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG); - seg->angle = angle; - P_SetMobjState(seg, rightstate); - - seg = P_SpawnMobjFromMobj(mobj, 13*(x1 + x2), 13*(y1 + y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, rollerstate); - seg = P_SpawnMobjFromMobj(mobj, 13*(x1 - x2), 13*(y1 - y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, rollerstate); - seg = P_SpawnMobjFromMobj(mobj, -13*(x1 + x2), -13*(y1 + y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, rollerstate); - seg = P_SpawnMobjFromMobj(mobj, -13*(x1 - x2), -13*(y1 - y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, rollerstate); - - return true; -} - static void P_SnapToFinishLine(mobj_t *mobj) { line_t *finishline = P_FindNearestLine(mobj->x, mobj->y, @@ -11380,11 +11339,6 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean break; } break; - case MT_REDBOOSTER: - case MT_YELLOWBOOSTER: - if (!P_SetupBooster(mthing, mobj, mobj->type == MT_REDBOOSTER)) - return false; - break; case MT_AXIS: // Inverted if args[3] is set if (mthing->args[3]) From febd689aabe8a4867a9bab66bafc951895e53b22 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Fri, 11 Apr 2025 22:40:31 -0400 Subject: [PATCH 08/12] Fix some mario mode objects --- src/info/mobjs.h | 2 -- src/info/states.h | 28 +++++++++++++--------------- src/p_inter.c | 2 +- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/info/mobjs.h b/src/info/mobjs.h index 0783cd339..6d1939ea0 100644 --- a/src/info/mobjs.h +++ b/src/info/mobjs.h @@ -479,10 +479,8 @@ _(GOOMBA) _(BLUEGOOMBA) _(FIREFLOWER) _(FIREBALL) -_(FIREBALLTRAIL) _(SHELL) _(PUMA) -_(PUMATRAIL) _(HAMMER) _(KOOPA) _(KOOPAFLAME) diff --git a/src/info/states.h b/src/info/states.h index c284ab3c0..b7cd4477e 100644 --- a/src/info/states.h +++ b/src/info/states.h @@ -2299,22 +2299,20 @@ _(FIREFLOWER1) _(FIREFLOWER2) _(FIREFLOWER3) _(FIREFLOWER4) -_(FIREBALL) -_(FIREBALLTRAIL1) -_(FIREBALLTRAIL2) +_(FIREBALL1) +_(FIREBALL2) +_(FIREBALL3) +_(FIREBALL4) +_(FIREBALLEXP1) +_(FIREBALLEXP2) +_(FIREBALLEXP3) _(SHELL) -_(PUMA_START1) -_(PUMA_START2) -_(PUMA_UP1) -_(PUMA_UP2) -_(PUMA_UP3) -_(PUMA_DOWN1) -_(PUMA_DOWN2) -_(PUMA_DOWN3) -_(PUMATRAIL1) -_(PUMATRAIL2) -_(PUMATRAIL3) -_(PUMATRAIL4) +_(PUMA1) +_(PUMA2) +_(PUMA3) +_(PUMA4) +_(PUMA5) +_(PUMA6) _(HAMMER) _(KOOPA1) _(KOOPA2) diff --git a/src/p_inter.c b/src/p_inter.c index 68aae9b73..a3c102509 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2253,7 +2253,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da K_TryHurtSoundExchange(target, source); } - else if (source && source == player->mo && source->player) + else { K_DestroyBumpers(player, 1); } From 5d886b83ba05e0d9c2379cfa14510baed54f4f46 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sun, 13 Apr 2025 15:07:10 -0400 Subject: [PATCH 09/12] Fix RAGuard and other minor fixes --- src/d_netcmd.c | 2 +- src/k_collide.c | 1 - src/k_kart.c | 35 +++++++++++++++++--------- src/k_kart.h | 65 ++++++++++++++++++++++--------------------------- 4 files changed, 53 insertions(+), 50 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 52cc7c211..f4c47f304 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -7147,7 +7147,7 @@ static void KartChaining_OnChange(void) CONS_Printf(M_GetText("Boost Chaining will be turned \"On\" Next Round.\n")); } } - else if (K_ChainingActive() && !cv_kartstacking.value) + else if (K_ChainingActive() && !cv_kartchaining.value) { if (leveltime < starttime) { diff --git a/src/k_collide.c b/src/k_collide.c index 88adcabff..9d6a21974 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -578,7 +578,6 @@ boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2) { mobj_t *ghost = P_SpawnGhostMobj(t1); - UINT8 i; P_SetScale(ghost, 3*ghost->destscale/2); ghost->destscale = 15*ghost->destscale/2; diff --git a/src/k_kart.c b/src/k_kart.c index a8b6bdf55..133e20998 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -49,11 +49,11 @@ #include "k_follower.h" #include "k_grandprix.h" -consvar_t cv_kartstacking_colorflame = CVAR_INIT ("kartstacking_colorflame", "On", 0, CV_OnOff, NULL); -consvar_t cv_kartstacking_sneakerstacksound = CVAR_INIT ("kartstacking_sneakerstacksound", "On", 0, CV_OnOff, NULL); -consvar_t cv_kartchainingsound = CVAR_INIT ("kartchaining_chainsound", "On", 0, CV_OnOff, NULL); -consvar_t cv_kartdriftsounds = CVAR_INIT ("kartdriftsounds", "On", 0, CV_OnOff, NULL); -consvar_t cv_kartdriftefx = CVAR_INIT ("kartdriftefx", "On", 0, CV_OnOff, NULL); +consvar_t cv_kartstacking_colorflame = CVAR_INIT ("kartstacking_colorflame", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_kartstacking_sneakerstacksound = CVAR_INIT ("kartstacking_sneakerstacksound", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_kartchainingsound = CVAR_INIT ("kartchaining_chainsound", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_kartdriftsounds = CVAR_INIT ("kartdriftsounds", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_kartdriftefx = CVAR_INIT ("kartdriftefx", "On", CV_SAVE, CV_OnOff, NULL); static CV_PossibleValue_t driftsparkpulse_cons_t[] = {{0, "MIN"}, {FRACUNIT*3, "MAX"}, {0, NULL}}; consvar_t cv_driftsparkpulse = CVAR_INIT ("driftsparkpulse", "1.4", CV_SAVE|CV_FLOAT, driftsparkpulse_cons_t, NULL); @@ -3198,20 +3198,31 @@ boolean K_TripwirePass(player_t *player) } // Safe guard cvars to prevent cheating in RA. -INT32 K_RAGuard(consvar_t cvar, SINT8 mode) +INT32 K_RAGuard(consvar_t cvar) { if (modeattacking != ATTACKING_NONE) { - if (mode == RAG_INT) - { - // This is a int, just use atoi the value normally. - return atoi(cvar.defaultvalue); - } - else if (mode == RAG_FLOAT) + if (cvar.flags & CV_FLOAT) { // This is a float, atof the value and run it through FloatToFixed return FloatToFixed(atof(cvar.defaultvalue)); } + else + { + // Handle string bools first. + if (!strcmp(cvar.defaultvalue, "On") || !strcmp(cvar.defaultvalue, "Yes")) + { + return true; + } + + if (!strcmp(cvar.defaultvalue, "Off") || !strcmp(cvar.defaultvalue, "No")) + { + return false; + } + + // This is a int, just use atoi the value normally. + return atoi(cvar.defaultvalue); + } } return cvar.value; diff --git a/src/k_kart.h b/src/k_kart.h index 5dc201177..6c2df086a 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -39,37 +39,37 @@ Make sure this matches the actual number of states // Precalculated constants for stacked boost diminishing // *Somewhat* matches old calc but doesn't use arrays, which makes it faster and more memory efficent -#define CALC_ARG_OFFSET K_RAGuard(cv_kartstacking_calc_arg_offset, RAG_FLOAT) +#define CALC_ARG_OFFSET K_RAGuard(cv_kartstacking_calc_arg_offset) #define CALC_RET_OFFSET FixedSqrt(CALC_ARG_OFFSET) -#define MAXVANILLABOOST K_RAGuard(cv_kartstacking_maxvanillaboost, RAG_FLOAT) -#define SPEEDBOOSTDROPOFF K_RAGuard(cv_kartstacking_speedboostdropoff, RAG_FLOAT) -#define SPEEDBOOSTDROPOFF_BRAKE K_RAGuard(cv_kartstacking_speedboostdropoff_brake, RAG_FLOAT) +#define MAXVANILLABOOST K_RAGuard(cv_kartstacking_maxvanillaboost) +#define SPEEDBOOSTDROPOFF K_RAGuard(cv_kartstacking_speedboostdropoff) +#define SPEEDBOOSTDROPOFF_BRAKE K_RAGuard(cv_kartstacking_speedboostdropoff_brake) // Vanilla Boosts -#define EASYSNEAKERSPEEDBOOST K_RAGuard(cv_kartstacking_sneaker_easyspeedboost, RAG_FLOAT) -#define NORMALSNEAKERSPEEDBOOST K_RAGuard(cv_kartstacking_sneaker_normalspeedboost, RAG_FLOAT) -#define HARDSNEAKERSPEEDBOOST K_RAGuard(cv_kartstacking_sneaker_hardspeedboost, RAG_FLOAT) -#define SNEAKERACCELBOOST K_RAGuard(cv_kartstacking_sneaker_accelboost, RAG_FLOAT) -#define MAXSNEAKERSTACK K_RAGuard(cv_kartstacking_sneaker_maxgrade, RAG_INT) -#define SNEAKERSTACKABLE K_RAGuard(cv_kartstacking_sneaker_stackable, RAG_INT) -#define INVINSPEEDBOOST K_RAGuard(cv_kartstacking_invincibility_speedboost, RAG_FLOAT) -#define INVINACCELBOOST K_RAGuard(cv_kartstacking_invincibility_accelboost, RAG_FLOAT) -#define INVINSTACKABLE K_RAGuard(cv_kartstacking_invincibility_stackable, RAG_INT) -#define GROWSPEEDBOOST K_RAGuard(cv_kartstacking_grow_speedboost, RAG_FLOAT) -#define GROWACCELBOOST K_RAGuard(cv_kartstacking_grow_accelboost, RAG_FLOAT) -#define GROWSTACKABLE K_RAGuard(cv_kartstacking_grow_stackable, RAG_INT) -#define FLAMESPEEDVAL K_RAGuard(cv_kartstacking_flame_speedval, RAG_FLOAT) -#define FLAMEACCELBOOST K_RAGuard(cv_kartstacking_flame_accelboost, RAG_FLOAT) -#define FLAMESTACKABLE K_RAGuard(cv_kartstacking_flame_stackable, RAG_INT) -#define STARTSPEEDBOOST K_RAGuard(cv_kartstacking_start_speedboost, RAG_FLOAT) -#define STARTACCELBOOST K_RAGuard(cv_kartstacking_start_accelboost, RAG_FLOAT) -#define STARTSTACKABLE K_RAGuard(cv_kartstacking_start_stackable, RAG_INT) -#define DRIFTSPEEDBOOST K_RAGuard(cv_kartstacking_drift_speedboost, RAG_FLOAT) -#define DRIFTACCELBOOST K_RAGuard(cv_kartstacking_drift_accelboost, RAG_FLOAT) -#define DRIFTSTACKABLE K_RAGuard(cv_kartstacking_drift_stackable, RAG_INT) -#define RINGSPEEDBOOST K_RAGuard(cv_kartstacking_ring_speedboost, RAG_FLOAT) -#define RINGACCELBOOST K_RAGuard(cv_kartstacking_ring_accelboost, RAG_FLOAT) -#define RINGSTACKABLE K_RAGuard(cv_kartstacking_ring_stackable, RAG_INT) +#define EASYSNEAKERSPEEDBOOST K_RAGuard(cv_kartstacking_sneaker_easyspeedboost) +#define NORMALSNEAKERSPEEDBOOST K_RAGuard(cv_kartstacking_sneaker_normalspeedboost) +#define HARDSNEAKERSPEEDBOOST K_RAGuard(cv_kartstacking_sneaker_hardspeedboost) +#define SNEAKERACCELBOOST K_RAGuard(cv_kartstacking_sneaker_accelboost) +#define MAXSNEAKERSTACK K_RAGuard(cv_kartstacking_sneaker_maxgrade) +#define SNEAKERSTACKABLE K_RAGuard(cv_kartstacking_sneaker_stackable) +#define INVINSPEEDBOOST K_RAGuard(cv_kartstacking_invincibility_speedboost) +#define INVINACCELBOOST K_RAGuard(cv_kartstacking_invincibility_accelboost) +#define INVINSTACKABLE K_RAGuard(cv_kartstacking_invincibility_stackable) +#define GROWSPEEDBOOST K_RAGuard(cv_kartstacking_grow_speedboost) +#define GROWACCELBOOST K_RAGuard(cv_kartstacking_grow_accelboost) +#define GROWSTACKABLE K_RAGuard(cv_kartstacking_grow_stackable) +#define FLAMESPEEDVAL K_RAGuard(cv_kartstacking_flame_speedval) +#define FLAMEACCELBOOST K_RAGuard(cv_kartstacking_flame_accelboost) +#define FLAMESTACKABLE K_RAGuard(cv_kartstacking_flame_stackable) +#define STARTSPEEDBOOST K_RAGuard(cv_kartstacking_start_speedboost) +#define STARTACCELBOOST K_RAGuard(cv_kartstacking_start_accelboost) +#define STARTSTACKABLE K_RAGuard(cv_kartstacking_start_stackable) +#define DRIFTSPEEDBOOST K_RAGuard(cv_kartstacking_drift_speedboost) +#define DRIFTACCELBOOST K_RAGuard(cv_kartstacking_drift_accelboost) +#define DRIFTSTACKABLE K_RAGuard(cv_kartstacking_drift_stackable) +#define RINGSPEEDBOOST K_RAGuard(cv_kartstacking_ring_speedboost) +#define RINGACCELBOOST K_RAGuard(cv_kartstacking_ring_accelboost) +#define RINGSTACKABLE K_RAGuard(cv_kartstacking_ring_stackable) #define CANTCHAINOFFROAD (cv_kartchaining.value && !cv_kartchainingoffroad.value) @@ -106,14 +106,7 @@ typedef enum #define RINGVOLUMEREGEN 1 #define RINGTRANSPARENCYREGEN 3 - -typedef enum -{ - RAG_INT, - RAG_FLOAT, -} raguard_e; - -INT32 K_RAGuard(consvar_t cvar, SINT8 mode); +INT32 K_RAGuard(consvar_t cvar); angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed); From af06da6560007be5c1f3a2e23492cbb2ccea69d8 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sun, 13 Apr 2025 17:39:35 -0400 Subject: [PATCH 10/12] Port v1 objects pt 6: Port 2.1 bosses --- src/info/actions.h | 1 - src/info/mobjs.h | 6 +- src/info/sprites.h | 11 +- src/info/states.h | 168 +++-- src/p_enemy.c | 349 +++------ src/p_inter.c | 13 +- src/p_mobj.c | 1705 +++++++++++++++++++++++++++++++++++++++++++- src/p_setup.c | 13 - src/p_spec.h | 7 - 9 files changed, 1910 insertions(+), 363 deletions(-) diff --git a/src/info/actions.h b/src/info/actions.h index 676e0caac..d52e430d6 100644 --- a/src/info/actions.h +++ b/src/info/actions.h @@ -98,7 +98,6 @@ _(A_SetReactionTime, SETREACTIONTIME) _(A_Boss1Spikeballs, BOSS1SPIKEBALLS) _(A_Boss3TakeDamage, BOSS3TAKEDAMAGE) _(A_Boss3Path, BOSS3PATH) -_(A_Boss3ShockThink, BOSS3SHOCKTHINK) _(A_LinedefExecute, LINEDEFEXECUTE) _(A_LinedefExecuteFromArg, LINEDEFEXECUTEFROMARG) _(A_PlaySeeSound, PLAYSEESOUND) diff --git a/src/info/mobjs.h b/src/info/mobjs.h index 6d1939ea0..834f25b3a 100644 --- a/src/info/mobjs.h +++ b/src/info/mobjs.h @@ -46,7 +46,6 @@ _(BOSSFLYPOINT) _(EGGTRAP) _(BOSS3WAYPOINT) _(BOSS9GATHERPOINT) -_(BOSSJUNK) // Boss 1 _(EGGMOBILE) @@ -59,19 +58,16 @@ _(EGGMOBILE_FIRE) _(EGGMOBILE2) _(EGGMOBILE2_POGO) _(GOOP) -_(GOOPTRAIL) // Boss 3 _(EGGMOBILE3) +_(PROPELLER) _(FAKEMOBILE) -_(SHOCKWAVE) // Boss 4 _(EGGMOBILE4) _(EGGMOBILE4_MACE) _(JETFLAME) -_(EGGROBO1) -_(EGGROBO1JET) // Black Eggman (Boss 7) _(BLACKEGGMAN) diff --git a/src/info/sprites.h b/src/info/sprites.h index b8328f6ab..2f467e73b 100644 --- a/src/info/sprites.h +++ b/src/info/sprites.h @@ -58,18 +58,9 @@ _(SHCK) // Boss 3 Shockwave // Boss 4 (Castle Eggman) _(EGGP) _(EFIR) // Boss 4 jet flame -_(EGR1) // Boss 4 Spectator Eggrobo // Boss 5 (Arid Canyon) -_(FANG) // replaces EGGQ -_(BRKN) -_(WHAT) -_(VWRE) -_(PROJ) // projector light -_(FBOM) -_(FSGN) -_(BARX) // bomb explosion (also used by barrel) -_(BARD) // bomb dust (also used by barrel) +_(EGGQ) // Boss 6 (Red Volcano) _(EGGR) diff --git a/src/info/states.h b/src/info/states.h index b7cd4477e..0c28afde4 100644 --- a/src/info/states.h +++ b/src/info/states.h @@ -323,10 +323,10 @@ _(SONIC3KBOSSEXPLOSION5) _(SONIC3KBOSSEXPLOSION6) _(JETFUME1) +_(JETFUME2) // Boss 1 _(EGGMOBILE_STND) -_(EGGMOBILE_ROFL) _(EGGMOBILE_LATK1) _(EGGMOBILE_LATK2) _(EGGMOBILE_LATK3) @@ -336,6 +336,7 @@ _(EGGMOBILE_LATK6) _(EGGMOBILE_LATK7) _(EGGMOBILE_LATK8) _(EGGMOBILE_LATK9) +_(EGGMOBILE_LATK10) _(EGGMOBILE_RATK1) _(EGGMOBILE_RATK2) _(EGGMOBILE_RATK3) @@ -345,6 +346,7 @@ _(EGGMOBILE_RATK6) _(EGGMOBILE_RATK7) _(EGGMOBILE_RATK8) _(EGGMOBILE_RATK9) +_(EGGMOBILE_RATK10) _(EGGMOBILE_PANIC1) _(EGGMOBILE_PANIC2) _(EGGMOBILE_PANIC3) @@ -355,25 +357,27 @@ _(EGGMOBILE_PANIC7) _(EGGMOBILE_PANIC8) _(EGGMOBILE_PANIC9) _(EGGMOBILE_PANIC10) -_(EGGMOBILE_PANIC11) -_(EGGMOBILE_PANIC12) -_(EGGMOBILE_PANIC13) -_(EGGMOBILE_PANIC14) -_(EGGMOBILE_PANIC15) _(EGGMOBILE_PAIN) _(EGGMOBILE_PAIN2) _(EGGMOBILE_DIE1) _(EGGMOBILE_DIE2) _(EGGMOBILE_DIE3) _(EGGMOBILE_DIE4) +_(EGGMOBILE_DIE5) +_(EGGMOBILE_DIE6) +_(EGGMOBILE_DIE7) +_(EGGMOBILE_DIE8) +_(EGGMOBILE_DIE9) +_(EGGMOBILE_DIE10) +_(EGGMOBILE_DIE11) +_(EGGMOBILE_DIE12) +_(EGGMOBILE_DIE13) +_(EGGMOBILE_DIE14) _(EGGMOBILE_FLEE1) _(EGGMOBILE_FLEE2) _(EGGMOBILE_BALL) _(EGGMOBILE_TARGET) -_(BOSSEGLZ1) -_(BOSSEGLZ2) - // Boss 2 _(EGGMOBILE2_STND) _(EGGMOBILE2_POGO1) @@ -389,6 +393,16 @@ _(EGGMOBILE2_DIE1) _(EGGMOBILE2_DIE2) _(EGGMOBILE2_DIE3) _(EGGMOBILE2_DIE4) +_(EGGMOBILE2_DIE5) +_(EGGMOBILE2_DIE6) +_(EGGMOBILE2_DIE7) +_(EGGMOBILE2_DIE8) +_(EGGMOBILE2_DIE9) +_(EGGMOBILE2_DIE10) +_(EGGMOBILE2_DIE11) +_(EGGMOBILE2_DIE12) +_(EGGMOBILE2_DIE13) +_(EGGMOBILE2_DIE14) _(EGGMOBILE2_FLEE1) _(EGGMOBILE2_FLEE2) @@ -400,11 +414,9 @@ _(BOSSSPIGOT) _(GOOP1) _(GOOP2) _(GOOP3) -_(GOOPTRAIL) // Boss 3 _(EGGMOBILE3_STND) -_(EGGMOBILE3_SHOCK) _(EGGMOBILE3_ATK1) _(EGGMOBILE3_ATK2) _(EGGMOBILE3_ATK3A) @@ -413,16 +425,54 @@ _(EGGMOBILE3_ATK3C) _(EGGMOBILE3_ATK3D) _(EGGMOBILE3_ATK4) _(EGGMOBILE3_ATK5) -_(EGGMOBILE3_ROFL) +_(EGGMOBILE3_LAUGH1) +_(EGGMOBILE3_LAUGH2) +_(EGGMOBILE3_LAUGH3) +_(EGGMOBILE3_LAUGH4) +_(EGGMOBILE3_LAUGH5) +_(EGGMOBILE3_LAUGH6) +_(EGGMOBILE3_LAUGH7) +_(EGGMOBILE3_LAUGH8) +_(EGGMOBILE3_LAUGH9) +_(EGGMOBILE3_LAUGH10) +_(EGGMOBILE3_LAUGH11) +_(EGGMOBILE3_LAUGH12) +_(EGGMOBILE3_LAUGH13) +_(EGGMOBILE3_LAUGH14) +_(EGGMOBILE3_LAUGH15) +_(EGGMOBILE3_LAUGH16) +_(EGGMOBILE3_LAUGH17) +_(EGGMOBILE3_LAUGH18) +_(EGGMOBILE3_LAUGH19) +_(EGGMOBILE3_LAUGH20) _(EGGMOBILE3_PAIN) _(EGGMOBILE3_PAIN2) _(EGGMOBILE3_DIE1) _(EGGMOBILE3_DIE2) _(EGGMOBILE3_DIE3) _(EGGMOBILE3_DIE4) +_(EGGMOBILE3_DIE5) +_(EGGMOBILE3_DIE6) +_(EGGMOBILE3_DIE7) +_(EGGMOBILE3_DIE8) +_(EGGMOBILE3_DIE9) +_(EGGMOBILE3_DIE10) +_(EGGMOBILE3_DIE11) +_(EGGMOBILE3_DIE12) +_(EGGMOBILE3_DIE13) +_(EGGMOBILE3_DIE14) _(EGGMOBILE3_FLEE1) _(EGGMOBILE3_FLEE2) +// Boss 3 Propeller +_(PROPELLER1) +_(PROPELLER2) +_(PROPELLER3) +_(PROPELLER4) +_(PROPELLER5) +_(PROPELLER6) +_(PROPELLER7) + // Boss 3 Pinch _(FAKEMOBILE_INIT) _(FAKEMOBILE) @@ -432,15 +482,8 @@ _(FAKEMOBILE_ATK3A) _(FAKEMOBILE_ATK3B) _(FAKEMOBILE_ATK3C) _(FAKEMOBILE_ATK3D) -_(FAKEMOBILE_DIE1) -_(FAKEMOBILE_DIE2) - -_(BOSSSEBH1) -_(BOSSSEBH2) - -// Boss 3 Shockwave -_(SHOCKWAVE1) -_(SHOCKWAVE2) +_(FAKEMOBILE_ATK4) +_(FAKEMOBILE_ATK5) // Boss 4 _(EGGMOBILE4_STND) @@ -458,30 +501,36 @@ _(EGGMOBILE4_RATK5) _(EGGMOBILE4_RATK6) _(EGGMOBILE4_RAISE1) _(EGGMOBILE4_RAISE2) -_(EGGMOBILE4_PAIN1) -_(EGGMOBILE4_PAIN2) +_(EGGMOBILE4_RAISE3) +_(EGGMOBILE4_RAISE4) +_(EGGMOBILE4_RAISE5) +_(EGGMOBILE4_RAISE6) +_(EGGMOBILE4_RAISE7) +_(EGGMOBILE4_RAISE8) +_(EGGMOBILE4_RAISE9) +_(EGGMOBILE4_RAISE10) +_(EGGMOBILE4_PAIN) _(EGGMOBILE4_DIE1) _(EGGMOBILE4_DIE2) _(EGGMOBILE4_DIE3) _(EGGMOBILE4_DIE4) +_(EGGMOBILE4_DIE5) +_(EGGMOBILE4_DIE6) +_(EGGMOBILE4_DIE7) +_(EGGMOBILE4_DIE8) +_(EGGMOBILE4_DIE9) +_(EGGMOBILE4_DIE10) +_(EGGMOBILE4_DIE11) +_(EGGMOBILE4_DIE12) +_(EGGMOBILE4_DIE13) +_(EGGMOBILE4_DIE14) _(EGGMOBILE4_FLEE1) _(EGGMOBILE4_FLEE2) _(EGGMOBILE4_MACE) -_(EGGMOBILE4_MACE_DIE1) -_(EGGMOBILE4_MACE_DIE2) -_(EGGMOBILE4_MACE_DIE3) // Boss 4 jet flame -_(JETFLAME) - -// Boss 4 Spectator Eggrobo -_(EGGROBO1_STND) -_(EGGROBO1_BSLAP1) -_(EGGROBO1_BSLAP2) -_(EGGROBO1_PISSED) - -// Boss 4 Spectator Eggrobo jet flame -_(EGGROBOJET) +_(JETFLAME1) +_(JETFLAME2) // Black Eggman (Boss 7) _(BLACKEGG_STND) @@ -714,27 +763,54 @@ _(CYBRAKDEMONVILEEXPLOSION2) _(CYBRAKDEMONVILEEXPLOSION3) // Metal Sonic (Race) -_(METALSONIC_RACE) +// S_PLAY_STND +_(METALSONIC_STAND) +// S_PLAY_TAP1 +_(METALSONIC_WAIT1) +_(METALSONIC_WAIT2) +// S_PLAY_RUN1 +_(METALSONIC_WALK1) +_(METALSONIC_WALK2) +_(METALSONIC_WALK3) +_(METALSONIC_WALK4) +_(METALSONIC_WALK5) +_(METALSONIC_WALK6) +_(METALSONIC_WALK7) +_(METALSONIC_WALK8) +// S_PLAY_SPD1 +_(METALSONIC_RUN1) +_(METALSONIC_RUN2) +_(METALSONIC_RUN3) +_(METALSONIC_RUN4) // Metal Sonic (Battle) _(METALSONIC_FLOAT) _(METALSONIC_VECTOR) _(METALSONIC_STUN) +_(METALSONIC_BLOCK) _(METALSONIC_RAISE) _(METALSONIC_GATHER) _(METALSONIC_DASH) _(METALSONIC_BOUNCE) -_(METALSONIC_BADBOUNCE) _(METALSONIC_SHOOT) _(METALSONIC_PAIN) -_(METALSONIC_DEATH1) -_(METALSONIC_DEATH2) -_(METALSONIC_DEATH3) -_(METALSONIC_DEATH4) +_(METALSONIC_DEATH) _(METALSONIC_FLEE1) _(METALSONIC_FLEE2) +_(METALSONIC_FLEE3) +_(METALSONIC_FLEE4) _(MSSHIELD_F1) _(MSSHIELD_F2) +_(MSSHIELD_F3) +_(MSSHIELD_F4) +_(MSSHIELD_F5) +_(MSSHIELD_F6) +_(MSSHIELD_F7) +_(MSSHIELD_F8) +_(MSSHIELD_F9) +_(MSSHIELD_F10) +_(MSSHIELD_F11) +_(MSSHIELD_F12) // Ring _(RING) @@ -1128,14 +1204,6 @@ _(BLUEMONITOREXPLOSION2) _(ROCKET) _(LASER) -_(LASER2) -_(LASERFLASH) - -_(LASERFLAME1) -_(LASERFLAME2) -_(LASERFLAME3) -_(LASERFLAME4) -_(LASERFLAME5) _(TORPEDO) diff --git a/src/p_enemy.c b/src/p_enemy.c index 5179c90ce..ffc0819f8 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2094,29 +2094,23 @@ void A_Boss7FireMissiles(mobj_t *actor) // 3 - Boss 1 Middle // >=3 - Generic middle // +// Function: A_Boss1Laser +// +// Description: Shoot an object at your target ala Bosses: +// +// var1 = object # to shoot +// var2: +// 0 - Boss 1 Left side +// 1 - Boss 1 Right side +// void A_Boss1Laser(mobj_t *actor) { fixed_t x, y, z, floorz, speed; INT32 locvar1 = var1; - INT32 locvar2 = (var2 & 65535); - INT32 upperend = (var2>>16); + INT32 locvar2 = var2; INT32 i; angle_t angle; mobj_t *point; - tic_t dur; - static const UINT8 LASERCOLORS[] = - { - SKINCOLOR_KSUPER3, - SKINCOLOR_KSUPER4, - SKINCOLOR_KSUPER5, - SKINCOLOR_KETCHUP, - SKINCOLOR_RED, - SKINCOLOR_RED, - SKINCOLOR_KETCHUP, - SKINCOLOR_KSUPER5, - SKINCOLOR_KSUPER4, - SKINCOLOR_KSUPER3, - }; if (LUA_CallAction(A_BOSS1LASER, actor)) return; @@ -2124,48 +2118,24 @@ void A_Boss1Laser(mobj_t *actor) if (!actor->target) return; - if (actor->state->tics > 1) - dur = actor->tics; - else - { - if ((upperend & 1) && (actor->extravalue2 > 1)) - actor->extravalue2--; - - dur = actor->extravalue2; - } - switch (locvar2) { case 0: - x = actor->x + P_ReturnThrustX(actor, actor->angle+ANGLE_90, FixedMul(44*FRACUNIT, actor->scale)); - y = actor->y + P_ReturnThrustY(actor, actor->angle+ANGLE_90, FixedMul(44*FRACUNIT, actor->scale)); + x = actor->x + P_ReturnThrustX(actor, actor->angle+ANGLE_90, FixedMul(43*FRACUNIT, actor->scale)); + y = actor->y + P_ReturnThrustY(actor, actor->angle+ANGLE_90, FixedMul(43*FRACUNIT, actor->scale)); if (actor->eflags & MFE_VERTICALFLIP) z = actor->z + actor->height - FixedMul(56*FRACUNIT, actor->scale) - mobjinfo[locvar1].height; else z = actor->z + FixedMul(56*FRACUNIT, actor->scale); break; case 1: - x = actor->x + P_ReturnThrustX(actor, actor->angle-ANGLE_90, FixedMul(44*FRACUNIT, actor->scale)); - y = actor->y + P_ReturnThrustY(actor, actor->angle-ANGLE_90, FixedMul(44*FRACUNIT, actor->scale)); + x = actor->x + P_ReturnThrustX(actor, actor->angle-ANGLE_90, FixedMul(43*FRACUNIT, actor->scale)); + y = actor->y + P_ReturnThrustY(actor, actor->angle-ANGLE_90, FixedMul(43*FRACUNIT, actor->scale)); if (actor->eflags & MFE_VERTICALFLIP) z = actor->z + actor->height - FixedMul(56*FRACUNIT, actor->scale) - mobjinfo[locvar1].height; else z = actor->z + FixedMul(56*FRACUNIT, actor->scale); break; - case 2: - var1 = locvar1; var2 = 3; // Fire middle laser - A_Boss1Laser(actor); - var1 = locvar1; var2 = 0; // Fire left laser - A_Boss1Laser(actor); - var1 = locvar1; var2 = 1; // Fire right laser - A_Boss1Laser(actor); - return; - break; - case 3: - x = actor->x + P_ReturnThrustX(actor, actor->angle, FixedMul(42*FRACUNIT, actor->scale)); - y = actor->y + P_ReturnThrustY(actor, actor->angle, FixedMul(42*FRACUNIT, actor->scale)); - z = actor->z + actor->height/2; - break; default: x = actor->x; y = actor->y; @@ -2173,25 +2143,30 @@ void A_Boss1Laser(mobj_t *actor) break; } - if (!(actor->flags2 & MF2_FIRING) && dur > 1) + if (!(actor->flags2 & MF2_FIRING)) { actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y); if (mobjinfo[locvar1].seesound) S_StartSound(actor, mobjinfo[locvar1].seesound); - - point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET); - point->angle = actor->angle; - point->fuse = dur+1; - P_SetTarget(&point->target, actor->target); - P_SetTarget(&actor->target, point); + if (!(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)) + { + point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET); + point->fuse = actor->tics+1; + P_SetTarget(&point->target, actor->target); + P_SetTarget(&actor->target, point); + } } + else if (actor->target && !(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)) + actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y); - angle = R_PointToAngle2(z + (mobjinfo[locvar1].height>>1), 0, actor->target->z, R_PointToDist2(x, y, actor->target->x, actor->target->y)); - + if (actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH) + angle = FixedAngle(FixedDiv(actor->tics*160*FRACUNIT, actor->state->tics*FRACUNIT) + 10*FRACUNIT); + else + angle = R_PointToAngle2(z + (mobjinfo[locvar1].height>>1), 0, actor->target->z, R_PointToDist2(x, y, actor->target->x, actor->target->y)); point = P_SpawnMobj(x, y, z, locvar1); P_SetTarget(&point->target, actor); point->angle = actor->angle; - speed = point->radius; + speed = point->radius*2; point->momz = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), speed); point->momx = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(point->angle>>ANGLETOFINESHIFT), speed)); point->momy = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINESINE(point->angle>>ANGLETOFINESHIFT), speed)); @@ -2200,72 +2175,26 @@ void A_Boss1Laser(mobj_t *actor) { mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type); mo->angle = point->angle; - mo->color = LASERCOLORS[((UINT8)(i + 3*dur) >> 2) % sizeof(LASERCOLORS)]; // codeing P_UnsetThingPosition(mo); - mo->flags = MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY; + mo->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY; P_SetThingPosition(mo); - if (dur & 1 && mo->info->missilestate) - { - P_SetMobjState(mo, mo->info->missilestate); - if (mo->info->meleestate) - { - mobj_t *mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_PARTICLE); - mo2->flags2 |= MF2_LINKDRAW; - P_SetTarget(&mo2->tracer, actor); - P_SetMobjState(mo2, mo->info->meleestate); - } - } - - if (dur == 1) - P_SpawnGhostMobj(mo); - x = point->x, y = point->y, z = point->z; if (P_RailThinker(point)) break; } - x += point->momx; - y += point->momy; floorz = P_FloorzAtPos(x, y, z, mobjinfo[MT_EGGMOBILE_FIRE].height); - if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1 && dur & 1) + if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1) { - point = P_SpawnMobj(x, y, floorz, MT_EGGMOBILE_FIRE); - point->angle = actor->angle; - point->destscale = actor->scale; - P_SetScale(point, point->destscale); + point = P_SpawnMobj(x, y, floorz+1, MT_EGGMOBILE_FIRE); P_SetTarget(&point->target, actor); - P_MobjCheckWater(point); - if (point->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) - { - for (i = 0; i < 2; i++) - { - UINT8 size = 3; - mobj_t *steam = P_SpawnMobj(x, y, point->watertop - size*mobjinfo[MT_DUST].height, MT_DUST); - P_SetScale(steam, size*actor->scale); - P_SetObjectMomZ(steam, FRACUNIT + 2*P_RandomFixed(), true); - P_InstaThrust(steam, FixedAngle(P_RandomKey(360)*FRACUNIT), 2*P_RandomFixed()); - if (point->info->painsound) - S_StartSound(steam, point->info->painsound); - } - } - else - { - fixed_t distx = P_ReturnThrustX(point, point->angle, point->radius); - fixed_t disty = P_ReturnThrustY(point, point->angle, point->radius); - if (P_TryMove(point, point->x + distx, point->y + disty, false, NULL) // prevents the sprite from clipping into the wall or dangling off ledges - && P_TryMove(point, point->x - 2*distx, point->y - 2*disty, false, NULL) - && P_TryMove(point, point->x + distx, point->y + disty, false, NULL)) - { - if (point->info->seesound) - S_StartSound(point, point->info->seesound); - } - else - P_RemoveMobj(point); - } + point->destscale = 3*FRACUNIT; + point->scalespeed = FRACUNIT>>2; + point->fuse = TICRATE; } - if (dur > 1) + if (actor->tics > 1) actor->flags2 |= MF2_FIRING; else actor->flags2 &= ~MF2_FIRING; @@ -2278,16 +2207,11 @@ void A_Boss1Laser(mobj_t *actor) // var1: // 0 - accelerative focus with friction // 1 - steady focus with fixed movement speed -// anything else - don't move -// var2: -// 0 - don't trace target, just move forwards -// & 1 - change horizontal angle -// & 2 - change vertical angle +// var2 = unused // void A_FocusTarget(mobj_t *actor) { INT32 locvar1 = var1; - INT32 locvar2 = var2; if (LUA_CallAction(A_FOCUSTARGET, actor)) return; @@ -2295,9 +2219,9 @@ void A_FocusTarget(mobj_t *actor) if (actor->target) { fixed_t speed = FixedMul(actor->info->speed, actor->scale); - fixed_t dist = (locvar2 ? R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y) : speed+1); - angle_t hangle = ((locvar2 & 1) ? R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) : actor->angle); - angle_t vangle = ((locvar2 & 2) ? R_PointToAngle2(actor->z , 0, actor->target->z + (actor->target->height>>1), dist) : ANGLE_90); + fixed_t dist = R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y); + angle_t vangle = R_PointToAngle2(actor->z , 0, actor->target->z + (actor->target->height>>1), dist); + angle_t hangle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); switch(locvar1) { case 0: @@ -6143,7 +6067,9 @@ void A_Boss3TakeDamage(mobj_t *actor) return; actor->movecount = var1; - actor->movefactor = -512*FRACUNIT; + + if (actor->target && actor->target->spawnpoint) + actor->threshold = actor->target->spawnpoint->extrainfo; } // Function: A_Boss3Path @@ -6178,28 +6104,24 @@ void A_Boss3Path(mobj_t *actor) } else if (actor->threshold >= 0) // Traveling mode { - fixed_t dist = 0; + thinker_t *th; + mobj_t *mo2; + fixed_t dist, dist2; fixed_t speed; - if (!(actor->flags2 & MF2_STRONGBOX)) + P_SetTarget(&actor->target, NULL); + + // scan the thinkers + // to find a point that matches + // the number + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - mobj_t *mo2; - INT32 i; + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; - P_SetTarget(&actor->target, NULL); - - // Find waypoint - TAG_ITER_THINGS(actor->cusval, i) + mo2 = (mobj_t *)th; + if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint && mo2->spawnpoint->angle == actor->threshold) { - mo2 = mapthings[i].mobj; - - if (!mo2) - continue; - if (mo2->type != MT_BOSS3WAYPOINT) - continue; - if (mapthings[i].args[0] != actor->threshold) - continue; - P_SetTarget(&actor->target, mo2); break; } @@ -6207,117 +6129,67 @@ void A_Boss3Path(mobj_t *actor) if (!actor->target) // Should NEVER happen { - CONS_Debug(DBG_GAMELOGIC, "Error: Boss 3 Dummy was unable to find specified waypoint: %d, %d\n", actor->threshold, actor->cusval); + CONS_Debug(DBG_GAMELOGIC, "Error: Boss 3 Dummy was unable to find specified waypoint: %d\n", actor->threshold); return; } + dist = P_AproxDistance(P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z - actor->z); + + if (dist < 1) + dist = 1; + if (actor->tracer && ((actor->tracer->movedir) || (actor->tracer->health <= actor->tracer->info->damage))) speed = actor->info->speed * 2; else speed = actor->info->speed; - if (actor->target->x == actor->x && actor->target->y == actor->y) - { - dist = P_AproxDistance(P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z + actor->movefactor - actor->z); + actor->momx = FixedMul(FixedDiv(actor->target->x - actor->x, dist), speed); + actor->momy = FixedMul(FixedDiv(actor->target->y - actor->y, dist), speed); + actor->momz = FixedMul(FixedDiv(actor->target->z - actor->z, dist), speed); - if (dist < 1) - dist = 1; + if (actor->momx != 0 || actor->momy != 0) + actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); - actor->momx = FixedMul(FixedDiv(actor->target->x - actor->x, dist), speed); - actor->momy = FixedMul(FixedDiv(actor->target->y - actor->y, dist), speed); - actor->momz = FixedMul(FixedDiv(actor->target->z + actor->movefactor - actor->z, dist), speed); + dist2 = P_AproxDistance(P_AproxDistance(actor->target->x - (actor->x + actor->momx), actor->target->y - (actor->y + actor->momy)), actor->target->z - (actor->z + actor->momz)); - if (actor->momx != 0 || actor->momy != 0) - actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); - } + if (dist2 < 1) + dist2 = 1; - if (dist <= speed) + if ((dist >> FRACBITS) <= (dist2 >> FRACBITS)) { // If further away, set XYZ of mobj to waypoint location P_UnsetThingPosition(actor); actor->x = actor->target->x; actor->y = actor->target->y; - actor->z = actor->target->z + actor->movefactor; + actor->z = actor->target->z; actor->momx = actor->momy = actor->momz = 0; P_SetThingPosition(actor); - if (!actor->movefactor) // firing mode - { - actor->movecount |= 2; - actor->movefactor = -512*FRACUNIT; - actor->flags2 &= ~MF2_STRONGBOX; - } - else if (!(actor->flags2 & MF2_STRONGBOX)) // just spawned or going down - { - actor->flags2 |= MF2_STRONGBOX; - actor->movefactor = -512*FRACUNIT; - } - else if (!(actor->flags2 & MF2_AMBUSH)) // just shifted tube - { - actor->flags2 |= MF2_AMBUSH; - actor->movefactor = 0; - } - else // just hit the bottom of your tube + if (actor->threshold == 0) { P_RemoveMobj(actor); // Cycle completed. Dummy removed. return; } - } - } -} -// Function: A_Boss3ShockThink -// -// Description: Inserts new interstitial shockwave objects when the space between others spreads too much. -// -// var1 = unused -// var2 = unused -// -void A_Boss3ShockThink(mobj_t *actor) -{ - if (LUA_CallAction(A_BOSS3SHOCKTHINK, actor)) - return; + // Set to next waypoint in sequence + if (actor->target->spawnpoint) + { + // From the center point, choose one of the five paths + if (actor->target->spawnpoint->angle == 0) + { + P_RemoveMobj(actor); // Cycle completed. Dummy removed. + return; + } + else + actor->threshold = actor->target->spawnpoint->extrainfo; - if (actor->momx || actor->momy) - actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy) + ANGLE_90; - - if (actor->hnext && !P_MobjWasRemoved(actor->hnext)) - { - mobj_t *snext = actor->hnext; - mobj_t *snew; - fixed_t x0, y0, x1, y1; - - // Break the link if movements are too different - if (R_PointToDist2(0, 0, snext->momx - actor->momx, snext->momy - actor->momy) > 12*actor->scale) - { - P_SetTarget(&actor->hnext, NULL); - return; - } - - // Check distance between shockwave objects to determine whether interstitial ones should be spawned - x0 = actor->x; - y0 = actor->y; - x1 = snext->x; - y1 = snext->y; - if (R_PointToDist2(0, 0, x1 - x0, y1 - y0) > 2*actor->radius) - { - snew = P_SpawnMobj((x0 >> 1) + (x1 >> 1), - (y0 >> 1) + (y1 >> 1), - (actor->z >> 1) + (snext->z >> 1), actor->type); - snew->momx = (actor->momx + snext->momx) >> 1; - snew->momy = (actor->momy + snext->momy) >> 1; - snew->momz = (actor->momz + snext->momz) >> 1; // is this really needed? - snew->angle = (actor->angle + snext->angle) >> 1; - P_SetTarget(&snew->target, actor->target); - snew->fuse = actor->fuse; - - P_SetScale(snew, actor->scale); - snew->destscale = actor->destscale; - snew->scalespeed = actor->scalespeed; - - P_SetTarget(&actor->hnext, snew); - P_SetTarget(&snew->hnext, snext); + // If the deaf flag is set, go into firing mode + if (actor->target->spawnpoint->options & MTF_AMBUSH) + actor->movecount |= 2; + } + else // This should never happen, as well + CONS_Debug(DBG_GAMELOGIC, "Error: Boss 3 Dummy waypoint has no spawnpoint associated with it.\n"); } } } @@ -7167,7 +7039,7 @@ void A_SetObjectFlags2(mobj_t *actor) // // var1: // 0 - Triple jet fume pattern -// 1 - Unused (formerly Boss 3's propeller) +// 1 - Boss 3's propeller // 2 - Metal Sonic jet fume // 3 - Boss 4 jet flame // var2 = unused @@ -7226,12 +7098,12 @@ void A_BossJetFume(mobj_t *actor) P_SetTarget(&actor->tracer, filler); } - /*else if (locvar1 == 1) // Boss 3 propeller + else if (locvar1 == 1) // Boss 3 propeller { fixed_t jetx, jety, jetz; - jetx = actor->x + P_ReturnThrustX(actor, actor->angle, -60*actor->scale); - jety = actor->y + P_ReturnThrustY(actor, actor->angle, -60*actor->scale); + jetx = actor->x + P_ReturnThrustX(actor, actor->angle, -FixedMul(60*FRACUNIT, actor->scale)); + jety = actor->y + P_ReturnThrustY(actor, actor->angle, -FixedMul(60*FRACUNIT, actor->scale)); if (actor->eflags & MFE_VERTICALFLIP) jetz = actor->z + actor->height - FixedMul(17*FRACUNIT + mobjinfo[MT_PROPELLER].height, actor->scale); else @@ -7246,18 +7118,17 @@ void A_BossJetFume(mobj_t *actor) filler->angle = actor->angle - ANGLE_180; P_SetTarget(&actor->tracer, filler); - }*/ + } else if (locvar1 == 2) // Metal Sonic jet fumes { filler = P_SpawnMobj(actor->x, actor->y, actor->z, MT_JETFUME1); P_SetTarget(&filler->target, actor); filler->fuse = 59; P_SetTarget(&actor->tracer, filler); - P_SetScale(filler, (filler->destscale = actor->scale/3)); + filler->destscale = actor->scale/2; + P_SetScale(filler, filler->destscale); if (actor->eflags & MFE_VERTICALFLIP) filler->flags2 |= MF2_OBJECTFLIP; - filler->color = SKINCOLOR_CYAN; - filler->colorized = true; } else if (locvar1 == 3) // Boss 4 jet flame { @@ -7265,7 +7136,7 @@ void A_BossJetFume(mobj_t *actor) if (actor->eflags & MFE_VERTICALFLIP) jetz = actor->z + actor->height + FixedMul(50*FRACUNIT - mobjinfo[MT_JETFLAME].height, actor->scale); else - jetz = actor->z - 50*actor->scale; + jetz = actor->z - FixedMul(50*FRACUNIT, actor->scale); filler = P_SpawnMobj(actor->x, actor->y, jetz, MT_JETFLAME); P_SetTarget(&filler->target, actor); // Boss 4 already uses its tracer for other things @@ -7274,30 +7145,6 @@ void A_BossJetFume(mobj_t *actor) if (actor->eflags & MFE_VERTICALFLIP) filler->flags2 |= MF2_OBJECTFLIP; } - else if (locvar1 == 4) // Boss 4 Spectator Eggrobo jet flame - { - fixed_t jetx, jety, jetz, movefactor = 12; - - jetz = actor->z; - if (actor->eflags & MFE_VERTICALFLIP) - jetz += (actor->height - FixedMul(mobjinfo[MT_EGGROBO1JET].height, actor->scale)); - - while (true) - { - jetx = actor->x + P_ReturnThrustX(actor, actor->angle+ANGLE_90, movefactor*actor->scale) - P_ReturnThrustX(actor, actor->angle, 19*actor->scale); - jety = actor->y + P_ReturnThrustY(actor, actor->angle+ANGLE_90, movefactor*actor->scale) - P_ReturnThrustY(actor, actor->angle, 19*actor->scale); - filler = P_SpawnMobj(jetx, jety, jetz, MT_EGGROBO1JET); - filler->movefactor = movefactor; - P_SetTarget(&filler->target, actor); - filler->destscale = actor->scale; - P_SetScale(filler, filler->destscale); - if (actor->eflags & MFE_VERTICALFLIP) - filler->flags2 |= MF2_OBJECTFLIP; - if (movefactor <= 0) - break; - movefactor = -movefactor; - } - } } // Function: A_RandomState diff --git a/src/p_inter.c b/src/p_inter.c index a3c102509..d79a6cc5c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1498,7 +1498,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget case MT_EGGMOBILE3: { - mobj_t *mo2; thinker_t *th; UINT32 i = 0; // to check how many clones we've removed @@ -1514,20 +1513,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (mo->tracer != target) continue; - P_KillMobj(mo, inflictor, source, damagetype); - mo->destscale = mo->scale/8; - mo->scalespeed = (mo->scale - mo->destscale)/(2*TICRATE); - mo->momz = mo->info->speed; - mo->angle = FixedAngle((P_RandomKey(36)*10)<angle = mo->angle; - P_SetMobjState(mo2, S_BOSSSEBH2); + P_RemoveMobj(mo); if (++i == 2) // we've already removed 2 of these, let's stop now break; - else - S_StartSound(mo, mo->info->deathsound); // done once to prevent sound stacking } } break; diff --git a/src/p_mobj.c b/src/p_mobj.c index 4af901fb6..5a5c12730 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4353,6 +4353,1559 @@ static void P_GenericBossThinker(mobj_t *mobj) } } +// AI for the first boss. +static void P_Boss1Thinker(mobj_t *mobj) +{ + if (mobj->flags2 & MF2_FRET && (statenum_t)(mobj->state-states) == mobj->info->spawnstate) { + mobj->flags2 &= ~(MF2_FRET|MF2_SKULLFLY); + mobj->momx = mobj->momy = mobj->momz = 0; + } + + if (!mobj->tracer) + { + var1 = 0; + A_BossJetFume(mobj); + } + + if (!mobj->target || !(mobj->target->flags & MF_SHOOTABLE)) + { + if (mobj->target && mobj->target->health + && mobj->target->type == MT_EGGMOBILE_TARGET) // Oh, we're just firing our laser. + return; // It's okay, then. + + if (mobj->health <= 0) + { + if (P_BossTargetPlayer(mobj, false) && mobj->info->mass) // Bid farewell! + S_StartSound(mobj, mobj->info->mass); + return; + } + + // look for a new target + if (P_BossTargetPlayer(mobj, false) && mobj->info->seesound) + S_StartSound(mobj, mobj->info->seesound); + + return; + } + + if (mobj->state != &states[mobj->info->spawnstate] && mobj->health > 0 && mobj->flags & MF_FLOAT && !(mobj->flags2 & MF2_SKULLFLY)) + mobj->momz = FixedMul(mobj->momz,7*FRACUNIT/8); + + if (mobj->state == &states[mobj->info->meleestate] + || (mobj->state == &states[mobj->info->missilestate] + && mobj->health > mobj->info->damage)) + { + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); + } +} + +// AI for the second boss. +// No, it does NOT convert "Boss" to a "Thinker". =P +static void P_Boss2Thinker(mobj_t *mobj) +{ + if (mobj->movecount) + mobj->movecount--; + + if (!mobj->movecount) + mobj->flags2 &= ~MF2_FRET; + + if (!mobj->tracer) + { + var1 = 0; + A_BossJetFume(mobj); + } + + if (mobj->health <= mobj->info->damage && (!mobj->target || !(mobj->target->flags & MF_SHOOTABLE))) + { + if (mobj->health <= 0) + { + // look for a new target + if (P_BossTargetPlayer(mobj, false) && mobj->info->mass) // Bid farewell! + S_StartSound(mobj, mobj->info->mass); + return; + } + + // look for a new target + if (P_BossTargetPlayer(mobj, false) && mobj->info->seesound) + S_StartSound(mobj, mobj->info->seesound); + + return; + } + + if (mobj->state == &states[mobj->info->spawnstate] && mobj->health > mobj->info->damage) + A_Boss2Chase(mobj); + else if (mobj->health > 0 && mobj->state != &states[mobj->info->painstate] && mobj->state != &states[mobjinfo[mobj->info->missilestate].raisestate]) + { + mobj->flags &= ~MF_NOGRAVITY; + A_Boss2Pogo(mobj); + P_LinedefExecute(LE_PINCHPHASE, mobj, NULL); + } +} + +// AI for the third boss. +// +// Notes for reminders: +// movedir = move 2x fast? +// movecount = fire missiles? +// reactiontime = shock the water? +// threshold = next waypoint # +// extravalue1 = previous time shock sound was used +// +static void P_Boss3Thinker(mobj_t *mobj) +{ + if (mobj->state == &states[mobj->info->spawnstate]) + mobj->flags2 &= ~MF2_FRET; + + if (mobj->flags2 & MF2_FRET) + mobj->movedir = 1; + + if (!mobj->tracer) + { + var1 = 1; + A_BossJetFume(mobj); + } + + if (mobj->health <= 0) + { + mobj->movecount = 0; + mobj->reactiontime = 0; + + if (mobj->state < &states[mobj->info->xdeathstate]) + return; + + if (mobj->threshold == -1) + { + mobj->momz = mobj->info->speed; + return; + } + } + + if (mobj->reactiontime) // Shock mode + { + UINT32 i; + + if (mobj->state != &states[mobj->info->spawnstate]) + P_SetMobjState(mobj, mobj->info->spawnstate); + + mobj->reactiontime--; + if (!mobj->reactiontime) + { + ffloor_t *rover; + + // Shock the water + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + + if (!players[i].mo) + continue; + + if (players[i].mo->health <= 0) + continue; + + if (players[i].mo->eflags & MFE_UNDERWATER) + P_DamageMobj(players[i].mo, mobj, mobj, 1, DMG_VOLTAGE); + } + + // Make the water flash + for (i = 0; i < numsectors; i++) + { + if (!sectors[i].ffloors) + continue; + + for (rover = sectors[i].ffloors; rover; rover = rover->next) + { + if (!(rover->fofflags & FOF_EXISTS)) + continue; + + if (!(rover->fofflags & FOF_SWIMMABLE)) + continue; + + P_SpawnLightningFlash(rover->master->frontsector); + break; + } + } + + if ((UINT32)mobj->extravalue1 + TICRATE*2 < leveltime) + { + mobj->extravalue1 = (INT32)leveltime; + S_StartSound(0, sfx_buzz1); + } + + // If in the center, check to make sure + // none of the players are in the water + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + + if (!players[i].mo || players[i].bot) + continue; + + if (players[i].mo->health <= 0) + continue; + + if (players[i].mo->eflags & MFE_UNDERWATER) + { // Stay put + mobj->reactiontime = 2*TICRATE; + return; + } + } + } + + if (!mobj->reactiontime && mobj->health <= mobj->info->damage) + { // Spawn pinch dummies from the center when we're leaving it. + thinker_t *th; + mobj_t *mo2; + mobj_t *dummy; + SINT8 way = mobj->threshold - 1; // 0 through 4. + SINT8 way2; + + i = 0; // reset i to 0 so we can check how many clones we've removed + + // scan the thinkers to make sure all the old pinch dummies are gone before making new ones + // this can happen if the boss was hurt earlier than expected + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo2 = (mobj_t *)th; + if (mo2->type == (mobjtype_t)mobj->info->mass && mo2->tracer == mobj) + { + P_RemoveMobj(mo2); + i++; + } + if (i == 2) // we've already removed 2 of these, let's stop now + break; + } + + way = (way + P_RandomRange(1,3)) % 5; // dummy 1 at one of the first three options after eggmobile + dummy = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->info->mass); + dummy->angle = mobj->angle; + dummy->threshold = way + 1; + P_SetTarget(&dummy->tracer, mobj); + + do + way2 = (way + P_RandomRange(1,3)) % 5; // dummy 2 has to be careful, + while (way2 == mobj->threshold - 1); // to make sure it doesn't try to go the Eggman Way if dummy 1 rolled high. + dummy = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->info->mass); + dummy->angle = mobj->angle; + dummy->threshold = way2 + 1; + P_SetTarget(&dummy->tracer, mobj); + + CONS_Debug(DBG_GAMELOGIC, "Eggman path %d - Dummy selected paths %d and %d\n", mobj->threshold, way + 1, dummy->threshold); + P_LinedefExecute(LE_PINCHPHASE, mobj, NULL); + } + } + else if (mobj->movecount) // Firing mode + { + UINT32 i; + + // look for a new target + P_BossTargetPlayer(mobj, false); + + if (!mobj->target || !mobj->target->player) + return; + + // Are there any players underwater? If so, shock them! + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + + if (!players[i].mo || players[i].bot) + continue; + + if (players[i].mo->health <= 0) + continue; + + if (players[i].mo->eflags & MFE_UNDERWATER) + { + mobj->movecount = 0; + P_SetMobjState(mobj, mobj->info->spawnstate); + return; + } + } + + // Always face your target. + A_FaceTarget(mobj); + + // Check if the attack animation is running. If not, play it. + if (mobj->state < &states[mobj->info->missilestate] || mobj->state > &states[mobj->info->raisestate]) + { + if (mobj->health <= mobj->info->damage) // pinch phase + mobj->movecount--; // limited number of shots before diving again + if (mobj->movecount) + P_SetMobjState(mobj, mobj->info->missilestate); + } + } + else if (mobj->threshold >= 0) // Traveling mode + { + thinker_t *th; + mobj_t *mo2; + fixed_t dist, dist2; + fixed_t speed; + + P_SetTarget(&mobj->target, NULL); + + if (mobj->state != &states[mobj->info->spawnstate] && mobj->health > 0 + && !(mobj->flags2 & MF2_FRET)) + P_SetMobjState(mobj, mobj->info->spawnstate); + + // scan the thinkers + // to find a point that matches + // the number + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo2 = (mobj_t *)th; + + if (!mo2) + continue; + + if (mo2->type != MT_BOSS3WAYPOINT) + continue; + + if (!mo2->spawnpoint) + continue; + + if (mo2->spawnpoint->angle != mobj->threshold) + continue; + + P_SetTarget(&mobj->target, mo2); + break; + } + + if (!mobj->target) // Should NEVER happen + { + CONS_Debug(DBG_GAMELOGIC, "Error: Boss 3 was unable to find specified waypoint: %d\n", mobj->threshold); + return; + } + + dist = P_AproxDistance(P_AproxDistance(mobj->target->x - mobj->x, mobj->target->y - mobj->y), mobj->target->z - mobj->z); + + if (dist < 1) + dist = 1; + + if ((mobj->movedir) || (mobj->health <= mobj->info->damage)) + speed = mobj->info->speed * 2; + else + speed = mobj->info->speed; + + mobj->momx = FixedMul(FixedDiv(mobj->target->x - mobj->x, dist), speed); + mobj->momy = FixedMul(FixedDiv(mobj->target->y - mobj->y, dist), speed); + mobj->momz = FixedMul(FixedDiv(mobj->target->z - mobj->z, dist), speed); + + if (mobj->momx != 0 || mobj->momy != 0) + mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); + + dist2 = P_AproxDistance(P_AproxDistance(mobj->target->x - (mobj->x + mobj->momx), mobj->target->y - (mobj->y + mobj->momy)), mobj->target->z - (mobj->z + mobj->momz)); + + if (dist2 < 1) + dist2 = 1; + + if ((dist >> FRACBITS) <= (dist2 >> FRACBITS)) + { + // If further away, set XYZ of mobj to waypoint location + P_UnsetThingPosition(mobj); + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + mobj->z = mobj->target->z; + mobj->momx = mobj->momy = mobj->momz = 0; + P_SetThingPosition(mobj); + + if (mobj->threshold == 0) + { + mobj->reactiontime = 1; // Bzzt! Shock the water! + mobj->movedir = 0; + + if (mobj->health <= 0) + { + mobj->flags |= MF_NOGRAVITY|MF_NOCLIP; + mobj->flags |= MF_NOCLIPHEIGHT; + mobj->threshold = -1; + return; + } + } + + // Set to next waypoint in sequence + if (mobj->target->spawnpoint) + { + // From the center point, choose one of the five paths + if (mobj->target->spawnpoint->angle == 0) + mobj->threshold = P_RandomRange(1,5); + else + mobj->threshold = mobj->target->spawnpoint->extrainfo; + + // If the deaf flag is set, go into firing mode + if (mobj->target->spawnpoint->options & MTF_AMBUSH) + mobj->movecount = mobj->health+1; + } + else // This should never happen, as well + CONS_Debug(DBG_GAMELOGIC, "Error: Boss 3 waypoint has no spawnpoint associated with it.\n"); + } + } +} + +// Move Boss4's sectors by delta. +static boolean P_Boss4MoveCage(mobj_t *mobj, fixed_t delta) +{ + INT32 snum; + sector_t *sector; + boolean gotcage = false; + + if (!mobj->spawnpoint) + return false; + + TAG_ITER_SECTORS(mobj->spawnpoint->args[4], snum) + { + sector = §ors[snum]; + sector->floorheight += delta; + sector->ceilingheight += delta; + P_CheckSector(sector, true); + gotcage = true; + } + return gotcage; +} + +// Move Boss4's arms to angle +static void P_Boss4MoveSpikeballs(mobj_t *mobj, angle_t angle, fixed_t fz) +{ + INT32 s; + mobj_t *base = mobj, *seg; + fixed_t dist, bz = mobj->watertop+(16<tracer)) + { + for (seg = base, dist = 172*FRACUNIT, s = 9; seg; seg = seg->hnext, dist += 124*FRACUNIT, --s) + P_MoveOrigin(seg, mobj->x + P_ReturnThrustX(mobj, angle, dist), mobj->y + P_ReturnThrustY(mobj, angle, dist), bz + FixedMul(fz, FixedDiv(s<watertop+(16<tracer)) + { + for (seg = base, dist = 112*FRACUNIT, s = 9; seg; seg = seg->hnext, dist += 132*FRACUNIT, --s) + { + seg->z = bz + FixedMul(fz, FixedDiv(s<x + P_ReturnThrustX(mobj, angle, dist), mobj->y + P_ReturnThrustY(mobj, angle, dist), true, NULL); + } + angle += ANGLE_MAX/3; + } +} + +// Destroy cage FOFs. +static void P_Boss4DestroyCage(mobj_t *mobj) +{ + INT32 snum; + size_t a; + sector_t *sector, *rsec; + ffloor_t *rover; + + if (!mobj->spawnpoint) + return; + + TAG_ITER_SECTORS(mobj->spawnpoint->args[4], snum) + { + sector = §ors[snum]; + + // Destroy the FOFs. + for (a = 0; a < sector->numattached; a++) + { + rsec = §ors[sector->attached[a]]; + for (rover = rsec->ffloors; rover; rover = rover->next) + if (rover->fofflags & FOF_EXISTS && rover->secnum == (size_t)snum) + { + if (rover->fofflags & FOF_RENDERALL) // checking for FF_RENDERANY. + EV_CrumbleChain(rsec, rover); // This FOF is visible to some extent? Crumble it. + else // Completely invisible FOF + { + // no longer exists (can't collide with again) + rover->fofflags &= ~FOF_EXISTS; + sector->moved = true; + rsec->moved = true; + } + } + } + } +} + +// Destroy Boss4's arms +static void P_Boss4PopSpikeballs(mobj_t *mobj) +{ + mobj_t *base = mobj->tracer, *seg, *next; + P_SetTarget(&mobj->tracer, NULL); + while(base) + { + next = base->tracer; + P_SetTarget(&base->tracer, NULL); + for (seg = base; seg; seg = seg->hnext) + { + if (seg->health) + P_KillMobj(seg, NULL, NULL, DMG_INSTAKILL); + } + base = next; + } +} + +// +// AI for the fourth boss. +// +static void P_Boss4Thinker(mobj_t *mobj) +{ + if ((statenum_t)(mobj->state-states) == mobj->info->spawnstate) + { + if (mobj->health > mobj->info->damage || mobj->movedir == 4) + mobj->flags2 &= ~MF2_FRET; + mobj->reactiontime = 0; // Drop the cage immediately. + } + + // Oh no, we dead? D: + if (!mobj->health) + { + if (mobj->tracer) // need to clean up! + { + P_Boss4DestroyCage(mobj); // Just in case pinch phase was skipped. + P_Boss4PopSpikeballs(mobj); + } + return; + } + + // movedir == battle stage: + // 0: initialization + // 1: phase 1 forward + // 2: phase 1 reverse + // 3: pinch rise + // 4: pinch phase + switch(mobj->movedir) + { + // WELCOME to your DOOM! + case 0: + { + // For this stage only: + // movecount == cage height + // threshold == cage momz + if (mobj->movecount == 0) // Initialize stage! + { + fixed_t z; + INT32 i, arm; + mobj_t *seg, *base = mobj; + // First frame init, spawn all the things. + mobj->watertop = mobj->z; + z = mobj->z + mobj->height/2 - mobjinfo[MT_EGGMOBILE4_MACE].height/2; + for (arm = 0; arm <3 ; arm++) + { + seg = P_SpawnMobj(mobj->x, mobj->y, z, MT_EGGMOBILE4_MACE); + P_SetTarget(&base->tracer, seg); + base = seg; + P_SetTarget(&seg->target, mobj); + for (i = 0; i < 9; i++) + { + P_SetTarget(&seg->hnext, P_SpawnMobj(mobj->x, mobj->y, z, MT_EGGMOBILE4_MACE)); + P_SetTarget(&seg->hnext->hprev, seg); + seg = seg->hnext; + } + } + // Move the cage up to the sky. + mobj->movecount = 800*FRACUNIT; + if (!P_Boss4MoveCage(mobj, mobj->movecount)) + { + mobj->movecount = 0; + mobj->threshold = 3*TICRATE; + mobj->extravalue1 = 1; + mobj->movedir++; // We don't have a cage, just continue. + } + else + P_Boss4MoveSpikeballs(mobj, 0, mobj->movecount); + } + else // Cage slams down over Eggman's head! + { + fixed_t oldz = mobj->movecount; + mobj->threshold -= 5*FRACUNIT; + mobj->movecount += mobj->threshold; + if (mobj->movecount < 0) + mobj->movecount = 0; + P_Boss4MoveCage(mobj, mobj->movecount - oldz); + P_Boss4MoveSpikeballs(mobj, 0, mobj->movecount); + if (mobj->movecount == 0) + { + mobj->threshold = 3*TICRATE; + mobj->extravalue1 = 1; + P_LinedefExecute(LE_BOSS4DROP, mobj, NULL); + mobj->movedir++; // Initialization complete, next phase! + } + } + return; + } + + // Normal operation + case 1: + case 2: + break; + + // Pinch phase init! + case 3: + { + fixed_t z; + if (mobj->z < mobj->watertop+(512<momz = 8*FRACUNIT; + else + { + mobj->momz = 0; + mobj->movedir++; + } + mobj->movecount += 400<<(FRACBITS>>1); + mobj->movecount %= 360*FRACUNIT; + z = mobj->z - mobj->watertop - mobjinfo[MT_EGGMOBILE4_MACE].height - mobj->height/2; + if (z < 0) // We haven't risen high enough to pull the spikeballs along yet + P_Boss4MoveSpikeballs(mobj, FixedAngle(mobj->movecount), 0); // So don't pull the spikeballs along yet. + else + P_Boss4PinchSpikeballs(mobj, FixedAngle(mobj->movecount), z); + return; + } + // Pinch phase! + case 4: + { + if (mobj->z < (mobj->watertop + ((512+128*(mobj->info->damage-mobj->health))<momz = 8*FRACUNIT; + else + mobj->momz = 0; + mobj->movecount += (800+800*(mobj->info->damage-mobj->health))<<(FRACBITS>>1); + mobj->movecount %= 360*FRACUNIT; + P_Boss4PinchSpikeballs(mobj, FixedAngle(mobj->movecount), mobj->z - mobj->watertop - mobjinfo[MT_EGGMOBILE4_MACE].height - mobj->height/2); + + if (!mobj->target || !mobj->target->health) + P_SupermanLook4Players(mobj); + A_FaceTarget(mobj); + return; + } + + default: // ????? + return; + } + + // Haahahahahaaa, and let the FUN.. BEGIN! + // movedir == arms direction + // movecount == arms angle + // threshold == countdown to next attack + // reactiontime == cage raise, speed burst + // movefactor == cage z + // friction == turns until helm lift + + // Raise the cage! + if (mobj->reactiontime == 1) + { + fixed_t oldz = mobj->movefactor; + mobj->movefactor += 8*FRACUNIT; + if (mobj->movefactor > 128*FRACUNIT) + mobj->movefactor = 128*FRACUNIT; + P_Boss4MoveCage(mobj, mobj->movefactor - oldz); + } + // Drop the cage! + else if (mobj->movefactor) + { + fixed_t oldz = mobj->movefactor; + mobj->movefactor -= 4*FRACUNIT; + if (mobj->movefactor < 0) + mobj->movefactor = 0; + P_Boss4MoveCage(mobj, mobj->movefactor - oldz); + if (!mobj->movefactor) + { + if (mobj->health <= mobj->info->damage) + { // Proceed to pinch phase! + P_Boss4DestroyCage(mobj); + mobj->movedir = 3; + P_LinedefExecute(LE_PINCHPHASE, mobj, NULL); + return; + } + P_LinedefExecute(LE_BOSS4DROP, mobj, NULL); + } + } + + { + fixed_t movespeed = 170<<(FRACBITS>>1); + if (mobj->reactiontime == 2) + movespeed *= 3; + if (mobj->movedir == 2) + mobj->movecount -= movespeed; + else + mobj->movecount += movespeed; + } + mobj->movecount %= 360*FRACUNIT; + P_Boss4MoveSpikeballs(mobj, FixedAngle(mobj->movecount), mobj->movefactor); + + // Check for attacks, always tick the timer even while animating!! + if (!(mobj->flags2 & MF2_FRET) // but pause for pain so we don't interrupt pinch phase, eep! + && mobj->threshold-- == 0) + { + // 5 -> 2.5 second timer + mobj->threshold = 5*TICRATE-(TICRATE/2)*(mobj->info->spawnhealth-mobj->health); + if (mobj->threshold < 1) + mobj->threshold = 1; + + if (mobj->extravalue1-- == 0) + { + P_SetMobjState(mobj, mobj->info->raisestate); + mobj->extravalue1 = 3; + } + else + { + if (mobj->reactiontime == 1) // Cage is raised? + mobj->reactiontime = 0; // Drop it! + switch(P_RandomKey(10)) + { + // Telegraph Right (Speed Up!!) + case 1: + case 3: + case 4: + case 5: + case 6: + P_SetMobjState(mobj, mobj->info->missilestate); + break; + // Telegraph Left (Reverse Direction) + default: + P_SetMobjState(mobj, mobj->info->meleestate); + break; + } + } + } + + // Leave if animating. + if ((statenum_t)(mobj->state-states) != mobj->info->spawnstate) + return; + + // Map allows us to get killed despite cage being down? + if (mobj->health <= mobj->info->damage) + { // Proceed to pinch phase! + P_Boss4DestroyCage(mobj); + // spawn jet's flame now you're flying upwards + // tracer is already used, so if this ever gets reached again we've got problems + var1 = 3; + A_BossJetFume(mobj); + mobj->movedir = 3; + P_LinedefExecute(LE_PINCHPHASE, mobj, NULL); + return; + } + + mobj->reactiontime = 0; // Drop the cage if it hasn't been dropped already. + if (!mobj->target || !mobj->target->health) + P_SupermanLook4Players(mobj); + A_FaceTarget(mobj); +} + +// +// AI for Black Eggman +// Note: You CANNOT have more than ONE Black Eggman +// in a level! Just don't try it! +// +static void P_Boss7Thinker(mobj_t *mobj) +{ + if (!mobj->target || !(mobj->target->flags & MF_SHOOTABLE)) + { + // look for a new target + if (P_BossTargetPlayer(mobj, false)) + return; // got a new target + + P_SetMobjStateNF(mobj, mobj->info->spawnstate); + return; + } + + if (mobj->health >= mobj->info->spawnhealth && (leveltime & 14) == 0) + { + mobj_t *smoke = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height, MT_SMOKE); + smoke->destscale = mobj->destscale; + P_SetScale(smoke, smoke->destscale); + smoke->momz = FixedMul(FRACUNIT, smoke->scale); + } + + if (mobj->state == &states[S_BLACKEGG_STND] && mobj->tics == mobj->state->tics) + { + mobj->reactiontime += P_RandomByte(); + + if (mobj->health <= mobj->info->damage) + mobj->reactiontime /= 4; + } + else if (mobj->state == &states[S_BLACKEGG_DIE4] && mobj->tics == mobj->state->tics) + A_BossDeath(mobj); + else if (mobj->state >= &states[S_BLACKEGG_WALK1] + && mobj->state <= &states[S_BLACKEGG_WALK6]) + A_Boss7Chase(mobj); + else if (mobj->state == &states[S_BLACKEGG_PAIN1] && mobj->tics == mobj->state->tics) + { + if (mobj->health > 0) + mobj->health--; + + S_StartSound(0, (mobj->health) ? sfx_behurt : sfx_bedie2); + + mobj->reactiontime /= 3; + + if (mobj->health <= 0) + { + INT32 i; + + P_KillMobj(mobj, NULL, NULL, DMG_INSTAKILL); + + // It was a team effort + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + P_AddPlayerScore(&players[i], 1000); + } + } + } + else if (mobj->state == &states[S_BLACKEGG_PAIN35] && mobj->tics == 1) + { + if (mobj->health == mobj->info->damage) + { + // Begin platform destruction + mobj->flags2 |= MF2_FRET; + P_SetMobjState(mobj, mobj->info->raisestate); + P_LinedefExecute(LE_PINCHPHASE, mobj, NULL); + } + } + else if (mobj->state == &states[S_BLACKEGG_HITFACE4] && mobj->tics == mobj->state->tics) + { + // This is where Black Eggman hits his face. + // If a player is on top of him, the player gets hurt. + // But, if the player has managed to escape, + // Black Eggman gets hurt! + INT32 i; + mobj->state->nextstate = mobj->info->painstate; // Reset + + S_StartSound(0, sfx_bedeen); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + + if (!players[i].mo) + continue; + + if (players[i].mo->health <= 0) + continue; + + if (P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y) > (mobj->radius + players[i].mo->radius)) + continue; + + if (players[i].mo->z > mobj->z + mobj->height - FRACUNIT + && players[i].mo->z < mobj->z + mobj->height + 128*FRACUNIT) // You can't be in the vicinity, either... + { + // Punch him! + P_DamageMobj(players[i].mo, mobj, mobj, 1, DMG_NORMAL); + mobj->state->nextstate = mobj->info->spawnstate; + + // Laugh + S_StartSound(0, sfx_bewar1 + P_RandomKey(4)); + } + } + } + else if (mobj->state == &states[S_BLACKEGG_GOOP]) + { + // Lob cannon balls + if (mobj->movecount-- <= 0 || !mobj->target) + { + P_SetMobjState(mobj, mobj->info->spawnstate); + return; + } + + if ((leveltime & 15) == 0) + { + var1 = MT_CANNONBALL; + + var2 = 2*TICRATE + (80<<16); + + A_LobShot(mobj); + S_StartSound(0, sfx_begoop); + } + } + else if (mobj->state == &states[S_BLACKEGG_SHOOT2]) + { + // Chaingun goop + mobj_t *missile; + + if (mobj->movecount-- <= 0 || !mobj->target) + { + P_SetMobjState(mobj, mobj->info->spawnstate); + return; + } + + A_FaceTarget(mobj); + + missile = P_SpawnXYZMissile(mobj, mobj->target, MT_BLACKEGGMAN_GOOPFIRE, + mobj->x + P_ReturnThrustX(mobj, mobj->angle-ANGLE_90, FixedDiv(mobj->radius, 3*FRACUNIT/2)+(4*FRACUNIT)), + mobj->y + P_ReturnThrustY(mobj, mobj->angle-ANGLE_90, FixedDiv(mobj->radius, 3*FRACUNIT/2)+(4*FRACUNIT)), + mobj->z + FixedDiv(mobj->height, 3*FRACUNIT/2)); + + S_StopSound(missile); + + if (leveltime & 1) + S_StartSound(0, sfx_beshot); + } + else if (mobj->state == &states[S_BLACKEGG_JUMP1] && mobj->tics == 1) + { + mobj_t *hitspot = NULL, *mo2; + angle_t an; + fixed_t dist, closestdist; + fixed_t vertical, horizontal; + fixed_t airtime = 5*TICRATE; + INT32 waypointNum = 0; + thinker_t *th; + INT32 i; + boolean foundgoop = false; + INT32 closestNum; + + // Looks for players in goop. If you find one, try to jump on him. + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + + if (!players[i].mo) + continue; + + if (players[i].mo->health <= 0) + continue; + + if (players[i].powers[pw_ingoop]) + { + closestNum = -1; + closestdist = 16384*FRACUNIT; // Just in case... + + // Find waypoint he is closest to + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo2 = (mobj_t *)th; + if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint) + { + dist = P_AproxDistance(players[i].mo->x - mo2->x, players[i].mo->y - mo2->y); + + if (closestNum == -1 || dist < closestdist) + { + closestNum = (mo2->spawnpoint->options & 7); + closestdist = dist; + foundgoop = true; + } + } + } + waypointNum = closestNum; + break; + } + } + + if (!foundgoop) + { + if (mobj->z > 1056*FRACUNIT) + waypointNum = 0; + else + waypointNum = 1 + P_RandomKey(4); + } + + // Don't jump to the center when health is low. + // Force the player to beat you with missiles. + if (mobj->health <= mobj->info->damage && waypointNum == 0) + waypointNum = 1 + P_RandomKey(4); + + if (mobj->tracer && mobj->tracer->type == MT_BOSS3WAYPOINT + && mobj->tracer->spawnpoint && (mobj->tracer->spawnpoint->options & 7) == waypointNum) + { + if (P_RandomChance(FRACUNIT/2)) + waypointNum++; + else + waypointNum--; + + waypointNum %= 5; + + if (waypointNum < 0) + waypointNum = 0; + } + + if (waypointNum == 0 && mobj->health <= mobj->info->damage) + waypointNum = 1 + (P_RandomFixed() & 1); + + // scan the thinkers to find + // the waypoint to use + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo2 = (mobj_t *)th; + if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint && (mo2->spawnpoint->options & 7) == waypointNum) + { + hitspot = mo2; + break; + } + } + + if (hitspot == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "BlackEggman unable to find waypoint #%d!\n", waypointNum); + P_SetMobjState(mobj, mobj->info->spawnstate); + return; + } + + P_SetTarget(&mobj->tracer, hitspot); + + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, hitspot->x, hitspot->y); + + an = mobj->angle; + an >>= ANGLETOFINESHIFT; + + dist = P_AproxDistance(hitspot->x - mobj->x, hitspot->y - mobj->y); + + horizontal = dist / airtime; + vertical = (gravity*airtime)/2; + + mobj->momx = FixedMul(horizontal, FINECOSINE(an)); + mobj->momy = FixedMul(horizontal, FINESINE(an)); + mobj->momz = vertical; + +// mobj->momz = 10*FRACUNIT; + } + else if (mobj->state == &states[S_BLACKEGG_JUMP2] && mobj->z <= mobj->floorz) + { + // BANG! onto the ground + INT32 i,j; + fixed_t ns; + fixed_t x,y,z; + mobj_t *mo2; + + S_StartSound(0, sfx_befall); + + z = mobj->floorz; + for (j = 0; j < 2; j++) + { + for (i = 0; i < 32; i++) + { + const angle_t fa = (i*FINEANGLES/16) & FINEMASK; + ns = 64 * FRACUNIT; + x = mobj->x + FixedMul(FINESINE(fa),ns); + y = mobj->y + FixedMul(FINECOSINE(fa),ns); + + mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE); + ns = 16 * FRACUNIT; + mo2->momx = FixedMul(FINESINE(fa),ns); + mo2->momy = FixedMul(FINECOSINE(fa),ns); + } + z -= 32*FRACUNIT; + } + + // Hurt player?? + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + + if (!players[i].mo) + continue; + + if (players[i].mo->health <= 0) + continue; + + if (P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y) > mobj->radius*4) + continue; + + if (players[i].mo->z > mobj->z + 128*FRACUNIT) + continue; + + if (players[i].mo->z < mobj->z - 64*FRACUNIT) + continue; + + P_DamageMobj(players[i].mo, mobj, mobj, 1, DMG_NORMAL); + + // Laugh + S_StartSound(0, sfx_bewar1 + P_RandomKey(4)); + } + + P_SetMobjState(mobj, mobj->info->spawnstate); + } + else if (mobj->state == &states[mobj->info->deathstate] && mobj->tics == mobj->state->tics) + S_StartSound(0, sfx_bedie1 + (P_RandomFixed() & 1)); + +} + +// Metal Sonic battle boss +// You CAN put multiple Metal Sonics in a single map +// because I am a totally competent programmer who can do shit right. +static void P_Boss9Thinker(mobj_t *mobj) +{ + TryMoveResult_t result = {0}; + + if ((statenum_t)(mobj->state-states) == mobj->info->spawnstate) + mobj->flags2 &= ~MF2_FRET; + + if (!mobj->tracer) + { + thinker_t *th; + mobj_t *mo2; + mobj_t *last=NULL; + + // Initialize the boss, spawn jet fumes, etc. + mobj->threshold = 0; + mobj->reactiontime = 0; + mobj->watertop = mobj->floorz + 32*FRACUNIT; + var1 = 2; + A_BossJetFume(mobj); + + // Run through the thinkers ONCE and find all of the MT_BOSS9GATHERPOINT in the map. + // Build a hoop linked list of 'em! + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo2 = (mobj_t *)th; + if (mo2->type == MT_BOSS9GATHERPOINT) + { + if (last) + P_SetTarget(&last->hnext, mo2); + else + P_SetTarget(&mobj->hnext, mo2); + P_SetTarget(&mo2->hprev, last); + last = mo2; + } + } + } + + if (mobj->health <= 0) + return; + + if ((!mobj->target || !(mobj->target->flags & MF_SHOOTABLE))) + { + P_BossTargetPlayer(mobj, false); + if (mobj->target && !P_IsObjectOnGround(mobj->target)) + P_SetTarget(&mobj->target, NULL); // Wait for them to hit the ground first + if (!mobj->target) // Still no target, aww. + { + // Reset the boss. + P_SetMobjState(mobj, mobj->info->spawnstate); + mobj->fuse = 0; + mobj->momx = FixedDiv(mobj->momx, FRACUNIT + (FRACUNIT>>2)); + mobj->momy = FixedDiv(mobj->momy, FRACUNIT + (FRACUNIT>>2)); + mobj->momz = FixedDiv(mobj->momz, FRACUNIT + (FRACUNIT>>2)); + return; + } + else if (!mobj->fuse) + mobj->fuse = 10*TICRATE; + } + + // AI goes here. + { + boolean danger = true; + angle_t angle; + if (mobj->threshold) + mobj->momz = (mobj->watertop-mobj->z)/16; // Float to your desired position FASTER + else + mobj->momz = (mobj->watertop-mobj->z)/40; // Float to your desired position + + if (mobj->movecount == 2) + { + mobj_t *spawner; + fixed_t dist = 0; + angle = 0x06000000*leveltime; + + // Alter your energy bubble's size/position + if (mobj->health > 3) + { + mobj->tracer->destscale = FRACUNIT + (4*TICRATE - mobj->fuse)*(FRACUNIT/2)/TICRATE + FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT),FRACUNIT/2); + P_SetScale(mobj->tracer, mobj->tracer->destscale); + P_SetOrigin(mobj->tracer, mobj->x, mobj->y, mobj->z + mobj->height/2 - mobj->tracer->height/2); + mobj->tracer->momx = mobj->momx; + mobj->tracer->momy = mobj->momy; + mobj->tracer->momz = mobj->momz; + } + + // Face your target + P_BossTargetPlayer(mobj, true); + angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); // absolute angle + angle = (angle-mobj->angle); // relative angle + if (angle < ANGLE_180) + mobj->angle += angle/8; + else + mobj->angle -= InvAngle(angle)/8; + + // Spawn energy particles + for (spawner = mobj->hnext; spawner; spawner = spawner->hnext) + { + dist = P_AproxDistance(spawner->x - mobj->x, spawner->y - mobj->y); + if (P_RandomRange(1,(dist>>FRACBITS)/16) == 1) + break; + } + if (spawner && dist) + { + mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER); + missile->momz = FixedDiv(missile->momz, 7*FRACUNIT/4); + missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy)); + if (missile->fuse > mobj->fuse) + P_RemoveMobj(missile); + } + } + + // Pre-threshold reactiontime stuff for attack phases + if (mobj->reactiontime && mobj->movecount == 3) + { + if (mobj->movedir == 0 || mobj->movedir == 2) // Pausing between bounces in the pinball phase + { + if (mobj->target->player->powers[pw_tailsfly]) // Trying to escape, eh? + mobj->watertop = mobj->target->z + mobj->target->momz*6; // Readjust your aim. >:3 + else + mobj->watertop = mobj->target->floorz + 16*FRACUNIT; + if (!(mobj->threshold%4)) + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x + mobj->target->momx*4, mobj->target->y + mobj->target->momy*4); + } + // Pausing between energy ball shots + mobj->reactiontime--; + return; + } + + // threshold is used for attacks/maneuvers. + if (mobj->threshold) + { + fixed_t speed = 20*FRACUNIT + FixedMul(40*FRACUNIT, FixedDiv((mobj->info->spawnhealth - mobj->health)<info->spawnhealth<movecount == 3 && mobj->movedir == 1) + { + if (!(mobj->threshold&1)) + { + mobj_t *missile; + if (mobj->info->seesound) + S_StartSound(mobj, mobj->info->seesound); + P_SetMobjState(mobj, mobj->info->missilestate); + if (mobj->extravalue1 == 3) + mobj->reactiontime = TICRATE/16; + else + mobj->reactiontime = TICRATE/8; + + A_FaceTarget(mobj); + missile = P_SpawnMissile(mobj, mobj->target, mobj->info->speed); + if (mobj->extravalue1 == 2 || mobj->extravalue1 == 3) + { + missile->destscale = FRACUNIT>>1; + P_SetScale(missile, missile->destscale); + } + missile->fuse = 3*TICRATE; + missile->z -= missile->height/2; + + if (mobj->extravalue1 == 2) + { + int i; + mobj_t *spread; + missile->flags |= MF_MISSILE; + for (i = 0; i < 5; i++) + { + if (i == 2) + continue; + spread = P_SpawnMobj(missile->x, missile->y, missile->z, missile->type); + spread->angle = missile->angle+(ANGLE_11hh/2)*(i-2); + P_InstaThrust(spread,spread->angle,spread->info->speed); + spread->momz = missile->momz; + spread->destscale = FRACUNIT>>1; + P_SetScale(spread, spread->destscale); + spread->fuse = 3*TICRATE; + } + missile->flags &= ~MF_MISSILE; + } + } + else + { + P_SetMobjState(mobj, mobj->state->nextstate); + if (mobj->extravalue1 == 3) + mobj->reactiontime = TICRATE/8; + else + mobj->reactiontime = TICRATE/4; + } + mobj->threshold--; + return; + } + + P_SpawnGhostMobj(mobj); + + // Pinball attack! + if (mobj->movecount == 3 && (mobj->movedir == 0 || mobj->movedir == 2)) + { + if ((statenum_t)(mobj->state-states) != mobj->info->seestate) + P_SetMobjState(mobj, mobj->info->seestate); + if (mobj->movedir == 0) // mobj health == 1 + P_InstaThrust(mobj, mobj->angle, 38*FRACUNIT); + else if (mobj->health == 3) + P_InstaThrust(mobj, mobj->angle, 22*FRACUNIT); + else // mobj health == 2 + P_InstaThrust(mobj, mobj->angle, 30*FRACUNIT); + + if (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true, &result)) // Hit a wall? Find a direction to bounce + { + mobj->threshold--; + if (mobj->threshold) + { + P_SetMobjState(mobj, mobj->state->nextstate); + if (mobj->info->mass) + S_StartSound(mobj, mobj->info->mass); + if (!(mobj->threshold%4)) // We've decided to lock onto the player this bounce. + { + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x + mobj->target->momx*4, mobj->target->y + mobj->target->momy*4); + mobj->reactiontime = TICRATE; // targetting time + } + else // No homing, just use P_BounceMove + { + P_BounceMove(mobj, &result); + mobj->angle = R_PointToAngle2(0,0,mobj->momx,mobj->momy); + mobj->reactiontime = TICRATE/4; // just a pause before you bounce away + } + mobj->momx = mobj->momy = 0; + } + } + return; + } + + // Vector form dodge! + mobj->angle += mobj->movedir; + P_InstaThrust(mobj, mobj->angle, -speed); + while (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true, &result) && tries++ < 16) + { + mobj->angle += mobj->movedir; + P_InstaThrust(mobj, mobj->angle, -speed); + } + mobj->momx = mobj->momy = 0; + mobj->threshold--; + if (!mobj->threshold) + { // Go into stun after dodge. + // from 3*TICRATE down to 1.25*TICRATE + //mobj->reactiontime = 5*TICRATE/4 + (FixedMul((7*TICRATE/4)<health-1)<info->spawnhealth-1)<>FRACBITS); + // from 3*TICRATE down to 2*TICRATE + mobj->reactiontime = 2*TICRATE + (FixedMul((1*TICRATE)<health-1)<info->spawnhealth-1)<>FRACBITS); + mobj->flags |= MF_SPECIAL|MF_SHOOTABLE; + P_SetMobjState(mobj, mobj->state->nextstate); + } + return; + } + + angle = 0x06000000*leveltime; + mobj->momz += FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT),2*FRACUNIT); // Use that "angle" to bob gently in the air + // This is below threshold because we don't want to bob while zipping around + + // Ohh you're in for it now.. + if (mobj->flags2 & MF2_FRET && mobj->health <= mobj->info->damage) + mobj->fuse = 0; + + // reactiontime is used for delays. + if (mobj->reactiontime) + { + // Stunned after vector form + if (mobj->movedir > ANGLE_180) + mobj->angle -= FixedAngle(FixedMul(AngleFixed(InvAngle(mobj->movedir)),FixedDiv(mobj->reactiontime<angle += FixedAngle(FixedMul(AngleFixed(mobj->movedir),FixedDiv(mobj->reactiontime<reactiontime--; + if (!mobj->reactiontime) + // Out of stun. + P_SetMobjState(mobj, mobj->state->nextstate); + return; + } + + // Not stunned? Can hit. + // Here because stun won't always get the chance to complete due to pinch phase activating, being hit, etc. + mobj->flags &= ~(MF_SPECIAL|MF_SHOOTABLE); + + if (mobj->health <= mobj->info->damage && mobj->fuse && !(mobj->fuse%TICRATE)) + { + var1 = 1; + var2 = 0; + A_BossScream(mobj); + } + + // Don't move if we're still in pain! + if (mobj->flags2 & MF2_FRET) + return; + + if (mobj->state == &states[mobj->info->raisestate]) // Charging energy + { + if (mobj->momx != 0 || mobj->momy != 0) // Apply the air breaks + { + if (abs(mobj->momx)+abs(mobj->momy) < FRACUNIT) + mobj->momx = mobj->momy = 0; + else + P_Thrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), -6*FRACUNIT/8); + } + return; + } + + if (mobj->fuse == 0) + { + // It's time to attack! What are we gonna do?! + switch(mobj->movecount) + { + case 0: + default: + // Fly up and prepare for an attack! + // We have to charge up first, so let's go up into the air + P_SetMobjState(mobj, mobj->info->raisestate); + if (mobj->floorz >= mobj->target->floorz) + mobj->watertop = mobj->floorz + 256*FRACUNIT; + else + mobj->watertop = mobj->target->floorz + 256*FRACUNIT; + break; + + case 1: + { + // Okay, we're up? Good, time to gather energy... + if (mobj->health > mobj->info->damage) + { // No more bubble if we're broken (pinch phase) + mobj_t *shield = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_MSSHIELD_FRONT); + P_SetTarget(&mobj->tracer, shield); + P_SetTarget(&shield->target, mobj); + } + else + P_LinedefExecute(LE_PINCHPHASE, mobj, NULL); + mobj->fuse = 4*TICRATE; + mobj->flags |= MF_PAIN; + if (mobj->info->attacksound) + S_StartSound(mobj, mobj->info->attacksound); + A_FaceTarget(mobj); + break; + } + + case 2: + // We're all charged and ready now! Unleash the fury!! + if (mobj->health > mobj->info->damage) + { + mobj_t *removemobj = mobj->tracer; + P_SetTarget(&mobj->tracer, mobj->hnext); + P_RemoveMobj(removemobj); + } + if (mobj->health <= mobj->info->damage) + { + // Attack 1: Pinball dash! + if (mobj->health == 1) + mobj->movedir = 0; + else + mobj->movedir = 2; + if (mobj->info->seesound) + S_StartSound(mobj, mobj->info->seesound); + P_SetMobjState(mobj, mobj->info->seestate); + if (mobj->movedir == 2) + mobj->threshold = 16; // bounce 16 times + else + mobj->threshold = 32; // bounce 32 times + mobj->watertop = mobj->target->floorz + 16*FRACUNIT; + P_LinedefExecute(LE_PINCHPHASE, mobj, NULL); + } + else + { + // Attack 2: Energy shot! + mobj->movedir = 1; + + if (mobj->health >= 8) + mobj->extravalue1 = 0; + else if (mobj->health >= 5) + mobj->extravalue1 = 2; + else if (mobj->health >= 4) + mobj->extravalue1 = 1; + else + mobj->extravalue1 = 3; + + switch(mobj->extravalue1) + { + case 0: // shoot once + case 2: // spread-shot + default: + mobj->threshold = 2; + break; + case 1: // shoot 3 times + mobj->threshold = 3*2; + break; + case 3: // shoot like a goddamn machinegun + mobj->threshold = 8*2; + break; + } + } + break; + + case 3: + // Return to idle. + mobj->watertop = mobj->target->floorz + 32*FRACUNIT; + P_SetMobjState(mobj, mobj->info->spawnstate); + mobj->flags &= ~MF_PAIN; + mobj->fuse = 10*TICRATE; + break; + } + mobj->movecount++; + mobj->movecount %= 4; + return; + } + + // Idle AI + if (mobj->state == &states[mobj->info->spawnstate]) + { + fixed_t dist; + + // Target the closest player + P_BossTargetPlayer(mobj, true); + + // Face your target + angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); // absolute angle + angle = (angle-mobj->angle); // relative angle + if (angle < ANGLE_180) + mobj->angle += angle/8; + else + mobj->angle -= InvAngle(angle)/8; + //A_FaceTarget(mobj); + + // Check if we're being attacked + if (mobj->target->x+mobj->target->radius+abs(mobj->target->momx*2) < mobj->x-mobj->radius) + danger = false; + if (mobj->target->x-mobj->target->radius-abs(mobj->target->momx*2) > mobj->x+mobj->radius) + danger = false; + if (mobj->target->y+mobj->target->radius+abs(mobj->target->momy*2) < mobj->y-mobj->radius) + danger = false; + if (mobj->target->y-mobj->target->radius-abs(mobj->target->momy*2) > mobj->y+mobj->radius) + danger = false; + if (mobj->target->z+mobj->target->height+mobj->target->momz*2 < mobj->z) + danger = false; + if (mobj->target->z+mobj->target->momz*2 > mobj->z+mobj->height) + danger = false; + if (danger) + { + // An incoming attack is detected! What should we do?! + // Go into vector form! + mobj->movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh), FixedDiv((mobj->info->spawnhealth - mobj->health)<info->spawnhealth-1)<movedir = InvAngle(mobj->movedir); + mobj->threshold = 6 + (FixedMul(24<info->spawnhealth - mobj->health)<info->spawnhealth-1)<>FRACBITS); + if (mobj->info->activesound) + S_StartSound(mobj, mobj->info->activesound); + if (mobj->info->painchance) + P_SetMobjState(mobj, mobj->info->painchance); + return; + } + + // Move normally: Approach the player using normal thrust and simulated friction. + dist = P_AproxDistance(mobj->x-mobj->target->x, mobj->y-mobj->target->y); + P_Thrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), -3*FRACUNIT/8); + if (dist < 64*FRACUNIT) + P_Thrust(mobj, mobj->angle, -4*FRACUNIT); + else if (dist > 180*FRACUNIT) + P_Thrust(mobj, mobj->angle, FRACUNIT); + mobj->momz += P_AproxDistance(mobj->momx, mobj->momy)/12; // Move up higher the faster you're going. + } + } +} + // // P_GetClosestAxis // @@ -5457,9 +7010,6 @@ static void P_MobjSceneryThink(mobj_t *mobj) return; } break; - case MT_BOSSJUNK: - mobj->renderflags ^= RF_DONTDRAW; - break; case MT_MACEPOINT: case MT_CHAINMACEPOINT: case MT_SPRINGBALLPOINT: @@ -6150,6 +7700,28 @@ static boolean P_MobjBossThink(mobj_t *mobj) else switch (mobj->type) { + case MT_EGGMOBILE: + if (mobj->health < mobj->info->damage+1 && leveltime & 1 && mobj->health > 0) + P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMOKE); + if (mobj->flags2 & MF2_SKULLFLY) + P_SpawnGhostMobj(mobj); + P_Boss1Thinker(mobj); + break; + case MT_EGGMOBILE2: + P_Boss2Thinker(mobj); + break; + case MT_EGGMOBILE3: + P_Boss3Thinker(mobj); + break; + case MT_EGGMOBILE4: + P_Boss4Thinker(mobj); + break; + case MT_BLACKEGGMAN: + P_Boss7Thinker(mobj); + break; + case MT_METALSONIC_BATTLE: + P_Boss9Thinker(mobj); + break; // No SRB2Kart bosses... yet :) default: // Generic SOC-made boss if (mobj->flags2 & MF2_SKULLFLY) @@ -6476,6 +8048,122 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->tracer->z += mobj->height; } break; + case MT_NIGHTSCORE: + mobj->color = (UINT16)(leveltime % SKINCOLOR_WHITE); + break; + case MT_JETFUME1: + { + fixed_t jetx, jety; + + if (!mobj->target // if you have no target + || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now + { // then remove yourself as well! + P_RemoveMobj(mobj); + return false; + } + + jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); + jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); + + if (mobj->fuse == 56) // First one + { + P_UnsetThingPosition(mobj); + mobj->x = jetx; + mobj->y = jety; + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(38*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z + FixedMul(38*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + else if (mobj->fuse == 57) + { + P_UnsetThingPosition(mobj); + mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + else if (mobj->fuse == 58) + { + P_UnsetThingPosition(mobj); + mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + else if (mobj->fuse == 59) + { + jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, -mobj->target->radius); + jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, -mobj->target->radius); + P_UnsetThingPosition(mobj); + mobj->x = jetx; + mobj->y = jety; + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height/2 + mobj->height/2; + else + mobj->z = mobj->target->z + mobj->target->height/2 - mobj->height/2; + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + mobj->fuse++; + } + break; + case MT_PROPELLER: + { + fixed_t jetx, jety; + + if (!mobj->target // if you have no target + || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now + { // then remove yourself as well! + P_RemoveMobj(mobj); + return false; + } + + jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale)); + jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale)); + + P_UnsetThingPosition(mobj); + mobj->x = jetx; + mobj->y = jety; + mobj->z = mobj->target->z + FixedMul(17*FRACUNIT, mobj->target->scale); + mobj->angle = mobj->target->angle - ANGLE_180; + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + break; + case MT_JETFLAME: + { + if (!mobj->target // if you have no target + || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now + { // then remove yourself as well! + P_RemoveMobj(mobj); + return false; + } + + P_UnsetThingPosition(mobj); + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + mobj->z = mobj->target->z - FixedMul(50*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + break; case MT_PLAYER: if (mobj->player) P_PlayerMobjThinker(mobj); @@ -9250,10 +10938,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_KART_LEFTOVER: mobj->color = SKINCOLOR_RED; break; - case MT_EGGROBO1: - mobj->movecount = P_RandomKey(13); - mobj->color = FIRSTRAINBOWCOLOR + P_RandomKey(FIRSTSUPERCOLOR - FIRSTRAINBOWCOLOR); - break; case MT_REDRING: // Make MT_REDRING red by default mobj->color = skincolor_redring; break; @@ -9281,13 +10965,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) if (nummaprings >= 0) nummaprings++; break; - case MT_METALSONIC_RACE: - mobj->skin = &skins[5]; - /* FALLTHRU */ - case MT_METALSONIC_BATTLE: - mobj->color = skins[5].prefcolor; - sc = 5; - break; case MT_CORK: mobj->flags2 |= MF2_SUPERFIRE; break; diff --git a/src/p_setup.c b/src/p_setup.c index 9d772e5f7..9c2cbdd58 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7355,25 +7355,12 @@ static void P_ConvertBinaryThingTypes(void) } break; } - case 1101: //Torch - case 1119: //Candle - case 1120: //Candle pricket - mapthings[i].args[0] = !!(mapthings[i].options & MTF_EXTRA); - break; case 1121: //Flame holder if (mapthings[i].options & MTF_OBJECTSPECIAL) mapthings[i].args[0] |= TMFH_NOFLAME; if (mapthings[i].options & MTF_EXTRA) mapthings[i].args[0] |= TMFH_CORONA; break; - case 1127: //Spectator EggRobo - if (mapthings[i].options & MTF_AMBUSH) - mapthings[i].args[0] = TMED_LEFT; - else if (mapthings[i].options & MTF_OBJECTSPECIAL) - mapthings[i].args[0] = TMED_RIGHT; - else - mapthings[i].args[0] = TMED_NONE; - break; case 1200: //Tumbleweed (Big) case 1201: //Tumbleweed (Small) mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); diff --git a/src/p_spec.h b/src/p_spec.h index d86765a2b..7bfab7f13 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -111,13 +111,6 @@ typedef enum TMP_CLASSIC = 3, } textmappushabletype_t; -typedef enum -{ - TMED_NONE = 0, - TMED_RIGHT = 1, - TMED_LEFT = 2, -} textmapeggrobodirection_t; - typedef enum { TMMR_SAME = 0, From a524831f1e77015aaf0dc3048fea4ed2bdb229ae Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sun, 13 Apr 2025 18:02:55 -0400 Subject: [PATCH 11/12] Port v1 objects pt 7: HOHOHO MERRY CHRISTMAS --- src/info/mobjs.h | 13 ++++--------- src/info/sprites.h | 3 +-- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/info/mobjs.h b/src/info/mobjs.h index 834f25b3a..472347455 100644 --- a/src/info/mobjs.h +++ b/src/info/mobjs.h @@ -297,16 +297,11 @@ _(STALAGMITE9) // Christmas Scenery _(XMASPOLE) _(CANDYCANE) -_(SNOWMAN) // normal -_(SNOWMANHAT) // with hat + scarf -_(LAMPPOST1) // normal -_(LAMPPOST2) // with snow +_(SNOWMAN) +_(SNOWMANHAT) +_(LAMPPOST1) +_(LAMPPOST2) _(HANGSTAR) -_(MISTLETOE) -// Xmas GFZ bushes -_(XMASBLUEBERRYBUSH) -_(XMASBERRYBUSH) -_(XMASBUSH) // Botanic Serenity scenery _(BSZTALLFLOWER_RED) diff --git a/src/info/sprites.h b/src/info/sprites.h index 2f467e73b..28ceb15ab 100644 --- a/src/info/sprites.h +++ b/src/info/sprites.h @@ -202,8 +202,7 @@ _(XMS3) // Snowman _(XMS4) // Lamppost _(XMS5) // Hanging Star _(XMS6) // Mistletoe -_(FHZI) // FHZ Ice -_(ROSY) + // Azure Temple Scenery _(RCRY) // ATZ Red Crystal (Target) _(CFLM) // Green torch flame From 89478cdd4791cac5da4e8a5add509c0e9a5654b3 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sun, 13 Apr 2025 18:07:29 -0400 Subject: [PATCH 12/12] Fix lingering nights score --- src/p_mobj.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5a5c12730..49db795ec 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10143,6 +10143,9 @@ static boolean P_FuseThink(mobj_t *mobj) P_RemoveMobj(mobj); return false; } + case MT_NIGHTSCORE: + P_RemoveMobj(mobj); + return false; case MT_PLAYER: break; // don't remove default: