diff --git a/src/d_main.cpp b/src/d_main.cpp index 38ee1ab10..94e7a33d0 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -94,7 +94,7 @@ #define ASSET_HASH_TEXTURES_KART 0xb4211b2f32b6a291 #define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b #define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9 -#define ASSET_HASH_MAIN_PK3 0xb1730fd0965adcb1 +#define ASSET_HASH_MAIN_PK3 0x92477cf651c45063 #define ASSET_HASH_MAPPATCH_PK3 0x0afd8afc6fc50175 #define ASSET_HASH_BONUSCHARS_KART 0x60e6f13d822a7461 #ifdef USE_PATCH_FILE diff --git a/src/info/actions.h b/src/info/actions.h index 1c2f6fd0b..f32aa3438 100644 --- a/src/info/actions.h +++ b/src/info/actions.h @@ -223,3 +223,4 @@ _(A_MayonakaArrow, MAYONAKAARROW) _(A_MementosTPParticles, MEMENTOSTPPARTICLES) _(A_ReaperThinker, REAPERTHINKER) _(A_SpawnSneakerPanel, SPAWNSNEAKERPANEL) +_(A_KartGibs, KARTGIBS) diff --git a/src/p_enemy.c b/src/p_enemy.c index 4f7c75202..4c37a2d1f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -11987,3 +11987,27 @@ void A_SpawnSneakerPanel(void *thing) mo->angle = actor->angle; Obj_SneakerPanelSpriteScale(mo); } + +// spews the kart's gib particles +void A_KartGibs(void *thing) +{ + mobj_t *actor = thing; + angle_t tireangle = actor->angle + ANGLE_90 - ANGLE_22h; + INT32 i; + + if (LUA_CallAction(A_KARTGIBS, actor)) + return; + + for (i = 0; i < 4; i++, tireangle += ANGLE_45) + { + if (i == 2) tireangle += ANGLE_90; + + mobj_t *tire = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_KART_TIRE); + tire->fuse = 3*TICRATE; + tire->angle = tireangle; + if (i == 0 || i == 3) + P_SetScale(tire, (tire->destscale = 3*tire->scale/4)); + P_InstaThrust(tire, tireangle, 3 * tire->scale); + P_SetObjectMomZ(tire, 9*FRACUNIT + 3*P_RandomFixed(), false); + } +} diff --git a/src/p_inter.c b/src/p_inter.c index bddd11064..c0ee3c23c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1629,21 +1629,20 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (target->player == NULL || skins[target->player->skin].flags & SF_OLDDEATH) break; - angle_t flingangle; - if (!P_MobjWasRemoved(source)) - flingangle = R_PointToAngle2( - source->x - source->momx, source->y - source->momy, - target->x, target->y - ); - else + angle_t flingangle = target->angle + ANGLE_180; + fixed_t angleoffset = P_RandomRange(20, 40)*FRACUNIT; + if (angleoffset < 30*FRACUNIT) + angleoffset -= 60*FRACUNIT; + + if (target->player->pflags & PF_NOCONTEST) { - // -45..-30 or 30..45 - fixed_t offset = P_RandomRange(15, 45)*FRACUNIT; - if (offset < 30*FRACUNIT) - offset -= 60*FRACUNIT; - flingangle = target->angle + ANGLE_180 + FixedAngle(offset); + target->flags &= ~MF_NOCLIPHEIGHT; // do the bounce! + target->friction = 4*FRACUNIT/5; // reduce momentum if we die on the ground + angleoffset /= 2; } + flingangle += FixedAngle(angleoffset); + // Spawn kart frame mobj_t *kart = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_KART_LEFTOVER); @@ -1668,28 +1667,21 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget P_KillMobj(kart, inflictor, source, damagetype); } else - P_SetMobjState(kart, S_KART_LEFTOVER_NOTIRES); - - // Spawn tires (this makes no sense being here...) - angle_t tireangle = flingangle - ANGLE_90 - ANGLE_22h; - for (INT32 i = 0; i < 4; i++, tireangle += ANGLE_45) - { - if (i == 2) tireangle += ANGLE_90; - - mobj_t *tire = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_KART_TIRE); - tire->fuse = 2*TICRATE; - tire->angle = tireangle; - if (i == 0 || i == 3) - P_SetScale(tire, (tire->destscale = 3*tire->scale/4)); - P_InstaThrust(tire, tireangle, 3 * tire->scale); - P_SetObjectMomZ(tire, 10*FRACUNIT, false); - } + P_SetMobjState(kart, kart->info->deathstate); } P_InstaThrust(target, flingangle, 4 * target->scale); + target->player->rmomx = target->momx; // fix friction + target->player->rmomy = target->momy; break; case MT_KART_LEFTOVER: + if (!P_MobjWasRemoved(inflictor)) + target->angle = R_PointToAngle2( + target->x, target->y, + inflictor->x - inflictor->momx, inflictor->y - inflictor->momy + ); + target->fuse = 2*TICRATE; target->flags &= ~(MF_SOLID|MF_SHOOTABLE); P_UnsetThingPosition(target); diff --git a/src/p_map.c b/src/p_map.c index 2caaf1c07..9611424b5 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2934,9 +2934,16 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y, TryMoveResult_t *r else tryy = y; + // yeah yeah, performance, but the result needs a line now!!! + if (result != NULL) + g_tm.sweep = true; + if (!P_CheckPosition(thing, tryx, tryy, result)) return false; // solid wall or thing + if (result != NULL) + result->line = P_SweepTestLines(thing->x, thing->y, tryx, tryy, thing->radius, &result->normal); + if (!(thing->flags & MF_NOCLIP)) { const fixed_t maxstep = P_BaseStepUp(); diff --git a/src/p_mobj.c b/src/p_mobj.c index 86ed4a66b..9cc9bcf61 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1960,7 +1960,7 @@ void P_SceneryXYMovement(mobj_t *mo) oldy = mo->y; if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy, &result)) - P_BounceMove(mo, &result); + (mo->flags & MF_BOUNCE ? P_BounceMove : P_SlideMove)(mo, &result); if (P_MobjWasRemoved(mo)) return; @@ -2422,6 +2422,11 @@ boolean P_ZMovement(mobj_t *mo) mom.z = P_MobjFlip(mo)*FixedMul(5*FRACUNIT, mo->scale); else if (mo->type == MT_SPINFIRE) // elemental shield fire is another exception here ; + else if (mo->type == MT_PLAYER) // only DEAD players + { + mom.z = -4*mom.z/5; + mo->flags |= MF_NOCLIPHEIGHT; // fall through floor next time + } else if (mo->flags & MF_MISSILE) { if (!(mo->flags & MF_NOCLIP)) @@ -2992,7 +2997,12 @@ boolean P_SceneryZMovement(mobj_t *mo) { mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack - if (g_tm.floorthing) + if (mo->type == MT_KART_TIRE) + { + mo->momz = -mo->momz; + mo->flags |= MF_NOCLIPHEIGHT; + } + else if (g_tm.floorthing) mo->momz = g_tm.floorthing->momz; else if (!g_tm.floorthing) mo->momz = 0; @@ -7951,7 +7961,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj) } } // Apply gravity to fall downwards. - else if (skins[mobj->player->skin].flags & SF_OLDDEATH) + else if (mobj->player == NULL || skins[mobj->player->skin].flags & SF_OLDDEATH) { P_SetObjectMomZ(mobj, -3*FRACUNIT/2, true); if (mobj->player != NULL)