diff --git a/src/deh_tables.c b/src/deh_tables.c index 48b87fdd8..b25bf7259 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -309,7 +309,6 @@ actionpointer_t actionpointers[] = // SRB2Kart {{A_ItemPop}, "A_ITEMPOP"}, - {{A_JawzChase}, "A_JAWZCHASE"}, {{A_JawzExplode}, "A_JAWZEXPLODE"}, {{A_SSMineSearch}, "A_SSMINESEARCH"}, {{A_SSMineExplode}, "A_SSMINEEXPLODE"}, @@ -3512,14 +3511,6 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_JAWZ6", "S_JAWZ7", "S_JAWZ8", - "S_JAWZ_DUD1", - "S_JAWZ_DUD2", - "S_JAWZ_DUD3", - "S_JAWZ_DUD4", - "S_JAWZ_DUD5", - "S_JAWZ_DUD6", - "S_JAWZ_DUD7", - "S_JAWZ_DUD8", "S_JAWZ_SHIELD1", "S_JAWZ_SHIELD2", "S_JAWZ_SHIELD3", @@ -5326,7 +5317,6 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_ORBINAUT_SHIELD", "MT_JAWZ", // Jawz stuff - "MT_JAWZ_DUD", "MT_JAWZ_SHIELD", "MT_PLAYERRETICULE", // Jawz reticule diff --git a/src/info.c b/src/info.c index 947b06701..794b147d7 100644 --- a/src/info.c +++ b/src/info.c @@ -4091,23 +4091,14 @@ state_t states[NUMSTATES] = {SPR_ORBN, 11, 3, {NULL}, 0, 0, S_ORBINAUT_SHIELD1}, // S_ORBINAUT_SHIELD6 {SPR_ORBN, 6, 175, {NULL}, 0, 0, S_NULL}, // S_ORBINAUT_SHIELDDEAD - {SPR_JAWZ, 0, 1, {A_JawzChase}, 0, 0, S_JAWZ2}, // S_JAWZ1 - {SPR_JAWZ, 4, 1, {A_JawzChase}, 0, 0, S_JAWZ3}, // S_JAWZ2 - {SPR_JAWZ, 1, 1, {A_JawzChase}, 0, 0, S_JAWZ4}, // S_JAWZ3 - {SPR_JAWZ, 4, 1, {A_JawzChase}, 0, 0, S_JAWZ5}, // S_JAWZ4 - {SPR_JAWZ, 2, 1, {A_JawzChase}, 0, 0, S_JAWZ6}, // S_JAWZ5 - {SPR_JAWZ, 4, 1, {A_JawzChase}, 0, 0, S_JAWZ7}, // S_JAWZ6 - {SPR_JAWZ, 3, 1, {A_JawzChase}, 0, 0, S_JAWZ8}, // S_JAWZ7 - {SPR_JAWZ, 4, 1, {A_JawzChase}, 0, 0, S_JAWZ1}, // S_JAWZ8 - - {SPR_JAWZ, 0, 1, {NULL}, 0, 0, S_JAWZ_DUD2}, // S_JAWZ_DUD1 - {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_DUD3}, // S_JAWZ_DUD2 - {SPR_JAWZ, 1, 1, {NULL}, 0, 0, S_JAWZ_DUD4}, // S_JAWZ_DUD3 - {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_DUD5}, // S_JAWZ_DUD4 - {SPR_JAWZ, 2, 1, {NULL}, 0, 0, S_JAWZ_DUD6}, // S_JAWZ_DUD5 - {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_DUD7}, // S_JAWZ_DUD6 - {SPR_JAWZ, 3, 1, {NULL}, 0, 0, S_JAWZ_DUD8}, // S_JAWZ_DUD7 - {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_DUD1}, // S_JAWZ_DUD8 + {SPR_JAWZ, 0, 1, {NULL}, 0, 0, S_JAWZ2}, // S_JAWZ1 + {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ3}, // S_JAWZ2 + {SPR_JAWZ, 1, 1, {NULL}, 0, 0, S_JAWZ4}, // S_JAWZ3 + {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ5}, // S_JAWZ4 + {SPR_JAWZ, 2, 1, {NULL}, 0, 0, S_JAWZ6}, // S_JAWZ5 + {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ7}, // S_JAWZ6 + {SPR_JAWZ, 3, 1, {NULL}, 0, 0, S_JAWZ8}, // S_JAWZ7 + {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ1}, // S_JAWZ8 {SPR_JAWZ, 0, 1, {NULL}, 0, 0, S_JAWZ_SHIELD2}, // S_JAWZ_SHIELD1 {SPR_JAWZ, 4, 1, {NULL}, 0, 0, S_JAWZ_SHIELD3}, // S_JAWZ_SHIELD2 @@ -23506,33 +23497,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_JAWZ_DUD - -1, // doomednum - S_JAWZ_DUD1, // spawnstate - 1, // spawnhealth - S_NULL, // seestate - sfx_tossed, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_JAWZ_DEAD1, // deathstate - S_JAWZ_DEAD2, // xdeathstate - sfx_s3k5d, // deathsound - 64*FRACUNIT, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_s3kc0s, // activesound - MF_SHOOTABLE|MF_DONTENCOREMAP, // flags - S_NULL // raisestate - }, - { // MT_JAWZ_SHIELD -1, // doomednum S_JAWZ_SHIELD1, // spawnstate diff --git a/src/info.h b/src/info.h index 426963709..b05a7034b 100644 --- a/src/info.h +++ b/src/info.h @@ -273,7 +273,6 @@ enum actionnum A_DRAGONSEGMENT, A_CHANGEHEIGHT, A_ITEMPOP, - A_JAWZCHASE, A_JAWZEXPLODE, A_SSMINESEARCH, A_SSMINEEXPLODE, @@ -545,7 +544,6 @@ void A_ChangeHeight(); // SRB2Kart // void A_ItemPop(); -void A_JawzChase(); void A_JawzExplode(); void A_SSMineSearch(); void A_SSMineExplode(); @@ -4522,14 +4520,6 @@ typedef enum state S_JAWZ6, S_JAWZ7, S_JAWZ8, - S_JAWZ_DUD1, - S_JAWZ_DUD2, - S_JAWZ_DUD3, - S_JAWZ_DUD4, - S_JAWZ_DUD5, - S_JAWZ_DUD6, - S_JAWZ_DUD7, - S_JAWZ_DUD8, S_JAWZ_SHIELD1, S_JAWZ_SHIELD2, S_JAWZ_SHIELD3, @@ -6372,7 +6362,6 @@ typedef enum mobj_type MT_ORBINAUT_SHIELD, MT_JAWZ, // Jawz stuff - MT_JAWZ_DUD, MT_JAWZ_SHIELD, MT_PLAYERRETICULE, // Jawz reticule diff --git a/src/k_botsearch.c b/src/k_botsearch.c index 26fc9f73d..5b6f1ccca 100644 --- a/src/k_botsearch.c +++ b/src/k_botsearch.c @@ -413,7 +413,6 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing) case MT_ORBINAUT: case MT_ORBINAUT_SHIELD: case MT_JAWZ: - case MT_JAWZ_DUD: case MT_JAWZ_SHIELD: case MT_SSMINE: case MT_SSMINE_SHIELD: diff --git a/src/k_collide.c b/src/k_collide.c index a373af5c2..e4a536403 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -37,104 +37,6 @@ angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2) return R_PointToAngle2(0, 0, momux, momuy); } -boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) -{ - boolean damageitem = false; - boolean sprung = false; - - if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0)) - return true; - - if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && ((t1->threshold > 0 && t2->type == MT_PLAYER) || (t2->type != MT_PLAYER && t2->threshold > 0))) - return true; - - if (t1->health <= 0 || t2->health <= 0) - return true; - - if ((t1->type == MT_ORBINAUT_SHIELD || t1->type == MT_JAWZ_SHIELD) && t1->lastlook - && (t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD) && t2->lastlook - && (t1->target == t2->target)) // Don't hit each other if you have the same target - return true; - - if (t2->player) - { - if ((t2->player->flashing > 0 && t2->hitlag == 0) - && !(t1->type == MT_ORBINAUT || t1->type == MT_JAWZ || t1->type == MT_JAWZ_DUD)) - return true; - - if (t2->player->hyudorotimer) - return true; // no interaction - - if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD) - { - // Melt item - S_StartSound(t2, sfx_s3k43); - } - else - { - // Player Damage - P_DamageMobj(t2, t1, t1->target, 1, DMG_WIPEOUT|DMG_WOMBO); - K_KartBouncing(t2, t1); - S_StartSound(t2, sfx_s3k7b); - } - - damageitem = true; - } - else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ || t2->type == MT_JAWZ_DUD - || t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD - || t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD - || t2->type == MT_BALLHOG) - { - // Other Item Damage - angle_t bounceangle = K_GetCollideAngle(t1, t2); - - S_StartSound(t2, t2->info->deathsound); - P_KillMobj(t2, t1, t1, DMG_NORMAL); - - P_SetObjectMomZ(t2, 8*FRACUNIT, false); - P_InstaThrust(t2, bounceangle, 16*FRACUNIT); - - P_SpawnMobj(t2->x/2 + t1->x/2, t2->y/2 + t1->y/2, t2->z/2 + t1->z/2, MT_ITEMCLASH); - - damageitem = true; - } - else if (t2->type == MT_SSMINE_SHIELD || t2->type == MT_SSMINE || t2->type == MT_LANDMINE) - { - damageitem = true; - // Bomb death - P_KillMobj(t2, t1, t1, DMG_NORMAL); - } - else if (t2->flags & MF_SPRING && (t1->type != MT_ORBINAUT_SHIELD && t1->type != MT_JAWZ_SHIELD)) - { - // Let thrown items hit springs! - sprung = P_DoSpring(t2, t1); - } - else if (t2->flags & MF_SHOOTABLE) - { - // Shootable damage - P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); - damageitem = true; - } - - if (damageitem) - { - // This Item Damage - angle_t bounceangle = K_GetCollideAngle(t2, t1); - S_StartSound(t1, t1->info->deathsound); - P_KillMobj(t1, t2, t2, DMG_NORMAL); - - P_SetObjectMomZ(t1, 8*FRACUNIT, false); - P_InstaThrust(t1, bounceangle, 16*FRACUNIT); - } - - if (sprung) - { - return false; - } - - return true; -} - boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) { boolean damageitem = false; @@ -178,7 +80,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2) } else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD || t2->type == MT_ORBINAUT || t2->type == MT_ORBINAUT_SHIELD - || t2->type == MT_JAWZ || t2->type == MT_JAWZ_DUD || t2->type == MT_JAWZ_SHIELD + || t2->type == MT_JAWZ || t2->type == MT_JAWZ_SHIELD || t2->type == MT_BALLHOG) { // Other Item Damage @@ -432,7 +334,7 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) K_PuntMine(t1, t2); } } - else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ || t2->type == MT_JAWZ_DUD + else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ || t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD) { // Bomb death @@ -493,7 +395,7 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2) } else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD || t2->type == MT_ORBINAUT || t2->type == MT_ORBINAUT_SHIELD - || t2->type == MT_JAWZ || t2->type == MT_JAWZ_DUD || t2->type == MT_JAWZ_SHIELD + || t2->type == MT_JAWZ || t2->type == MT_JAWZ_SHIELD || t2->type == MT_BALLHOG) { // Other Item Damage diff --git a/src/k_collide.h b/src/k_collide.h index cf1ee5dc7..a498241ca 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -6,8 +6,6 @@ angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2); -boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2); - boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2); boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2); diff --git a/src/k_kart.c b/src/k_kart.c index ad93fdb75..df01b4e6a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1421,7 +1421,6 @@ fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) weight = K_PlayerWeight(against, NULL); break; case MT_JAWZ: - case MT_JAWZ_DUD: case MT_JAWZ_SHIELD: if (against->player) weight = K_PlayerWeight(against, NULL) + (3*FRACUNIT); @@ -4674,7 +4673,7 @@ fixed_t K_ItemScaleForPlayer(player_t *player) } } -static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, INT32 flags2, fixed_t speed) +static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, INT32 flags2, fixed_t speed, SINT8 dir) { mobj_t *th; fixed_t x, y, z; @@ -4688,20 +4687,20 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I if (source->player->itemscale == ITEMSCALE_SHRINK) { // Nerf the base item speed a bit. - finalspeed = FixedMul(finalspeed, SHRINK_PHYSICS_SCALE); + speed = finalspeed = FixedMul(speed, SHRINK_PHYSICS_SCALE); } if (source->player->speed > topspeed) { - angle_t input = source->angle - an; - boolean invert = (input > ANGLE_180); - if (invert) - input = InvAngle(input); + angle_t delta = AngleDelta(source->angle, an); - finalspeed = max(speed, FixedMul(speed, FixedMul( - FixedDiv(source->player->speed, topspeed), // Multiply speed to be proportional to your own, boosted maxspeed. - (((180<player->speed, topspeed), // Multiply speed to be proportional to your own, boosted maxspeed. + FixedDiv(AngleFixed(ANGLE_180 - delta), 180 * FRACUNIT) // multiply speed based on angle diff... i.e: don't do this for firing backward :V + ) + )); } finalscale = K_ItemScaleForPlayer(source->player); @@ -4712,6 +4711,12 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I finalscale = source->scale; } + if (dir == -1 && (type == MT_ORBINAUT || type == MT_BALLHOG)) + { + // Backwards nerfs + finalspeed /= 8; + } + x = source->x + source->momx + FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT)); y = source->y + source->momy + FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT)); z = source->z; // spawn on the ground please @@ -4763,31 +4768,11 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I switch (type) { case MT_ORBINAUT: - if (source && source->player) - th->color = source->player->skincolor; - else - th->color = SKINCOLOR_GREY; - th->movefactor = finalspeed; + Obj_OrbinautThrown(th, finalspeed, dir); break; case MT_JAWZ: - if (source && source->player) - { - INT32 lasttarg = source->player->lastjawztarget; - th->cvmem = source->player->skincolor; - if ((lasttarg >= 0 && lasttarg < MAXPLAYERS) - && playeringame[lasttarg] - && !players[lasttarg].spectator - && players[lasttarg].mo) - { - P_SetTarget(&th->tracer, players[lasttarg].mo); - } - } - else - th->cvmem = SKINCOLOR_KETCHUP; - /* FALLTHRU */ - case MT_JAWZ_DUD: - S_StartSound(th, th->info->activesound); - /* FALLTHRU */ + Obj_JawzThrown(th, finalspeed, dir); + break; case MT_SPB: th->movefactor = finalspeed; break; @@ -5623,15 +5608,15 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, if (missile) // Shootables { - if (dir == -1 && mapthing != MT_SPB) + if (dir < 0 && mapthing != MT_SPB) { // Shoot backward - mo = K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) + angleOffset, 0, PROJSPEED/8); + mo = K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) + angleOffset, 0, PROJSPEED, dir); } else { // Shoot forward - mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + angleOffset, 0, PROJSPEED); + mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + angleOffset, 0, PROJSPEED, dir); } if (mapthing == MT_DROPTARGET && mo) @@ -6345,7 +6330,7 @@ void K_DropHnextList(player_t *player, boolean keepshields) break; case MT_JAWZ_SHIELD: orbit = true; - type = MT_JAWZ_DUD; + type = MT_JAWZ; break; // Kart trailing items case MT_BANANA_SHIELD: @@ -6402,6 +6387,12 @@ void K_DropHnextList(player_t *player, boolean keepshields) dropwork->health = work->health; // will never be set to 0 as long as above guard exists dropwork->hitlag = work->hitlag; + if (orbit == true) + { + // Projectile item; set fuse + dropwork->fuse = RR_PROJECTILE_FUSE; + } + // Copy interp data dropwork->old_angle = work->old_angle; dropwork->old_x = work->old_x; @@ -6463,7 +6454,7 @@ void K_DropHnextList(player_t *player, boolean keepshields) dropwork->tics = -1; - if (type == MT_JAWZ_DUD) + if (type == MT_JAWZ) { dropwork->z += 20*flip*dropwork->scale; } @@ -6851,8 +6842,11 @@ static void K_MoveHeldObjects(player_t *player) if (!player->mo->hnext) { player->bananadrag = 0; + if (player->pflags & PF_EGGMANOUT) + { player->pflags &= ~PF_EGGMANOUT; + } else if (player->pflags & PF_ITEMOUT) { player->itemamount = 0; @@ -6867,14 +6861,18 @@ static void K_MoveHeldObjects(player_t *player) // we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic... P_SetTarget(&player->mo->hnext, NULL); player->bananadrag = 0; + if (player->pflags & PF_EGGMANOUT) + { player->pflags &= ~PF_EGGMANOUT; + } else if (player->pflags & PF_ITEMOUT) { player->itemamount = 0; K_UnsetItemOut(player); player->itemtype = KITEM_NONE; } + return; } @@ -6885,80 +6883,9 @@ static void K_MoveHeldObjects(player_t *player) case MT_ORBINAUT_SHIELD: // Kart orbit items case MT_JAWZ_SHIELD: { - mobj_t *cur = player->mo->hnext; - fixed_t speed = ((8 - min(4, player->itemamount)) * cur->info->speed) / 7; - - player->bananadrag = 0; // Just to make sure - - while (cur && !P_MobjWasRemoved(cur)) - { - const fixed_t radius = FixedHypot(player->mo->radius, player->mo->radius) + FixedHypot(cur->radius, cur->radius); // mobj's distance from its Target, or Radius. - fixed_t z; - - if (!cur->health) - { - cur = cur->hnext; - continue; - } - - cur->color = player->skincolor; - - cur->angle -= ANGLE_90; - cur->angle += FixedAngle(speed); - - if (cur->extravalue1 < radius) - cur->extravalue1 += P_AproxDistance(cur->extravalue1, radius) / 12; - if (cur->extravalue1 > radius) - cur->extravalue1 = radius; - - // If the player is on the ceiling, then flip your items as well. - if (player && player->mo->eflags & MFE_VERTICALFLIP) - cur->eflags |= MFE_VERTICALFLIP; - else - cur->eflags &= ~MFE_VERTICALFLIP; - - // Shrink your items if the player shrunk too. - P_SetScale(cur, (cur->destscale = FixedMul(FixedDiv(cur->extravalue1, radius), finalscale))); - - if (P_MobjFlip(cur) > 0) - z = player->mo->z; - else - z = player->mo->z + player->mo->height - cur->height; - - cur->flags |= MF_NOCLIPTHING; // temporarily make them noclip other objects so they can't hit anyone while in the player - P_MoveOrigin(cur, player->mo->x, player->mo->y, z); - cur->momx = FixedMul(FINECOSINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1); - cur->momy = FixedMul(FINESINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1); - cur->flags &= ~MF_NOCLIPTHING; - - if (!P_TryMove(cur, player->mo->x + cur->momx, player->mo->y + cur->momy, true)) - P_SlideMove(cur); - - if (P_IsObjectOnGround(player->mo)) - { - if (P_MobjFlip(cur) > 0) - { - if (cur->floorz > player->mo->z - cur->height) - z = cur->floorz; - } - else - { - if (cur->ceilingz < player->mo->z + player->mo->height + cur->height) - z = cur->ceilingz - cur->height; - } - } - - // Center it during the scale up animation - z += (FixedMul(mobjinfo[cur->type].height, finalscale - cur->scale)>>1) * P_MobjFlip(cur); - - cur->z = z; - cur->momx = cur->momy = 0; - cur->angle += ANGLE_90; - - cur = cur->hnext; - } + Obj_OrbinautJawzMoveHeld(player); + break; } - break; case MT_BANANA_SHIELD: // Kart trailing items case MT_SSMINE_SHIELD: case MT_DROPTARGET_SHIELD: @@ -7168,94 +7095,110 @@ static void K_MoveHeldObjects(player_t *player) } } -player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) +player_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range) { - fixed_t best = -1; + fixed_t best = INT32_MAX; player_t *wtarg = NULL; INT32 i; for (i = 0; i < MAXPLAYERS; i++) { - angle_t thisang; - player_t *player; + angle_t thisang = ANGLE_MAX; + fixed_t thisdist = INT32_MAX; + fixed_t thisScore = INT32_MAX; + player_t *player = NULL; - if (!playeringame[i]) + if (playeringame[i] == false) + { continue; + } player = &players[i]; - if (player->spectator) - continue; // spectator - - if (!player->mo) - continue; - - if (player->mo->health <= 0) - continue; // dead - // Don't target yourself, stupid. if (player == source) + { continue; + } - // Don't home in on teammates. - if (G_GametypeHasTeams() && source->ctfteam == player->ctfteam) + if (player->spectator) + { + // Spectators continue; + } - // Invisible, don't bother - if (player->hyudorotimer) + if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true) + { + // Invalid mobj continue; + } - // Find the angle, see who's got the best. - thisang = actor->angle - R_PointToAngle2(actor->x, actor->y, player->mo->x, player->mo->y); - if (thisang > ANGLE_180) - thisang = InvAngle(thisang); + if (player->mo->health <= 0) + { + // dead + continue; + } + + if (G_GametypeHasTeams() && source != NULL && source->ctfteam == player->ctfteam) + { + // Don't home in on teammates. + continue; + } + + if (player->hyudorotimer > 0) + { + // Invisible player + continue; + } + + thisdist = P_AproxDistance(player->mo->x - (actor->x + actor->momx), player->mo->y - (actor->y + actor->momy)); - // Jawz only go after the person directly ahead of you in race... sort of literally now! if (gametyperules & GTR_CIRCUIT) { - // Don't go for people who are behind you - if (thisang > ANGLE_67h) - continue; - // Don't pay attention to people who aren't above your position if (player->position >= source->position) - continue; - if ((best == -1) || (player->position > best)) { - wtarg = player; - best = player->position; + // Don't pay attention to people who aren't above your position + continue; } } else { - fixed_t thisdist; - fixed_t thisavg; - - // Don't go for people who are behind you - if (thisang > ANGLE_45) - continue; - - // Don't pay attention to dead players if (player->bumpers <= 0) + { + // Don't pay attention to dead players continue; + } // Z pos too high/low - if (abs(player->mo->z - (actor->z + actor->momz)) > RING_DIST/8) - continue; - - thisdist = P_AproxDistance(player->mo->x - (actor->x + actor->momx), player->mo->y - (actor->y + actor->momy)); - - if (thisdist > 2*RING_DIST) // Don't go for people who are too far away - continue; - - thisavg = (AngleFixed(thisang) + thisdist) / 2; - - //CONS_Printf("got avg %d from player # %d\n", thisavg>>FRACBITS, i); - - if ((best == -1) || (thisavg < best)) + if (abs(player->mo->z - (actor->z + actor->momz)) > FixedMul(RING_DIST/8, mapobjectscale)) { - wtarg = player; - best = thisavg; + continue; } + + // Distance too far away + if (thisdist > FixedMul(RING_DIST*2, mapobjectscale)) + { + continue; + } + } + + // Find the angle, see who's got the best. + thisang = AngleDelta(actor->angle, R_PointToAngle2(actor->x, actor->y, player->mo->x, player->mo->y)); + + // Don't go for people who are behind you + if (thisang > range) + { + continue; + } + + thisScore = (AngleFixed(thisang) * 8) + (thisdist / 32); + + //CONS_Printf("got score %f from player # %d\n", FixedToFloat(thisScore), i); + + if (thisScore < best) + { + wtarg = player; + best = thisScore; } } @@ -8326,19 +8269,69 @@ void K_KartPlayerAfterThink(player_t *player) // Jawz reticule (seeking) if (player->itemtype == KITEM_JAWZ && (player->pflags & PF_ITEMOUT)) { - INT32 lasttarg = player->lastjawztarget; - player_t *targ; - mobj_t *ret; + INT32 lastTargID = player->lastjawztarget; + player_t *lastTarg = NULL; + player_t *targ = NULL; + mobj_t *ret = NULL; - if (player->jawztargetdelay && playeringame[lasttarg] && !players[lasttarg].spectator) + if ((lastTargID >= 0 && lastTargID <= MAXPLAYERS) + && playeringame[lastTargID] == true) { - targ = &players[lasttarg]; - player->jawztargetdelay--; + if (players[lastTargID].spectator == false) + { + lastTarg = &players[lastTargID]; + } + } + + if (player->throwdir == -1) + { + // Backwards Jawz targets yourself. + targ = player; + player->jawztargetdelay = 0; } else - targ = K_FindJawzTarget(player->mo, player); + { + // Find a new target. + targ = K_FindJawzTarget(player->mo, player, ANGLE_45); + } - if (!targ || !targ->mo || P_MobjWasRemoved(targ->mo)) + if (targ != NULL && targ->mo != NULL && P_MobjWasRemoved(targ->mo) == false) + { + if (targ - players == lastTargID) + { + // Increment delay. + if (player->jawztargetdelay < 10) + { + player->jawztargetdelay++; + } + } + else + { + if (player->jawztargetdelay > 0) + { + // Wait a bit before swapping... + player->jawztargetdelay--; + targ = lastTarg; + } + else + { + // Allow a swap. + if (P_IsDisplayPlayer(player) || P_IsDisplayPlayer(targ)) + { + S_StartSound(NULL, sfx_s3k89); + } + else + { + S_StartSound(targ->mo, sfx_s3k89); + } + + player->lastjawztarget = targ - players; + player->jawztargetdelay = 5; + } + } + } + + if (targ == NULL || targ->mo == NULL || P_MobjWasRemoved(targ->mo) == true) { player->lastjawztarget = -1; player->jawztargetdelay = 0; @@ -8353,17 +8346,6 @@ void K_KartPlayerAfterThink(player_t *player) ret->frame |= ((leveltime % 10) / 2); ret->tics = 1; ret->color = player->skincolor; - - if (targ-players != lasttarg) - { - if (P_IsDisplayPlayer(player) || P_IsDisplayPlayer(targ)) - S_StartSound(NULL, sfx_s3k89); - else - S_StartSound(targ->mo, sfx_s3k89); - - player->lastjawztarget = targ-players; - player->jawztargetdelay = 5; - } } else { @@ -10357,10 +10339,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->pflags & PF_ITEMOUT)) // Jawz thrown { - if (player->throwdir == 1 || player->throwdir == 0) - K_ThrowKartItem(player, true, MT_JAWZ, 1, 0, 0); - else if (player->throwdir == -1) // Throwing backward gives you a dud that doesn't home in - K_ThrowKartItem(player, true, MT_JAWZ_DUD, -1, 0, 0); + K_ThrowKartItem(player, true, MT_JAWZ, 1, 0, 0); K_PlayAttackTaunt(player->mo); player->itemamount--; K_UpdateHnextList(player, false); diff --git a/src/k_kart.h b/src/k_kart.h index b120f0b6c..1c75288e5 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -28,6 +28,8 @@ Make sure this matches the actual number of states #define GROW_PHYSICS_SCALE (3*FRACUNIT/2) #define SHRINK_PHYSICS_SCALE (3*FRACUNIT/4) +#define RR_PROJECTILE_FUSE (8*TICRATE) + #define STUMBLE_STEEP_VAL ANG60 #define STUMBLE_STEEP_VAL_AIR (ANG30 + ANG10) @@ -116,7 +118,7 @@ void K_UpdateHnextList(player_t *player, boolean clean); void K_DropHnextList(player_t *player, boolean keepshields); void K_RepairOrbitChain(mobj_t *orbit); void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player); -player_t *K_FindJawzTarget(mobj_t *actor, player_t *source); +player_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range); INT32 K_GetKartRingPower(player_t *player, boolean boosted); void K_UpdateDistanceFromFinishLine(player_t *const player); boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y); diff --git a/src/k_objects.h b/src/k_objects.h index d39da4247..7679db658 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -29,4 +29,14 @@ void Obj_SPBTouch(mobj_t *spb, mobj_t *toucher); void Obj_MantaRingThink(mobj_t *manta); mobj_t *Obj_MantaRingCreate(mobj_t *spb, mobj_t *owner, mobj_t *chase); +/* Orbinaut */ +void Obj_OrbinautThink(mobj_t *th); +boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2); +void Obj_OrbinautThrown(mobj_t *th, fixed_t finalSpeed, SINT8 dir); +void Obj_OrbinautJawzMoveHeld(player_t *player); + +/* Jawz */ +void Obj_JawzThink(mobj_t *th); +void Obj_JawzThrown(mobj_t *th, fixed_t finalSpeed, SINT8 dir); + #endif/*k_objects_H*/ diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 1219c7ba9..771d41b51 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3632,7 +3632,7 @@ static int lib_kFindJawzTarget(lua_State *L) return LUA_ErrInvalid(L, "mobj_t"); if (!source) return LUA_ErrInvalid(L, "player_t"); - LUA_PushUserdata(L, K_FindJawzTarget(actor, source), META_PLAYER); + LUA_PushUserdata(L, K_FindJawzTarget(actor, source, ANGLE_45), META_PLAYER); return 1; } diff --git a/src/objects/Sourcefile b/src/objects/Sourcefile index 84e263f29..339175b0c 100644 --- a/src/objects/Sourcefile +++ b/src/objects/Sourcefile @@ -3,3 +3,5 @@ shrink.c item-debris.c spb.c manta-ring.c +orbinaut.c +jawz.c diff --git a/src/objects/jawz.c b/src/objects/jawz.c new file mode 100644 index 000000000..b5bc71058 --- /dev/null +++ b/src/objects/jawz.c @@ -0,0 +1,292 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour +// Copyright (C) 2022 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file jawz.c +/// \brief Jawz item code. + +#include "../doomdef.h" +#include "../doomstat.h" +#include "../info.h" +#include "../k_kart.h" +#include "../k_objects.h" +#include "../m_random.h" +#include "../p_local.h" +#include "../r_main.h" +#include "../s_sound.h" +#include "../g_game.h" +#include "../z_zone.h" +#include "../k_waypoint.h" +#include "../k_respawn.h" +#include "../k_collide.h" + +#define MAX_JAWZ_TURN (ANGLE_90 / 15) // We can turn a maximum of 6 degrees per frame at regular max speed + +#define jawz_speed(o) ((o)->movefactor) +#define jawz_selfdelay(o) ((o)->threshold) +#define jawz_dropped(o) ((o)->flags2 & MF2_AMBUSH) +#define jawz_droptime(o) ((o)->movecount) + +#define jawz_retcolor(o) ((o)->cvmem) +#define jawz_stillturn(o) ((o)->cusval) + +#define jawz_owner(o) ((o)->target) +#define jawz_chase(o) ((o)->tracer) + +static void JawzChase(mobj_t *th, boolean grounded) +{ + fixed_t thrustamount = 0; + fixed_t frictionsafety = (th->friction == 0) ? 1 : th->friction; + fixed_t topspeed = jawz_speed(th); + + if (jawz_chase(th) != NULL && P_MobjWasRemoved(jawz_chase(th)) == false) + { + if (jawz_chase(th)->health > 0) + { + const angle_t targetangle = R_PointToAngle2( + th->x, th->y, + jawz_chase(th)->x, jawz_chase(th)->y + ); + angle_t angledelta = th->angle - targetangle; + mobj_t *ret = NULL; + + if (gametyperules & GTR_CIRCUIT) + { + const fixed_t distbarrier = FixedMul( + 512 * mapobjectscale, + FRACUNIT + ((gamespeed-1) * (FRACUNIT/4)) + ); + + const fixed_t distaway = P_AproxDistance( + jawz_chase(th)->x - th->x, + jawz_chase(th)->y - th->y + ); + + if (distaway < distbarrier) + { + if (jawz_chase(th)->player != NULL) + { + fixed_t speeddifference = abs( + topspeed - min( + jawz_chase(th)->player->speed, + K_GetKartSpeed(jawz_chase(th)->player, false, false) + ) + ); + + topspeed = topspeed - FixedMul(speeddifference, FRACUNIT - FixedDiv(distaway, distbarrier)); + } + } + } + + if (angledelta != 0) + { + angle_t turnSpeed = MAX_JAWZ_TURN; + boolean turnclockwise = true; + + // MAX_JAWZ_TURN gets stronger the slower the top speed of jawz + if (topspeed < jawz_speed(th)) + { + if (topspeed == 0) + { + turnSpeed = ANGLE_180; + } + else + { + fixed_t anglemultiplier = FixedDiv(jawz_speed(th), topspeed); + turnSpeed += FixedAngle(FixedMul(AngleFixed(turnSpeed), anglemultiplier)); + } + } + + if (angledelta > ANGLE_180) + { + angledelta = InvAngle(angledelta); + turnclockwise = false; + } + + if (angledelta > turnSpeed) + { + angledelta = turnSpeed; + } + + if (turnclockwise == true) + { + th->angle -= angledelta; + } + else + { + th->angle += angledelta; + } + } + + ret = P_SpawnMobjFromMobj(jawz_chase(th), 0, 0, 0, MT_PLAYERRETICULE); + ret->old_x = jawz_chase(th)->old_x; + ret->old_y = jawz_chase(th)->old_y; + ret->old_z = jawz_chase(th)->old_z; + P_SetTarget(&ret->target, jawz_chase(th)); + ret->frame |= ((leveltime % 10) / 2) + 5; + ret->color = jawz_retcolor(th); + ret->renderflags = (ret->renderflags & ~RF_DONTDRAW) | (th->renderflags & RF_DONTDRAW); + } + else + { + P_SetTarget(&jawz_chase(th), NULL); + } + } + + if (jawz_chase(th) == NULL || P_MobjWasRemoved(jawz_chase(th)) == true) + { + th->angle = K_MomentumAngle(th); + + if (jawz_owner(th) != NULL && P_MobjWasRemoved(jawz_owner(th)) == false + && jawz_owner(th)->player != NULL) + { + player_t *newPlayer = K_FindJawzTarget(th, jawz_owner(th)->player, ANGLE_90); + + if (newPlayer != NULL) + { + P_SetTarget(&jawz_chase(th), newPlayer->mo); + } + } + } + + if (jawz_stillturn(th) > 0) + { + // When beginning to chase your own owner, + // we should turn but not thrust quite yet. + return; + } + + if (grounded == true) + { + const fixed_t currentspeed = R_PointToDist2(0, 0, th->momx, th->momy); + + if (currentspeed >= topspeed) + { + // Thrust as if you were at top speed, slow down naturally + thrustamount = FixedDiv(topspeed, frictionsafety) - topspeed; + } + else + { + const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; + // Thrust to immediately get to top speed + thrustamount = beatfriction + FixedDiv(topspeed - currentspeed, frictionsafety); + } + + P_Thrust(th, th->angle, thrustamount); + } +} + +void Obj_JawzThink(mobj_t *th) +{ + mobj_t *ghost = P_SpawnGhostMobj(th); + boolean grounded = P_IsObjectOnGround(th); + + if (th->fuse > 0 && th->fuse <= TICRATE) + { + th->renderflags ^= RF_DONTDRAW; + } + + if (jawz_dropped(th)) + { + if (grounded && (th->flags & MF_NOCLIPTHING)) + { + th->momx = 1; + th->momy = 0; + S_StartSound(th, th->info->deathsound); + th->flags &= ~MF_NOCLIPTHING; + } + + return; + } + + if (jawz_owner(th) != NULL && P_MobjWasRemoved(jawz_owner(th)) == false + && jawz_owner(th)->player != NULL) + { + ghost->color = jawz_owner(th)->player->skincolor; + ghost->colorized = true; + } + + if (!(gametyperules & GTR_CIRCUIT)) + { + th->friction = max(0, 3 * th->friction / 4); + } + + JawzChase(th, grounded); + K_DriftDustHandling(th); + + if (P_MobjTouchingSectorSpecial(th, 3, 1, true)) + { + K_DoPogoSpring(th, 0, 1); + } + + if (jawz_selfdelay(th) > 0) + { + jawz_selfdelay(th)--; + } + + if (jawz_stillturn(th) > 0) + { + jawz_stillturn(th)--; + } + + if (leveltime % TICRATE == 0) + { + S_StartSound(th, th->info->activesound); + } +} + +void Obj_JawzThrown(mobj_t *th, fixed_t finalSpeed, SINT8 dir) +{ + INT32 lastTarg = -1; + + if (jawz_owner(th) != NULL && P_MobjWasRemoved(jawz_owner(th)) == false + && jawz_owner(th)->player != NULL) + { + lastTarg = jawz_owner(th)->player->lastjawztarget; + jawz_retcolor(th) = jawz_owner(th)->player->skincolor; + } + else + { + jawz_retcolor(th) = SKINCOLOR_KETCHUP; + } + + if (dir == -1) + { + // Thrown backwards, init self-chase + P_SetTarget(&jawz_chase(th), jawz_owner(th)); + + // Stop it here. + th->momx = 0; + th->momy = 0; + + // Slow down the top speed. + finalSpeed = FixedMul(finalSpeed, 4*FRACUNIT/5); + + // Set a fuse. + th->fuse = RR_PROJECTILE_FUSE; + + // Stay still while you turn towards the player + jawz_stillturn(th) = ANGLE_180 / MAX_JAWZ_TURN; + } + else + { + if ((lastTarg >= 0 && lastTarg < MAXPLAYERS) + && playeringame[lastTarg] == true) + { + player_t *tryPlayer = &players[lastTarg]; + + if (tryPlayer->spectator == false) + { + P_SetTarget(&jawz_chase(th), tryPlayer->mo); + } + } + } + + S_StartSound(th, th->info->activesound); + jawz_speed(th) = finalSpeed; +} diff --git a/src/objects/orbinaut.c b/src/objects/orbinaut.c new file mode 100644 index 000000000..0c04c4b67 --- /dev/null +++ b/src/objects/orbinaut.c @@ -0,0 +1,379 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour +// Copyright (C) 2022 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file orbinaut.c +/// \brief Orbinaut item code. + +#include "../doomdef.h" +#include "../doomstat.h" +#include "../info.h" +#include "../k_kart.h" +#include "../k_objects.h" +#include "../m_random.h" +#include "../p_local.h" +#include "../r_main.h" +#include "../s_sound.h" +#include "../g_game.h" +#include "../z_zone.h" +#include "../k_waypoint.h" +#include "../k_respawn.h" +#include "../k_collide.h" + +#define ORBINAUT_MAXTURN (ANGLE_67h) +#define ORBINAUT_TURNLERP (16) + +#define orbinaut_speed(o) ((o)->movefactor) +#define orbinaut_selfdelay(o) ((o)->threshold) +#define orbinaut_dropped(o) ((o)->flags2 & MF2_AMBUSH) +#define orbinaut_droptime(o) ((o)->movecount) + +#define orbinaut_turn(o) ((o)->extravalue1) + +#define orbinaut_owner(o) ((o)->target) + +#define orbinaut_shield_dist(o) ((o)->extravalue1) + +void Obj_OrbinautThink(mobj_t *th) +{ + boolean grounded = P_IsObjectOnGround(th); + mobj_t *ghost = NULL; + + if (th->fuse > 0 && th->fuse <= TICRATE) + { + th->renderflags ^= RF_DONTDRAW; + } + + if (orbinaut_dropped(th)) + { + if (grounded && (th->flags & MF_NOCLIPTHING)) + { + th->momx = 1; + th->momy = 0; + th->frame = 3; + S_StartSound(th, th->info->activesound); + th->flags &= ~MF_NOCLIPTHING; + } + else if (orbinaut_droptime(th)) + { + orbinaut_droptime(th)--; + } + else if (th->frame < 3) + { + orbinaut_droptime(th) = 2; + th->frame++; + } + + return; + } + + ghost = P_SpawnGhostMobj(th); + ghost->colorized = true; // already has color! + + th->angle = K_MomentumAngle(th); + if (orbinaut_turn(th) != 0) + { + th->angle += orbinaut_turn(th); + + if (abs(orbinaut_turn(th)) < ORBINAUT_MAXTURN) + { + if (orbinaut_turn(th) < 0) + { + orbinaut_turn(th) -= ORBINAUT_MAXTURN / ORBINAUT_TURNLERP; + } + else + { + orbinaut_turn(th) += ORBINAUT_MAXTURN / ORBINAUT_TURNLERP; + } + } + } + + if (grounded == true) + { + fixed_t finalspeed = orbinaut_speed(th); + const fixed_t currentspeed = R_PointToDist2(0, 0, th->momx, th->momy); + fixed_t thrustamount = 0; + fixed_t frictionsafety = (th->friction == 0) ? 1 : th->friction; + + if (th->health <= 5) + { + INT32 i; + for (i = 5; i >= th->health; i--) + { + finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4); + } + } + + if (currentspeed >= finalspeed) + { + // Thrust as if you were at top speed, slow down naturally + thrustamount = FixedDiv(finalspeed, frictionsafety) - finalspeed; + } + else + { + const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; + // Thrust to immediately get to top speed + thrustamount = beatfriction + FixedDiv(finalspeed - currentspeed, frictionsafety); + } + + P_Thrust(th, th->angle, thrustamount); + } + + if (P_MobjTouchingSectorSpecial(th, 3, 1, true)) + { + K_DoPogoSpring(th, 0, 1); + } + + if (orbinaut_selfdelay(th) > 0) + { + orbinaut_selfdelay(th)--; + } + + if (leveltime % 6 == 0) + { + S_StartSound(th, th->info->activesound); + } +} + +boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2) +{ + boolean damageitem = false; + boolean sprung = false; + + if ((orbinaut_selfdelay(t1) > 0 && t2->hitlag > 0) + || (orbinaut_selfdelay(t2) > 0 && t1->hitlag > 0)) + { + return true; + } + + if (t1->health <= 0 || t2->health <= 0) + { + return true; + } + + if ((orbinaut_owner(t1) == t2) + || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (orbinaut_owner(t1) == t2->target))) + { + if ((orbinaut_selfdelay(t1) > 0 && t2->type == MT_PLAYER) + || (orbinaut_selfdelay(t2) > 0 && t2->type != MT_PLAYER)) + { + return true; + } + } + + if ((t1->type == MT_ORBINAUT_SHIELD || t1->type == MT_JAWZ_SHIELD) && t1->lastlook + && (t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD) && t2->lastlook + && (orbinaut_owner(t1) == t2->target)) // Don't hit each other if you have the same target + { + return true; + } + + if (t2->player) + { + if ((t2->player->flashing > 0 && t2->hitlag == 0) + && !(t1->type == MT_ORBINAUT || t1->type == MT_JAWZ)) + return true; + + if (t2->player->hyudorotimer) + return true; // no interaction + + if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD) + { + // Melt item + S_StartSound(t2, sfx_s3k43); + } + else + { + // Player Damage + P_DamageMobj(t2, t1, t1->target, 1, DMG_WIPEOUT|DMG_WOMBO); + K_KartBouncing(t2, t1); + S_StartSound(t2, sfx_s3k7b); + } + + damageitem = true; + } + else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ + || t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD + || t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD + || t2->type == MT_BALLHOG) + { + // Other Item Damage + angle_t bounceangle = K_GetCollideAngle(t1, t2); + + S_StartSound(t2, t2->info->deathsound); + P_KillMobj(t2, t1, t1, DMG_NORMAL); + + P_SetObjectMomZ(t2, 8*FRACUNIT, false); + P_InstaThrust(t2, bounceangle, 16*FRACUNIT); + + P_SpawnMobj(t2->x/2 + t1->x/2, t2->y/2 + t1->y/2, t2->z/2 + t1->z/2, MT_ITEMCLASH); + + damageitem = true; + } + else if (t2->type == MT_SSMINE_SHIELD || t2->type == MT_SSMINE || t2->type == MT_LANDMINE) + { + damageitem = true; + // Bomb death + P_KillMobj(t2, t1, t1, DMG_NORMAL); + } + else if (t2->flags & MF_SPRING && (t1->type != MT_ORBINAUT_SHIELD && t1->type != MT_JAWZ_SHIELD)) + { + // Let thrown items hit springs! + sprung = P_DoSpring(t2, t1); + } + else if (t2->flags & MF_SHOOTABLE) + { + // Shootable damage + P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); + damageitem = true; + } + + if (damageitem) + { + // This Item Damage + angle_t bounceangle = K_GetCollideAngle(t2, t1); + S_StartSound(t1, t1->info->deathsound); + P_KillMobj(t1, t2, t2, DMG_NORMAL); + + P_SetObjectMomZ(t1, 8*FRACUNIT, false); + P_InstaThrust(t1, bounceangle, 16*FRACUNIT); + } + + if (sprung) + { + return false; + } + + return true; +} + +void Obj_OrbinautThrown(mobj_t *th, fixed_t finalSpeed, SINT8 dir) +{ + if (orbinaut_owner(th) != NULL && P_MobjWasRemoved(orbinaut_owner(th)) == false + && orbinaut_owner(th)->player != NULL) + { + th->color = orbinaut_owner(th)->player->skincolor; + } + else + { + th->color = SKINCOLOR_GREY; + } + + th->fuse = RR_PROJECTILE_FUSE; + orbinaut_speed(th) = finalSpeed; + + if (dir == -1) + { + // Thrown backwards, init orbiting in place + orbinaut_turn(th) = ORBINAUT_MAXTURN / ORBINAUT_TURNLERP; + + th->angle -= ANGLE_45; + th->momx = FixedMul(finalSpeed, FINECOSINE(th->angle >> ANGLETOFINESHIFT)); + th->momy = FixedMul(finalSpeed, FINESINE(th->angle >> ANGLETOFINESHIFT)); + } +} + +void Obj_OrbinautJawzMoveHeld(player_t *player) +{ + fixed_t finalscale = K_ItemScaleForPlayer(player); + fixed_t speed = 0; + mobj_t *cur = NULL; + + player->bananadrag = 0; // Just to make sure + + cur = player->mo->hnext; + speed = ((8 - min(4, player->itemamount)) * cur->info->speed) / 7; + + while (cur != NULL && P_MobjWasRemoved(cur) == false) + { + const fixed_t radius = FixedHypot(player->mo->radius, player->mo->radius) + FixedHypot(cur->radius, cur->radius); // mobj's distance from its Target, or Radius. + fixed_t z; + + if (!cur->health) + { + cur = cur->hnext; + continue; + } + + cur->color = player->skincolor; + + cur->angle -= ANGLE_90; + cur->angle += FixedAngle(speed) / 3; + + if (orbinaut_shield_dist(cur) < radius) + { + orbinaut_shield_dist(cur) += P_AproxDistance(orbinaut_shield_dist(cur), radius) / 12; + } + + if (orbinaut_shield_dist(cur) > radius) + { + orbinaut_shield_dist(cur) = radius; + } + + // If the player is on the ceiling, then flip your items as well. + if (player && player->mo->eflags & MFE_VERTICALFLIP) + { + cur->eflags |= MFE_VERTICALFLIP; + } + else + { + cur->eflags &= ~MFE_VERTICALFLIP; + } + + // Shrink your items if the player shrunk too. + cur->destscale = FixedMul(FixedDiv(orbinaut_shield_dist(cur), radius), finalscale); + P_SetScale(cur, cur->destscale); + + if (P_MobjFlip(cur) > 0) + { + z = player->mo->z; + } + else + { + z = player->mo->z + player->mo->height - cur->height; + } + + cur->flags |= MF_NOCLIPTHING; // temporarily make them noclip other objects so they can't hit anyone while in the player + P_MoveOrigin(cur, player->mo->x, player->mo->y, z); + cur->momx = FixedMul(FINECOSINE(cur->angle >> ANGLETOFINESHIFT), orbinaut_shield_dist(cur)); + cur->momy = FixedMul(FINESINE(cur->angle >> ANGLETOFINESHIFT), orbinaut_shield_dist(cur)); + cur->flags &= ~MF_NOCLIPTHING; + + if (!P_TryMove(cur, player->mo->x + cur->momx, player->mo->y + cur->momy, true)) + { + P_SlideMove(cur); + } + + if (P_IsObjectOnGround(player->mo)) + { + if (P_MobjFlip(cur) > 0) + { + if (cur->floorz > player->mo->z - cur->height) + { + z = cur->floorz; + } + } + else + { + if (cur->ceilingz < player->mo->z + player->mo->height + cur->height) + { + z = cur->ceilingz - cur->height; + } + } + } + + // Center it during the scale up animation + z += (FixedMul(cur->info->height, finalscale - cur->scale) >> 1) * P_MobjFlip(cur); + + cur->z = z; + cur->momx = cur->momy = 0; + cur->angle += ANGLE_90; + + cur = cur->hnext; + } +} diff --git a/src/p_enemy.c b/src/p_enemy.c index 025ff5231..4cf7a7ad2 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -310,7 +310,6 @@ void A_ChangeHeight(mobj_t *actor); // SRB2Kart // void A_ItemPop(mobj_t *actor); -void A_JawzChase(mobj_t *actor); void A_JawzExplode(mobj_t *actor); void A_SSMineSearch(mobj_t *actor); void A_SSMineExplode(mobj_t *actor); @@ -13185,132 +13184,6 @@ void A_ItemPop(mobj_t *actor) } } -void A_JawzChase(mobj_t *actor) -{ - player_t *player; - fixed_t thrustamount = 0; - fixed_t frictionsafety = (actor->friction == 0) ? 1 : actor->friction; - fixed_t topspeed = actor->movefactor; - - if (LUA_CallAction(A_JAWZCHASE, actor)) - return; - - if (actor->tracer) - { - /*if ((gametyperules & GTR_CIRCUIT)) // Stop looking after first target in race - actor->extravalue1 = 1;*/ - - if (actor->tracer->health) - { - const angle_t targetangle = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y); - mobj_t *ret; - angle_t angledelta = actor->angle - targetangle; - boolean turnclockwise = true; - - if (gametyperules & GTR_CIRCUIT) - { - const fixed_t distbarrier = FixedMul(512*mapobjectscale, FRACUNIT + ((gamespeed-1) * (FRACUNIT/4))); - const fixed_t distaway = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); - if (distaway < distbarrier) - { - if (actor->tracer->player) - { - fixed_t speeddifference = abs(topspeed - min(actor->tracer->player->speed, K_GetKartSpeed(actor->tracer->player, false, false))); - topspeed = topspeed - FixedMul(speeddifference, FRACUNIT-FixedDiv(distaway, distbarrier)); - } - } - } - - if (angledelta != 0) - { - angle_t MAX_JAWZ_TURN = ANGLE_90/15; // We can turn a maximum of 6 degrees per frame at regular max speed - // MAX_JAWZ_TURN gets stronger the slower the top speed of jawz - if (topspeed < actor->movefactor) - { - if (topspeed == 0) - { - MAX_JAWZ_TURN = ANGLE_180; - } - else - { - fixed_t anglemultiplier = FixedDiv(actor->movefactor, topspeed); - MAX_JAWZ_TURN += FixedAngle(FixedMul(AngleFixed(MAX_JAWZ_TURN), anglemultiplier)); - } - } - - if (angledelta > ANGLE_180) - { - angledelta = InvAngle(angledelta); - turnclockwise = false; - } - - if (angledelta > MAX_JAWZ_TURN) - { - angledelta = MAX_JAWZ_TURN; - } - - if (turnclockwise) - { - actor->angle -= angledelta; - } - else - { - actor->angle += angledelta; - } - } - - ret = P_SpawnMobj(actor->tracer->x, actor->tracer->y, actor->tracer->z, MT_PLAYERRETICULE); - ret->old_x = actor->tracer->old_x; - ret->old_y = actor->tracer->old_y; - ret->old_z = actor->tracer->old_z; - P_SetTarget(&ret->target, actor->tracer); - ret->frame |= ((leveltime % 10) / 2) + 5; - ret->color = actor->cvmem; - } - else - P_SetTarget(&actor->tracer, NULL); - } - - if (!actor->tracer) - { - actor->angle = K_MomentumAngle(actor); - } - - if (P_IsObjectOnGround(actor)) - { - const fixed_t currentspeed = R_PointToDist2(0, 0, actor->momx, actor->momy); - - if (currentspeed >= topspeed) - { - // Thrust as if you were at top speed, slow down naturally - thrustamount = FixedDiv(topspeed, frictionsafety) - topspeed; - } - else - { - const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; - // Thrust to immediately get to top speed - thrustamount = beatfriction + FixedDiv(topspeed - currentspeed, frictionsafety); - } - - P_Thrust(actor, actor->angle, thrustamount); - } - - if ((actor->tracer != NULL) && (actor->tracer->health > 0)) - return; - - if (actor->extravalue1) // Disable looking by setting this - return; - - if (!actor->target || P_MobjWasRemoved(actor->target)) // No source! - return; - - player = K_FindJawzTarget(actor, actor->target->player); - if (player) - P_SetTarget(&actor->tracer, player->mo); - - return; -} - void A_JawzExplode(mobj_t *actor) { INT32 shrapnel = 2; diff --git a/src/p_inter.c b/src/p_inter.c index 4974338bb..0f185ea6f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -916,7 +916,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget // SRB2kart if (target->type != MT_PLAYER && !(target->flags & MF_MONITOR) && !(target->type == MT_ORBINAUT || target->type == MT_ORBINAUT_SHIELD - || target->type == MT_JAWZ || target->type == MT_JAWZ_DUD || target->type == MT_JAWZ_SHIELD + || target->type == MT_JAWZ || target->type == MT_JAWZ_SHIELD || target->type == MT_BANANA || target->type == MT_BANANA_SHIELD || target->type == MT_DROPTARGET || target->type == MT_DROPTARGET_SHIELD || target->type == MT_EGGMANITEM || target->type == MT_EGGMANITEM_SHIELD @@ -1497,7 +1497,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget break; } - if ((target->type == MT_JAWZ || target->type == MT_JAWZ_DUD || target->type == MT_JAWZ_SHIELD) && !(target->flags2 & MF2_AMBUSH)) + if ((target->type == MT_JAWZ || target->type == MT_JAWZ_SHIELD) && !(target->flags2 & MF2_AMBUSH)) { target->z += P_MobjFlip(target)*20*target->scale; } diff --git a/src/p_map.c b/src/p_map.c index 619f8698a..07d610fb8 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -863,7 +863,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) // Bubble Shield reflect if (((thing->type == MT_BUBBLESHIELD && thing->target->player && thing->target->player->bubbleblowup) || (thing->player && thing->player->bubbleblowup)) - && (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD + && (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_BANANA || tmthing->type == MT_EGGMANITEM || tmthing->type == MT_BALLHOG || tmthing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || tmthing->type == MT_SINK || (tmthing->type == MT_PLAYER && thing->target != tmthing))) @@ -878,7 +878,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) } else if (((tmthing->type == MT_BUBBLESHIELD && tmthing->target->player && tmthing->target->player->bubbleblowup) || (tmthing->player && tmthing->player->bubbleblowup)) - && (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD + && (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG || thing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || thing->type == MT_SINK || (thing->type == MT_PLAYER && tmthing->target != thing))) @@ -898,7 +898,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) // Droptarget reflect if ((thing->type == MT_DROPTARGET || thing->type == MT_DROPTARGET_SHIELD) - && (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD + && (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_BANANA || tmthing->type == MT_EGGMANITEM || tmthing->type == MT_BALLHOG || tmthing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || tmthing->type == MT_SINK || (tmthing->type == MT_PLAYER))) @@ -912,7 +912,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) return K_DropTargetCollide(thing, tmthing) ? BMIT_CONTINUE : BMIT_ABORT; } else if ((tmthing->type == MT_DROPTARGET || tmthing->type == MT_DROPTARGET_SHIELD) - && (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD + && (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG || thing->type == MT_SSMINE || tmthing->type == MT_LANDMINE || thing->type == MT_SINK || (thing->type == MT_PLAYER))) @@ -931,7 +931,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) || thing->type == MT_DROPTARGET_SHIELD || tmthing->type == MT_DROPTARGET_SHIELD) return BMIT_CONTINUE; - if (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD + if (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_ORBINAUT_SHIELD || tmthing->type == MT_JAWZ_SHIELD) { // see if it went over / under @@ -940,9 +940,9 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) if (tmthing->z + tmthing->height < thing->z) return BMIT_CONTINUE; // underneath - return K_OrbinautJawzCollide(tmthing, thing) ? BMIT_CONTINUE : BMIT_ABORT; + return Obj_OrbinautJawzCollide(tmthing, thing) ? BMIT_CONTINUE : BMIT_ABORT; } - else if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD + else if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD) { // see if it went over / under @@ -951,7 +951,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) if (tmthing->z + tmthing->height < thing->z) return BMIT_CONTINUE; // underneath - return K_OrbinautJawzCollide(thing, tmthing) ? BMIT_CONTINUE : BMIT_ABORT; + return Obj_OrbinautJawzCollide(thing, tmthing) ? BMIT_CONTINUE : BMIT_ABORT; } if (tmthing->type == MT_BANANA || tmthing->type == MT_BANANA_SHIELD || tmthing->type == MT_BALLHOG) diff --git a/src/p_mobj.c b/src/p_mobj.c index 626a4280a..9c7b48aca 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1743,7 +1743,6 @@ void P_XYMovement(mobj_t *mo) /*FALLTHRU*/ case MT_JAWZ: - case MT_JAWZ_DUD: if (mo->health == 1) { // This Item Damage @@ -2181,7 +2180,6 @@ boolean P_ZMovement(mobj_t *mo) case MT_BANANA: case MT_ORBINAUT: case MT_JAWZ: - case MT_JAWZ_DUD: case MT_BALLHOG: case MT_SSMINE: case MT_LANDMINE: @@ -4993,7 +4991,7 @@ boolean P_IsKartItem(INT32 type) type == MT_BANANA || type == MT_BANANA_SHIELD || type == MT_DROPTARGET || type == MT_DROPTARGET_SHIELD || type == MT_ORBINAUT || type == MT_ORBINAUT_SHIELD || - type == MT_JAWZ || type == MT_JAWZ_DUD || type == MT_JAWZ_SHIELD || + type == MT_JAWZ || type == MT_JAWZ_SHIELD || type == MT_SSMINE || type == MT_SSMINE_SHIELD || type == MT_SINK || type == MT_SINK_SHIELD || type == MT_SPB || type == MT_BALLHOG || type == MT_BUBBLESHIELDTRAP || @@ -6328,7 +6326,6 @@ static boolean P_MobjDeadThink(mobj_t *mobj) mobj->renderflags ^= RF_DONTDRAW; break; case MT_JAWZ: - case MT_JAWZ_DUD: if (P_IsObjectOnGround(mobj)) P_SetMobjState(mobj, mobj->info->xdeathstate); /* FALLTHRU */ @@ -6712,164 +6709,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj) break; case MT_ORBINAUT: { - boolean grounded = P_IsObjectOnGround(mobj); - - if (mobj->flags2 & MF2_AMBUSH) - { - if (grounded && (mobj->flags & MF_NOCLIPTHING)) - { - mobj->momx = 1; - mobj->momy = 0; - mobj->frame = 3; - S_StartSound(mobj, mobj->info->activesound); - mobj->flags &= ~MF_NOCLIPTHING; - } - else if (mobj->movecount) - mobj->movecount--; - else if (mobj->frame < 3) - { - mobj->movecount = 2; - mobj->frame++; - } - } - else - { - mobj_t *ghost = P_SpawnGhostMobj(mobj); - ghost->colorized = true; // already has color! - - mobj->angle = K_MomentumAngle(mobj); - - if (P_IsObjectOnGround(mobj)) - { - fixed_t finalspeed = mobj->movefactor; - const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy); - fixed_t thrustamount = 0; - fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction; - - if (!grounded) - { - // No friction in the air - frictionsafety = FRACUNIT; - } - - if (mobj->health <= 5) - { - INT32 i; - for (i = 5; i >= mobj->health; i--) - finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4); - } - - if (currentspeed >= finalspeed) - { - // Thrust as if you were at top speed, slow down naturally - thrustamount = FixedDiv(finalspeed, frictionsafety) - finalspeed; - } - else - { - const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; - // Thrust to immediately get to top speed - thrustamount = beatfriction + FixedDiv(finalspeed - currentspeed, frictionsafety); - } - - P_Thrust(mobj, mobj->angle, thrustamount); - } - - if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) - K_DoPogoSpring(mobj, 0, 1); - - if (mobj->threshold > 0) - mobj->threshold--; - - if (leveltime % 6 == 0) - S_StartSound(mobj, mobj->info->activesound); - } + Obj_OrbinautThink(mobj); break; } case MT_JAWZ: { - mobj_t *ghost = P_SpawnGhostMobj(mobj); - - if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) - { - ghost->color = mobj->target->player->skincolor; - ghost->colorized = true; - } - - if (mobj->threshold > 0) - mobj->threshold--; - if (leveltime % TICRATE == 0) - S_StartSound(mobj, mobj->info->activesound); - - // Movement handling has ALL been moved to A_JawzChase - - K_DriftDustHandling(mobj); - - if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) - K_DoPogoSpring(mobj, 0, 1); - - if (!(gametyperules & GTR_CIRCUIT)) - mobj->friction = max(0, 3 * mobj->friction / 4); - - break; - } - case MT_JAWZ_DUD: - { - boolean grounded = P_IsObjectOnGround(mobj); - - if (mobj->flags2 & MF2_AMBUSH) - { - if (grounded && (mobj->flags & MF_NOCLIPTHING)) - { - mobj->momx = 1; - mobj->momy = 0; - S_StartSound(mobj, mobj->info->deathsound); - mobj->flags &= ~MF_NOCLIPTHING; - } - } - else - { - mobj_t *ghost = P_SpawnGhostMobj(mobj); - const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy); - fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction; - fixed_t thrustamount = 0; - - if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) - { - ghost->color = mobj->target->player->skincolor; - ghost->colorized = true; - } - - if (!grounded) - { - // No friction in the air - frictionsafety = FRACUNIT; - } - - if (currentspeed >= mobj->movefactor) - { - // Thrust as if you were at top speed, slow down naturally - thrustamount = FixedDiv(mobj->movefactor, frictionsafety) - mobj->movefactor; - } - else - { - const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; - // Thrust to immediately get to top speed - thrustamount = beatfriction + FixedDiv(mobj->movefactor - currentspeed, frictionsafety); - } - - mobj->angle = K_MomentumAngle(mobj); - P_Thrust(mobj, mobj->angle, thrustamount); - - if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) - K_DoPogoSpring(mobj, 0, 1); - - if (mobj->threshold > 0) - mobj->threshold--; - - if (leveltime % TICRATE == 0) - S_StartSound(mobj, mobj->info->activesound); - } - + Obj_JawzThink(mobj); break; } case MT_EGGMANITEM: @@ -9450,7 +9295,7 @@ void P_MobjThinker(mobj_t *mobj) // Destroy items sector special if (mobj->type == MT_BANANA || mobj->type == MT_EGGMANITEM || mobj->type == MT_ORBINAUT || mobj->type == MT_BALLHOG - || mobj->type == MT_JAWZ || mobj->type == MT_JAWZ_DUD + || mobj->type == MT_JAWZ || mobj->type == MT_SSMINE || mobj->type == MT_BUBBLESHIELDTRAP || mobj->type == MT_LANDMINE) { @@ -9539,7 +9384,7 @@ void P_MobjThinker(mobj_t *mobj) || mobj->type == MT_CANNONBALLDECOR || mobj->type == MT_FALLINGROCK || mobj->type == MT_ORBINAUT - || mobj->type == MT_JAWZ || mobj->type == MT_JAWZ_DUD + || mobj->type == MT_JAWZ || (mobj->type == MT_DROPTARGET && mobj->reactiontime)) { P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly @@ -9841,7 +9686,6 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_ORBINAUT: case MT_ORBINAUT_SHIELD: case MT_JAWZ: - case MT_JAWZ_DUD: case MT_JAWZ_SHIELD: case MT_SSMINE: case MT_SSMINE_SHIELD: