diff --git a/src/k_kart.c b/src/k_kart.c index 0b166531f..744ff305d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2363,10 +2363,15 @@ void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics) INT32 tics1 = tics; INT32 tics2 = tics; + if (tics <= 0) + { + return; + } + if (mo1valid == true && mo2valid == true) { + const INT32 mintics = 1; const fixed_t ticaddfactor = mapobjectscale * 8; - const INT32 mintics = tics; const fixed_t mo1speed = FixedHypot(FixedHypot(mo1->momx, mo1->momy), mo1->momz); const fixed_t mo2speed = FixedHypot(FixedHypot(mo2->momx, mo2->momy), mo2->momz); @@ -2411,12 +2416,12 @@ void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics) if (mo1valid == true) { - mo1->hitlag += tics1; + mo1->hitlag = max(tics1, mo1->hitlag); } if (mo2valid == true) { - mo2->hitlag += tics2; + mo2->hitlag = max(tics2, mo2->hitlag); } } @@ -3604,10 +3609,11 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map else { // Use pre-determined speed for tossing - PROJSPEED = FixedMul(82 << FRACBITS, K_GetKartGameSpeedScalar(gamespeed)); + PROJSPEED = FixedMul(82 * FRACUNIT, K_GetKartGameSpeedScalar(gamespeed)); } - // Scale to map size + // Scale to map scale + // Intentionally NOT player scale, that doesn't work. PROJSPEED = FixedMul(PROJSPEED, mapobjectscale); if (altthrow) @@ -3708,7 +3714,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map if (mo) { angle_t fa = player->mo->angle>>ANGLETOFINESHIFT; - fixed_t HEIGHT = (20 + (dir*10))*FRACUNIT + (player->mo->momz*P_MobjFlip(player->mo)); + fixed_t HEIGHT = ((20 + (dir*10)) * FRACUNIT) + (player->mo->momz*P_MobjFlip(player->mo)); // Also intentionally not player scale P_SetObjectMomZ(mo, HEIGHT, false); mo->momx = player->mo->momx + FixedMul(FINECOSINE(fa), PROJSPEED*dir); @@ -3813,41 +3819,48 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map return mo; } -void K_PuntMine(mobj_t *thismine, mobj_t *punter) +void K_PuntMine(mobj_t *origMine, mobj_t *punter) { - angle_t fa = K_MomentumAngle(punter) >> ANGLETOFINESHIFT; - fixed_t z = 30*mapobjectscale + punter->momz; + angle_t fa = K_MomentumAngle(punter); + fixed_t z = (punter->momz * P_MobjFlip(punter)) + (30 * FRACUNIT); fixed_t spd; mobj_t *mine; - if (!thismine || P_MobjWasRemoved(thismine)) + if (!origMine || P_MobjWasRemoved(origMine)) return; - //This guarantees you hit a mine being dragged - if (thismine->type == MT_SSMINE_SHIELD) // Create a new mine, and clean up the old one + if (punter->hitlag > 0) + return; + + // This guarantees you hit a mine being dragged + if (origMine->type == MT_SSMINE_SHIELD) // Create a new mine, and clean up the old one { - mine = P_SpawnMobj(thismine->x, thismine->y, thismine->z, MT_SSMINE); - P_SetTarget(&mine->target, thismine->target); - mine->angle = thismine->angle; - mine->flags2 = thismine->flags2; - mine->floorz = thismine->floorz; - mine->ceilingz = thismine->ceilingz; + mobj_t *mineOwner = origMine->target; - //Since we aren't using P_KillMobj, we need to clean up the hnext reference + mine = P_SpawnMobj(origMine->x, origMine->y, origMine->z, MT_SSMINE); + + P_SetTarget(&mine->target, mineOwner); + mine->angle = origMine->angle; + mine->flags2 = origMine->flags2; + mine->floorz = origMine->floorz; + mine->ceilingz = origMine->ceilingz; + + // Since we aren't using P_KillMobj, we need to clean up the hnext reference + P_SetTarget(&mineOwner->hnext, NULL); + mineOwner->player->kartstuff[k_bananadrag] = 0; + mineOwner->player->kartstuff[k_itemheld] = 0; + + if (--mineOwner->player->kartstuff[k_itemamount] <= 0) { - P_SetTarget(&thismine->target->hnext, NULL); //target is the player who owns the mine - thismine->target->player->kartstuff[k_bananadrag] = 0; - thismine->target->player->kartstuff[k_itemheld] = 0; - - if (--thismine->target->player->kartstuff[k_itemamount] <= 0) - thismine->target->player->kartstuff[k_itemtype] = KITEM_NONE; + mineOwner->player->kartstuff[k_itemtype] = KITEM_NONE; } - P_RemoveMobj(thismine); - + P_RemoveMobj(origMine); } else - mine = thismine; + { + mine = origMine; + } if (!mine || P_MobjWasRemoved(mine)) return; @@ -3855,20 +3868,19 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter) if (mine->threshold > 0 || mine->hitlag > 0) return; - spd = (82 + ((gamespeed-1) * 14))*mapobjectscale; // Avg Speed is 41 in Normal + spd = FixedMul(82 * punter->scale, K_GetKartGameSpeedScalar(gamespeed)); // Avg Speed is 41 in Normal mine->flags |= MF_NOCLIPTHING; P_SetMobjState(mine, S_SSMINE_AIR1); mine->threshold = 10; - mine->extravalue1 = 0; mine->reactiontime = mine->info->reactiontime; - K_SetHitLagForObjects(punter, mine, 5); + mine->momx = punter->momx + FixedMul(FINECOSINE(fa >> ANGLETOFINESHIFT), spd); + mine->momy = punter->momy + FixedMul(FINESINE(fa >> ANGLETOFINESHIFT), spd); + P_SetObjectMomZ(mine, z, false); - mine->momx = punter->momx + FixedMul(FINECOSINE(fa), spd); - mine->momy = punter->momy + FixedMul(FINESINE(fa), spd); - mine->momz = P_MobjFlip(mine) * z; + //K_SetHitLagForObjects(punter, mine, 5); mine->flags &= ~MF_NOCLIPTHING; } diff --git a/src/p_enemy.c b/src/p_enemy.c index 0cb5b7a84..01f8f6bb7 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4457,9 +4457,6 @@ void A_GrenadeRing(mobj_t *actor) if (actor->flags2 & MF2_DEBRIS) return; - if (actor->hitlag > 0) - return; - if (actor->state == &states[S_SSMINE_DEPLOY8]) explodedist = (3*explodedist)/2; @@ -4484,7 +4481,7 @@ static inline boolean PIT_MineExplode(mobj_t *thing) if (!grenade || P_MobjWasRemoved(grenade)) return false; // There's the possibility these can chain react onto themselves after they've already died if there are enough all in one spot - if (grenade->flags2 & MF2_DEBRIS) // don't explode twice + if (grenade->flags2 & MF2_DEBRIS) // don't explode twice return false; if (thing == grenade || thing->type == MT_MINEEXPLOSIONSOUND) // Don't explode yourself! Endless loop! @@ -4527,9 +4524,6 @@ void A_SSMineExplode(mobj_t *actor) if (actor->flags2 & MF2_DEBRIS) return; - if (actor->hitlag > 0) - return; - type = (mobjtype_t)locvar1; // Use blockmap to check for nearby shootables diff --git a/src/p_inter.c b/src/p_inter.c index 4a798d4d0..50ad02188 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1854,8 +1854,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (!(target->flags & MF_SHOOTABLE)) return false; // shouldn't happen... - // Make sure that boxes cannot be popped by enemies, red rings, etc. - if (target->flags & MF_MONITOR && ((!source || !source->player) || (inflictor && !inflictor->player))) + if (target->hitlag > 0) return false; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 30e968466..098a49145 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6497,7 +6497,8 @@ static boolean P_MobjRegularThink(mobj_t *mobj) ghost->colorized = true; // already has color! } - if (P_IsObjectOnGround(mobj) && (mobj->state == &states[S_SSMINE_AIR1] || mobj->state == &states[S_SSMINE_AIR2])) + if (P_IsObjectOnGround(mobj) && (mobj->momz * P_MobjFlip(mobj)) <= 0 + && (mobj->state == &states[S_SSMINE_AIR1] || mobj->state == &states[S_SSMINE_AIR2])) { if (mobj->extravalue1 > 0) mobj->extravalue1--; @@ -8578,12 +8579,6 @@ void P_MobjThinker(mobj_t *mobj) I_Assert(mobj != NULL); I_Assert(!P_MobjWasRemoved(mobj)); - if (mobj->flags & MF_NOTHINK) - return; - - if ((mobj->flags & MF_BOSS) && mobj->spawnpoint && (bossdisabled & (1<spawnpoint->extrainfo))) - return; - // Remove dead target/tracer. if (mobj->target && P_MobjWasRemoved(mobj->target)) P_SetTarget(&mobj->target, NULL); @@ -8594,6 +8589,12 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->hprev && P_MobjWasRemoved(mobj->hprev)) P_SetTarget(&mobj->hprev, NULL); + if (mobj->flags & MF_NOTHINK) + return; + + if ((mobj->flags & MF_BOSS) && mobj->spawnpoint && (bossdisabled & (1<spawnpoint->extrainfo))) + return; + // Don't run any thinker code while in hitlag if (mobj->hitlag > 0) {