mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Add orbinaut.c + new backwards behavior
This commit is contained in:
parent
bf25bb6d85
commit
cc331d90da
9 changed files with 420 additions and 266 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
124
src/k_kart.c
124
src/k_kart.c
|
|
@ -4674,7 +4674,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 +4688,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((ANGLE_180 - delta), ANGLE_180) // multiply speed based on angle diff... i.e: don't do this for firing backward :V
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
finalscale = K_ItemScaleForPlayer(source->player);
|
||||
|
|
@ -4763,11 +4763,7 @@ 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)
|
||||
|
|
@ -4784,10 +4780,10 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
|
|||
}
|
||||
else
|
||||
th->cvmem = SKINCOLOR_KETCHUP;
|
||||
/* FALLTHRU */
|
||||
case MT_JAWZ_DUD:
|
||||
|
||||
S_StartSound(th, th->info->activesound);
|
||||
/* FALLTHRU */
|
||||
th->movefactor = finalspeed;
|
||||
break;
|
||||
case MT_SPB:
|
||||
th->movefactor = finalspeed;
|
||||
break;
|
||||
|
|
@ -5626,12 +5622,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);
|
||||
mo = K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) + angleOffset, 0, PROJSPEED / 8, 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)
|
||||
|
|
@ -6402,6 +6398,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;
|
||||
|
|
@ -6851,8 +6853,11 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
if (!player->mo->hnext)
|
||||
{
|
||||
player->bananadrag = 0;
|
||||
|
||||
if (player->pflags & PF_EGGMANOUT)
|
||||
{
|
||||
player->pflags &= ~PF_EGGMANOUT;
|
||||
}
|
||||
else if (player->pflags & PF_ITEMOUT)
|
||||
{
|
||||
player->itemamount = 0;
|
||||
|
|
@ -6867,14 +6872,18 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
// we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic...
|
||||
P_SetTarget(&player->mo->hnext, NULL);
|
||||
player->bananadrag = 0;
|
||||
|
||||
if (player->pflags & PF_EGGMANOUT)
|
||||
{
|
||||
player->pflags &= ~PF_EGGMANOUT;
|
||||
}
|
||||
else if (player->pflags & PF_ITEMOUT)
|
||||
{
|
||||
player->itemamount = 0;
|
||||
K_UnsetItemOut(player);
|
||||
player->itemtype = KITEM_NONE;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -6885,80 +6894,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_OrbinautMoveHeld(player);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MT_BANANA_SHIELD: // Kart trailing items
|
||||
case MT_SSMINE_SHIELD:
|
||||
case MT_DROPTARGET_SHIELD:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -29,4 +29,10 @@ 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_OrbinautMoveHeld(player_t *player);
|
||||
|
||||
#endif/*k_objects_H*/
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@ shrink.c
|
|||
item-debris.c
|
||||
spb.c
|
||||
manta-ring.c
|
||||
orbinaut.c
|
||||
|
|
|
|||
377
src/objects/orbinaut.c
Normal file
377
src/objects/orbinaut.c
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
// 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_center(o) ((o)->tracer)
|
||||
|
||||
#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 <= 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 || 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;
|
||||
}
|
||||
|
||||
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_OrbinautMoveHeld(player_t *player)
|
||||
{
|
||||
fixed_t finalscale = K_ItemScaleForPlayer(player);
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
|
|
@ -940,7 +940,7 @@ 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
|
||||
|| thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD)
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
72
src/p_mobj.c
72
src/p_mobj.c
|
|
@ -6712,77 +6712,7 @@ 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:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue