mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'master' into rng-states-2
This commit is contained in:
commit
15edb40eb5
17 changed files with 881 additions and 658 deletions
|
|
@ -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
|
||||
|
|
|
|||
52
src/info.c
52
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
|
||||
|
|
|
|||
11
src/info.h
11
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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
104
src/k_collide.c
104
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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
357
src/k_kart.c
357
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<<FRACBITS) - AngleFixed(input)) / 180) // multiply speed based on angle diff... i.e: don't do this for firing backward :V
|
||||
)));
|
||||
finalspeed = max(speed, FixedMul(
|
||||
speed,
|
||||
FixedMul(
|
||||
FixedDiv(source->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)
|
||||
|
|
@ -6265,7 +6250,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:
|
||||
|
|
@ -6322,6 +6307,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;
|
||||
|
|
@ -6383,7 +6374,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;
|
||||
}
|
||||
|
|
@ -6771,8 +6762,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;
|
||||
|
|
@ -6787,14 +6781,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;
|
||||
}
|
||||
|
||||
|
|
@ -6805,80 +6803,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:
|
||||
|
|
@ -7088,94 +7015,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8246,19 +8189,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;
|
||||
|
|
@ -8273,17 +8266,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
|
||||
{
|
||||
|
|
@ -10277,10 +10259,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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
|
|
@ -3635,7 +3635,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,3 +3,5 @@ shrink.c
|
|||
item-debris.c
|
||||
spb.c
|
||||
manta-ring.c
|
||||
orbinaut.c
|
||||
jawz.c
|
||||
|
|
|
|||
292
src/objects/jawz.c
Normal file
292
src/objects/jawz.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
379
src/objects/orbinaut.c
Normal file
379
src/objects/orbinaut.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
127
src/p_enemy.c
127
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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
16
src/p_map.c
16
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)
|
||||
|
|
|
|||
166
src/p_mobj.c
166
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:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue