Add jawz.c + new backwards behavior

This commit is contained in:
Sally Coolatta 2022-09-25 11:27:07 -04:00
parent cc331d90da
commit b0e3840550
16 changed files with 388 additions and 384 deletions

View file

@ -320,7 +320,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"},
@ -3523,14 +3522,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",
@ -5337,7 +5328,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

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -80,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
@ -334,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
@ -395,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

View file

@ -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);
@ -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
@ -4766,23 +4771,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
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;
S_StartSound(th, th->info->activesound);
th->movefactor = finalspeed;
Obj_JawzThrown(th, finalspeed, dir);
break;
case MT_SPB:
th->movefactor = finalspeed;
@ -5622,12 +5611,12 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
if (dir == -1 && mapthing != MT_SPB)
{
// Shoot backward
mo = K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) + angleOffset, 0, PROJSPEED / 8, dir);
mo = K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) + angleOffset, 0, PROJSPEED, -1);
}
else
{
// Shoot forward
mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + angleOffset, 0, PROJSPEED, dir);
mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + angleOffset, 0, PROJSPEED, 1);
}
if (mapthing == MT_DROPTARGET && mo)
@ -6341,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:
@ -6465,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;
}
@ -6894,7 +6883,7 @@ static void K_MoveHeldObjects(player_t *player)
case MT_ORBINAUT_SHIELD: // Kart orbit items
case MT_JAWZ_SHIELD:
{
Obj_OrbinautMoveHeld(player);
Obj_OrbinautJawzMoveHeld(player);
break;
}
case MT_BANANA_SHIELD: // Kart trailing items
@ -7106,95 +7095,111 @@ 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;
}
// 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))
if (player->position > source->position)
{
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))
{
wtarg = player;
best = thisavg;
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;
}
thisdist = P_AproxDistance(player->mo->x - (actor->x + actor->momx), player->mo->y - (actor->y + actor->momy));
// Don't go for people who are too far away
if (thisdist > 2*RING_DIST)
{
continue;
}
thisScore = (AngleFixed(thisang) * 2) + (thisdist / 2);
//CONS_Printf("got score %f from player # %d\n", FixedToFloat(thisScore), i);
if (thisScore < best)
{
wtarg = player;
best = thisScore;
}
}
return wtarg;
@ -8274,7 +8279,7 @@ void K_KartPlayerAfterThink(player_t *player)
player->jawztargetdelay--;
}
else
targ = K_FindJawzTarget(player->mo, player);
targ = K_FindJawzTarget(player->mo, player, ANGLE_45);
if (!targ || !targ->mo || P_MobjWasRemoved(targ->mo))
{
@ -10295,10 +10300,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);

View file

@ -118,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);

View file

@ -33,6 +33,10 @@ mobj_t *Obj_MantaRingCreate(mobj_t *spb, mobj_t *owner, mobj_t *chase);
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_OrbinautMoveHeld(player_t *player);
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*/

View file

@ -3651,7 +3651,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;
}

View file

@ -4,3 +4,4 @@ item-debris.c
spb.c
manta-ring.c
orbinaut.c
jawz.c

269
src/objects/jawz.c Normal file
View file

@ -0,0 +1,269 @@
// 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_owner(o) ((o)->target)
#define jawz_chase(o) ((o)->tracer)
#define jawz_shield_dist(o) ((o)->extravalue1)
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);
}
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 (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 (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));
th->fuse = RR_PROJECTILE_FUSE;
finalSpeed = FixedMul(finalSpeed, 4*FRACUNIT/5);
}
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;
}

View file

@ -36,7 +36,6 @@
#define orbinaut_turn(o) ((o)->extravalue1)
#define orbinaut_owner(o) ((o)->target)
#define orbinaut_center(o) ((o)->tracer)
#define orbinaut_shield_dist(o) ((o)->extravalue1)
@ -45,7 +44,7 @@ void Obj_OrbinautThink(mobj_t *th)
boolean grounded = P_IsObjectOnGround(th);
mobj_t *ghost = NULL;
if (th->fuse <= TICRATE)
if (th->fuse > 0 && th->fuse <= TICRATE)
{
th->renderflags ^= RF_DONTDRAW;
}
@ -177,7 +176,7 @@ boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
if (t2->player)
{
if ((t2->player->flashing > 0 && t2->hitlag == 0)
&& !(t1->type == MT_ORBINAUT || t1->type == MT_JAWZ || t1->type == MT_JAWZ_DUD))
&& !(t1->type == MT_ORBINAUT || t1->type == MT_JAWZ))
return true;
if (t2->player->hyudorotimer)
@ -198,7 +197,7 @@ boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
damageitem = true;
}
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
|| t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD
|| t2->type == MT_BALLHOG)
@ -279,7 +278,7 @@ void Obj_OrbinautThrown(mobj_t *th, fixed_t finalSpeed, SINT8 dir)
}
}
void Obj_OrbinautMoveHeld(player_t *player)
void Obj_OrbinautJawzMoveHeld(player_t *player)
{
fixed_t finalscale = K_ItemScaleForPlayer(player);
mobj_t *cur = player->mo->hnext;

View file

@ -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);
@ -13207,132 +13206,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;

View file

@ -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;
}

View file

@ -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
@ -942,7 +942,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
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

View file

@ -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 */
@ -6717,89 +6714,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
}
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:
@ -9380,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)
{
@ -9469,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
@ -9771,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: