diff --git a/src/deh_tables.c b/src/deh_tables.c index 8bd721381..c58a4bb0c 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5268,6 +5268,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_TUBEWAYPOINT", "MT_PUSH", "MT_GHOST", + "MT_FAKESHADOW", "MT_OVERLAY", "MT_ANGLEMAN", "MT_POLYANCHOR", diff --git a/src/info.c b/src/info.c index daaa8104b..b7bddd784 100644 --- a/src/info.c +++ b/src/info.c @@ -21427,6 +21427,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_FAKESHADOW + -1, // doomednum + S_THOK, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 48*FRACUNIT, // height + -1, // display offset + 1000, // mass + 8, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_OVERLAY -1, // doomednum S_NULL, // spawnstate diff --git a/src/info.h b/src/info.h index c2d7a0356..7c770562a 100644 --- a/src/info.h +++ b/src/info.h @@ -6379,6 +6379,7 @@ typedef enum mobj_type MT_TUBEWAYPOINT, MT_PUSH, MT_GHOST, + MT_FAKESHADOW, MT_OVERLAY, MT_ANGLEMAN, MT_POLYANCHOR, diff --git a/src/k_kart.c b/src/k_kart.c index 6c1df9b6d..920274054 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7938,7 +7938,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (leveltime < starttime) { - player->instaShieldCooldown = INSTAWHIP_STARTOFRACE; + player->instaShieldCooldown = (gametyperules & GTR_SPHERES) ? INSTAWHIP_STARTOFBATTLE : INSTAWHIP_STARTOFRACE; } else if (player->rings > 0) { @@ -10699,6 +10699,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_SetScale(whip, player->mo->scale); P_SetTarget(&whip->target, player->mo); K_MatchGenericExtraFlags(whip, player->mo); + P_SpawnFakeShadow(whip, 20); whip->fuse = 12; // Changing instawhip animation duration? Look here player->flashing = max(player->flashing, 12); player->mo->momz += 4*mapobjectscale; diff --git a/src/k_kart.h b/src/k_kart.h index 98e97899d..af7d142d2 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -34,6 +34,7 @@ Make sure this matches the actual number of states #define INSTAWHIP_COOLDOWN (TICRATE*2) #define INSTAWHIP_STARTOFRACE (255) +#define INSTAWHIP_STARTOFBATTLE (1) #define INSTAWHIP_DROPGUARD (12) #define GUARDBREAK_COOLDOWN (TICRATE*4) diff --git a/src/objects/instawhip.c b/src/objects/instawhip.c index 32cd1958e..14eff3318 100644 --- a/src/objects/instawhip.c +++ b/src/objects/instawhip.c @@ -38,22 +38,5 @@ void Obj_InstaWhipThink (mobj_t *whip) if (whip->extravalue2) // Whip has no hitbox but removing it is a pain in the ass whip->renderflags |= RF_DONTDRAW; - - // UGLY! - fixed_t dropOffset = 15*FRACUNIT; - whip->z -= dropOffset; - - mobj_t *dropshadow = P_SpawnGhostMobj(whip); - dropshadow->fuse = 2; - dropshadow->flags2 = MF2_LINKDRAW; - P_SetTarget(&dropshadow->tracer, whip); - dropshadow->renderflags = whip->renderflags; - dropshadow->lightlevel = 0; - dropshadow->extravalue1 = 1; // Suppress fade-out behavior! - dropshadow->renderflags &= ~(RF_TRANSMASK|RF_FULLBRIGHT); - dropshadow->renderflags |= RF_ABSOLUTELIGHTLEVEL; - - // FUCK! - whip->z += dropOffset; } } diff --git a/src/p_local.h b/src/p_local.h index 738faffd3..41615484e 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -186,6 +186,7 @@ void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative); void P_RestoreMusic(player_t *player); void P_EndingMusic(void); mobj_t *P_SpawnGhostMobj(mobj_t *mobj); +mobj_t *P_SpawnFakeShadow(mobj_t *mobj, UINT8 offset); INT32 P_GivePlayerRings(player_t *player, INT32 num_rings); INT32 P_GivePlayerSpheres(player_t *player, INT32 num_spheres); void P_GivePlayerLives(player_t *player, INT32 numlives); diff --git a/src/p_mobj.c b/src/p_mobj.c index 939f90219..6f96b6dbc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9850,11 +9850,6 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->type == MT_GHOST && mobj->fuse > 0) // Not guaranteed to be MF_SCENERY or not MF_SCENERY! { - if (mobj->frame & SPR_IWHP) - { - if (P_MobjWasRemoved(mobj->tracer)) - mobj->renderflags |= RF_DONTDRAW; - } if (mobj->extravalue1 > 0) // Sonic Advance 2 mode { if (mobj->extravalue2 >= 2) @@ -9886,6 +9881,26 @@ void P_MobjThinker(mobj_t *mobj) } } + if (mobj->type == MT_FAKESHADOW) + { + mobj->renderflags &= ~RF_DONTDRAW; + + if (P_MobjWasRemoved(mobj->tracer)) + { + P_RemoveMobj(mobj); + return; + } + + P_MoveOrigin(mobj, mobj->tracer->x, mobj->tracer->y, mobj->tracer->z - mobj->threshold*mapobjectscale); + mobj->angle = mobj->tracer->angle; + + mobj->frame = mobj->tracer->frame; + mobj->frame &= ~FF_FULLBRIGHT; + + if (mobj->tracer->renderflags & RF_DONTDRAW) + mobj->renderflags |= RF_DONTDRAW; + } + // Special thinker for scenery objects if (mobj->flags & MF_SCENERY) { diff --git a/src/p_user.c b/src/p_user.c index a5e9df25a..4793588dc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1253,6 +1253,85 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) return ghost; } +// +// P_SpawnFakeShadow +// +// Spawns a silhouette that copies its tracer and copies RF_DONTDRAW +// +mobj_t *P_SpawnFakeShadow(mobj_t *mobj, UINT8 offset) +{ + mobj_t *ghost = P_SpawnMobj(mobj->x, mobj->y, mobj->z - offset*mapobjectscale, MT_FAKESHADOW); + ghost->threshold = offset; + + P_SetTarget(&ghost->target, mobj); + + P_SetScale(ghost, mobj->scale); + ghost->destscale = mobj->scale; + + if (mobj->eflags & MFE_VERTICALFLIP) + { + ghost->eflags |= MFE_VERTICALFLIP; + ghost->z += mobj->height - ghost->height; + } + + ghost->color = mobj->color; + ghost->colorized = mobj->colorized; // Kart: they should also be colorized if their origin is + + ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle); + ghost->roll = mobj->roll; + ghost->pitch = mobj->pitch; + ghost->sprite = mobj->sprite; + ghost->sprite2 = mobj->sprite2; + ghost->frame = mobj->frame; + ghost->tics = -1; + ghost->renderflags = mobj->renderflags; + ghost->fuse = -1; + ghost->skin = mobj->skin; + ghost->standingslope = mobj->standingslope; + + ghost->sprxoff = mobj->sprxoff; + ghost->spryoff = mobj->spryoff; + ghost->sprzoff = mobj->sprzoff; + ghost->rollangle = mobj->rollangle; + + ghost->spritexscale = mobj->spritexscale; + ghost->spriteyscale = mobj->spriteyscale; + ghost->spritexoffset = mobj->spritexoffset; + ghost->spriteyoffset = mobj->spriteyoffset; + + if (mobj->flags2 & MF2_OBJECTFLIP) + ghost->flags |= MF2_OBJECTFLIP; + + if (!(mobj->flags & MF_DONTENCOREMAP)) + ghost->flags &= ~MF_DONTENCOREMAP; + + if (mobj->player && mobj->player->followmobj) + { + mobj_t *ghost2 = P_SpawnGhostMobj(mobj->player->followmobj); + P_SetTarget(&ghost2->tracer, ghost); + P_SetTarget(&ghost->tracer, ghost2); + ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW); + } + + // Copy interpolation data :) + ghost->old_x = mobj->old_x2; + ghost->old_y = mobj->old_y2; + ghost->old_z = mobj->old_z2; + ghost->old_angle = (mobj->player ? mobj->player->old_drawangle2 : mobj->old_angle2); + ghost->old_pitch = mobj->old_pitch2; + ghost->old_roll = mobj->old_roll2; + + ghost->renderflags &= ~(RF_TRANSMASK|RF_FULLBRIGHT); + ghost->renderflags |= RF_ABSOLUTELIGHTLEVEL; + ghost->lightlevel = 0; + + ghost->flags2 |= MF2_LINKDRAW; + P_SetTarget(&ghost->tracer, mobj); + + return ghost; +} + + // // P_DoPlayerExit //