Held item changes

This commit is contained in:
SeventhSentinel 2018-06-27 15:58:43 -04:00
parent 8bc27d9386
commit dd04d68c09
5 changed files with 227 additions and 132 deletions

View file

@ -2083,7 +2083,7 @@ void K_DriftDustHandling(mobj_t *spawner)
}
}
static mobj_t *K_FindLastTrailMobj(player_t *player) // YUCK, i hate this!
static mobj_t *K_FindLastTrailMobj(player_t *player)
{
mobj_t *trail = player->mo->hnext;
@ -2473,6 +2473,165 @@ void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source)
}
}
void K_RepairOrbitChain(mobj_t *orbit)
{
mobj_t *cachenext = orbit->hnext;
// First, repair the chain
if (orbit->hnext && !P_MobjWasRemoved(orbit->hnext))
{
P_SetTarget(&orbit->hnext->hprev, orbit->hprev);
P_SetTarget(&orbit->hnext, NULL);
}
if (orbit->hprev && !P_MobjWasRemoved(orbit->hprev))
{
P_SetTarget(&orbit->hprev->hnext, cachenext);
P_SetTarget(&orbit->hprev, NULL);
}
// Then recount to make sure item amount is correct
if (orbit->target && orbit->target->player)
{
mobj_t *cur = NULL;
mobj_t *prev = NULL;
INT32 num = 0;
if (orbit->target->hnext)
cur = orbit->target->hnext;
while (cur && !P_MobjWasRemoved(cur) && cur != orbit->target->player->mo)
{
num++;
prev = cur;
cur = cur->hnext;
if (num > orbit->target->player->kartstuff[k_itemamount])
P_RemoveMobj(prev);
}
if (orbit->target->player->kartstuff[k_itemamount] != num)
orbit->target->player->kartstuff[k_itemamount] = num;
}
}
static void K_MoveHeldObjects(player_t *player)
{
if (!player->mo)
return;
if (!player->mo->hnext)
return;
switch (player->mo->hnext->type)
{
case MT_GREENSHIELD: // Kart orbit items
case MT_JAWZ_SHIELD:
{
mobj_t *cur = player->mo->hnext;
while (cur && !P_MobjWasRemoved(cur) && cur != player->mo)
{
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;
cur->angle -= ANGLE_90;
cur->angle += FixedAngle(cur->info->speed);
// 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->scale = player->mo->scale;
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_TeleportMove(cur, player->mo->x, player->mo->y, z);
cur->momx = FixedMul(FINECOSINE(cur->angle>>ANGLETOFINESHIFT), radius);
cur->momy = FixedMul(FINESINE(cur->angle>>ANGLETOFINESHIFT), radius);
cur->flags &= ~MF_NOCLIPTHING;
if (!P_TryMove(cur, player->mo->x + cur->momx, player->mo->y + cur->momy, true))
P_SlideMove(cur, true);
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;
}
}
cur->z = z;
cur->momx = cur->momy = 0;
cur->angle += ANGLE_90;
cur = cur->hnext;
}
}
break;
case MT_BANANA_SHIELD: // Kart trailing items
case MT_SSMINE_SHIELD:
case MT_FAKESHIELD:
{
mobj_t *cur = player->mo->hnext;
mobj_t *targ = player->mo;
while (cur && !P_MobjWasRemoved(cur) && cur != player->mo)
{
const fixed_t spacing = FixedMul(3*cur->info->radius/2, player->mo->scale);
angle_t ang;
fixed_t targx;
fixed_t targy;
fixed_t targz;
fixed_t speed;
fixed_t dist = spacing;
if (cur != player->mo->hnext)
{
targ = cur->hprev;
dist = spacing/2;
}
if (!targ || P_MobjWasRemoved(targ))
continue;
ang = targ->angle;
targx = targ->x + P_ReturnThrustX(cur, ang + ANGLE_180, dist);
targy = targ->y + P_ReturnThrustY(cur, ang + ANGLE_180, dist);
targz = targ->z;
speed = FixedMul(R_PointToDist2(cur->x, cur->y, targx, targy), 3*FRACUNIT/4);
if (P_IsObjectOnGround(targ))
targz = cur->floorz;
cur->angle = R_PointToAngle2(cur->x, cur->y, targx, targy);
if (speed > dist)
P_InstaThrust(cur, cur->angle, speed-dist);
P_SetObjectMomZ(cur, FixedMul(targz - cur->z, 3*FRACUNIT/4) - gravity, false);
if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT)
P_TeleportMove(cur, targx, targy, cur->z);
cur = cur->hnext;
}
}
break;
default:
break;
}
}
/** \brief Decreases various kart timers and powers per frame. Called in P_PlayerThink in p_user.c
\param player player object passed from P_PlayerThink
@ -2675,6 +2834,9 @@ void K_KartPlayerAfterThink(player_t *player)
if (!(player->mo->state->frame & FF_FULLBRIGHT))
player->mo->frame &= ~FF_FULLBRIGHT;
}
// Move held objects (Bananas, Orbinaut, etc)
K_MoveHeldObjects(player);
}
// Returns false if this player being placed here causes them to collide with any other player
@ -3187,31 +3349,40 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
case KITEM_ORBINAUT:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
{
angle_t newangle;
fixed_t newx;
fixed_t newy;
INT32 moloop;
mobj_t *mo;
mobj_t *prev = NULL;
//K_PlayTauntSound(player->mo);
player->kartstuff[k_itemheld] = 1;
player->pflags |= PF_ATTACKDOWN;
//K_PlayTauntSound(player->mo);
S_StartSound(player->mo, sfx_s3k3a);
for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++)
{
angle_t newangle;
fixed_t newx;
fixed_t newy;
mobj_t *mo;
newangle = player->mo->angle;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT);
newangle = FixedAngle(((360/player->kartstuff[k_itemamount])*moloop)*FRACUNIT) + ANGLE_90;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 64*FRACUNIT);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 64*FRACUNIT);
mo = P_SpawnMobj(newx, newy, player->mo->z, MT_GREENSHIELD);
if (mo)
mo->angle = newangle;
mo->threshold = 10;
mo->movecount = player->kartstuff[k_itemamount];
mo->lastlook = moloop+1;
P_SetTarget(&mo->target, player->mo);
if (moloop > 0)
{
mo->threshold = 10;
mo->lastlook = moloop+1;
P_SetTarget(&mo->target, player->mo);
mo->angle = FixedAngle(((360/player->kartstuff[k_itemamount])*moloop)*FRACUNIT) + ANGLE_90;
P_SetTarget(&mo->hprev, prev);
if (prev != NULL)
P_SetTarget(&prev->hnext, mo);
}
else
P_SetTarget(&player->mo->hnext, mo);
if (moloop == player->kartstuff[k_itemamount]-1) // Complete loop for orbit items
P_SetTarget(&mo->hnext, player->mo);
prev = mo;
}
}
else if (ATTACK_IS_DOWN && player->kartstuff[k_itemheld]) // Orbinaut x3 thrown
@ -3228,31 +3399,40 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
case KITEM_JAWZ:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
{
angle_t newangle;
fixed_t newx;
fixed_t newy;
INT32 moloop;
mobj_t *mo;
mobj_t *prev = NULL;
//K_PlayTauntSound(player->mo);
player->kartstuff[k_itemheld] = 1;
player->pflags |= PF_ATTACKDOWN;
//K_PlayTauntSound(player->mo);
S_StartSound(player->mo, sfx_s3k3a);
for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++)
{
angle_t newangle;
fixed_t newx;
fixed_t newy;
mobj_t *mo;
newangle = player->mo->angle;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT);
newangle = FixedAngle(((360/player->kartstuff[k_itemamount])*moloop)*FRACUNIT) + ANGLE_90;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 64*FRACUNIT);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 64*FRACUNIT);
mo = P_SpawnMobj(newx, newy, player->mo->z, MT_JAWZ_SHIELD);
if (mo)
mo->angle = newangle;
mo->threshold = 10;
mo->movecount = player->kartstuff[k_itemamount];
mo->lastlook = moloop+1;
P_SetTarget(&mo->target, player->mo);
if (moloop > 0)
{
mo->threshold = 10;
mo->lastlook = moloop+1;
P_SetTarget(&mo->target, player->mo);
mo->angle = FixedAngle(((360/player->kartstuff[k_itemamount])*moloop)*FRACUNIT) + ANGLE_90;
P_SetTarget(&mo->hprev, prev);
if (prev != NULL)
P_SetTarget(&prev->hnext, mo);
}
else
P_SetTarget(&player->mo->hnext, mo);
if (moloop == player->kartstuff[k_itemamount]-1) // Complete loop for orbit items
P_SetTarget(&mo->hnext, player->mo);
prev = mo;
}
}
else if (ATTACK_IS_DOWN && HOLDING_ITEM && player->kartstuff[k_itemheld]) // Jawz thrown

View file

@ -36,6 +36,7 @@ void K_DriftDustHandling(mobj_t *spawner);
void K_DoSneaker(player_t *player, boolean doPFlag);
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed);
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source);
void K_RepairOrbitChain(mobj_t *orbit);
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
void K_StripItems(player_t *player);

View file

@ -2149,6 +2149,16 @@ static int lib_kKillBananaChain(lua_State *L)
return 0;
}
static int lib_kRepairOrbitChain(lua_State *L)
{
mobj_t *orbit = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
if (!orbit)
return LUA_ErrInvalid(L, "mobj_t");
K_RepairOrbitChain(orbit);
return 0;
}
static int lib_kMomentumToFacing(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -2377,6 +2387,7 @@ static luaL_Reg lib[] = {
{"K_DoSneaker",lib_kDoSneaker},
{"K_DoPogoSpring",lib_kDoPogoSpring},
{"K_KillBananaChain",lib_kKillBananaChain},
{"K_RepairOrbitChain",lib_kRepairOrbitChain},
{"K_MomentumToFacing",lib_kMomentumToFacing},
{"K_GetKartSpeed",lib_kGetKartSpeed},
{"K_GetKartAccel",lib_kGetKartAccel},

View file

@ -2122,7 +2122,13 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
}
else if ((target->type == MT_GREENSHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_ORBINAUT) // orbit items
|| (target->type == MT_JAWZ_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_JAWZ))
{
target->target->player->kartstuff[k_itemamount]--;
if (target->lastlook != 0)
{
K_RepairOrbitChain(target);
}
}
if (target->target->player->kartstuff[k_itemamount] < 0)
target->target->player->kartstuff[k_itemamount] = 0;

View file

@ -6697,63 +6697,6 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->health > 0 && mobj->target && mobj->target->player
&& mobj->target->player->health > 0 && !mobj->target->player->spectator)
{
fixed_t z;
const fixed_t radius = FixedHypot(mobj->target->radius, mobj->target->radius) + FixedHypot(mobj->radius, mobj->radius); // mobj's distance from its Target, or Radius.
mobj->angle -= ANGLE_90;
mobj->angle += FixedAngle(mobj->info->speed);
// If the player is on the ceiling, then flip your items as well.
if (mobj->target->player && mobj->target->eflags & MFE_VERTICALFLIP)
{
mobj->eflags |= MFE_VERTICALFLIP;
}
else
{
mobj->eflags &= ~MFE_VERTICALFLIP;
}
// Shrink your items if the player shrunk too.
if (mobj->target->player)
mobj->scale = mobj->target->scale;
if (P_MobjFlip(mobj) > 0)
{
z = mobj->target->z;
}
else
{
z = mobj->target->z + mobj->target->height - mobj->height;
}
mobj->flags |= MF_NOCLIPTHING; // temporarily make them noclip other objects so they can't hit anyone while in the player
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, z);
mobj->momx = FixedMul(FINECOSINE(mobj->angle>>ANGLETOFINESHIFT),radius);
mobj->momy = FixedMul(FINESINE(mobj->angle>>ANGLETOFINESHIFT), radius);
mobj->flags &= ~MF_NOCLIPTHING;
if (!P_TryMove(mobj, mobj->target->x + mobj->momx, mobj->target->y + mobj->momy, true))
P_SlideMove(mobj, true);
if (P_IsObjectOnGround(mobj->target))
{
if (P_MobjFlip(mobj) > 0)
{
if (mobj->floorz > mobj->target->z - mobj->height)
{
z = mobj->floorz;
}
}
else
{
if (mobj->ceilingz < mobj->target->z + mobj->target->height + mobj->height)
{
z = mobj->ceilingz - mobj->height;
}
}
}
mobj->z = z;
mobj->momx = mobj->momy = 0;
mobj->angle += ANGLE_90;
// Was this so hard?
if ((mobj->type == MT_GREENSHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_ORBINAUT)
|| (mobj->type == MT_JAWZ_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_JAWZ)
@ -6779,52 +6722,6 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->health > 0 && mobj->target && mobj->target->player
&& mobj->target->player->health > 0 && !mobj->target->player->spectator)
{
if (mobj->lastlook == 1)
{
const fixed_t spacing = FixedMul(3*mobj->info->radius/2, mobj->target->scale);
mobj_t *cur = mobj;
mobj_t *targ = mobj->target;
while (cur && !P_MobjWasRemoved(cur))
{
angle_t ang;
fixed_t targx;
fixed_t targy;
fixed_t targz;
fixed_t speed;
fixed_t dist = spacing;
if (cur != mobj)
{
targ = cur->hprev;
dist = spacing/2;
}
if (!targ || P_MobjWasRemoved(targ))
continue;
ang = targ->angle;
targx = targ->x + P_ReturnThrustX(cur, ang + ANGLE_180, dist);
targy = targ->y + P_ReturnThrustY(cur, ang + ANGLE_180, dist);
targz = targ->z;
speed = FixedMul(R_PointToDist2(cur->x, cur->y, targx, targy), 3*FRACUNIT/4);
if (P_IsObjectOnGround(targ))
targz = cur->floorz;
cur->angle = R_PointToAngle2(cur->x, cur->y, targx, targy);
if (speed > dist)
P_InstaThrust(cur, cur->angle, speed-dist);
P_SetObjectMomZ(cur, FixedMul(targz - cur->z, 3*FRACUNIT/4) - gravity, false);
if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT)
P_TeleportMove(cur, targx, targy, cur->z);
cur = cur->hnext;
}
}
// Was this so hard?
if ((mobj->type == MT_BANANA_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_BANANA)
|| (mobj->type == MT_SSMINE_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_MINE)