diff --git a/src/deh_tables.c b/src/deh_tables.c index 3c4e7fe1e..8b25029b6 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3755,6 +3755,11 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi // Caked-Up Booty-Sheet Ghost "S_HYUDORO", + // Shrink + "S_SHRINK_GUN", + "S_SHRINK_LASER", + "S_SHRINK_PARTICLE", + // The legend "S_SINK", "S_SINK_SHIELD", @@ -5338,7 +5343,10 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_HYUDORO_CENTER", "MT_SHRINK_POHBEE", + "MT_SHRINK_GUN", + "MT_SHRINK_CHAIN", "MT_SHRINK_LASER", + "MT_SHRINK_PARTICLE", "MT_SINK", // Kitchen Sink Stuff "MT_SINK_SHIELD", diff --git a/src/info.c b/src/info.c index f067ee1f1..c2bd3c964 100644 --- a/src/info.c +++ b/src/info.c @@ -573,6 +573,7 @@ char sprnames[NUMSPRITES + 1][5] = "FLML", // Flame Shield speed lines "FLMF", // Flame Shield flash "HYUU", // Hyudoro + "SHRG", // Shrink gun / laser "SINK", // Kitchen Sink "SITR", // Kitchen Sink Trail "KBLN", // Battle Mode Bumper @@ -4314,6 +4315,10 @@ state_t states[NUMSTATES] = {SPR_HYUU, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_HYUDORO + {SPR_SHRG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SHRINK_GUN + {SPR_SHRG, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_SHRINK_LASER + {SPR_SHRG, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_SHRINK_PARTICLE + {SPR_SINK, 0, 1, {A_SmokeTrailer}, MT_SINKTRAIL, 0, S_SINK}, // S_SINK {SPR_SINK, 0|FF_TRANS80|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_SINK_SHIELD}, // S_SINK_SHIELD {SPR_SITR, 0, 1, {NULL}, 0, 0, S_SINKTRAIL2}, // S_SINKTRAIL1 @@ -24063,9 +24068,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_SHRINK_LASER + { // MT_SHRINK_GUN -1, // doomednum - S_HYUDORO, // spawnstate + S_SHRINK_GUN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -24080,13 +24085,94 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 32*FRACUNIT, // radius - 24*FRACUNIT, // height + 48*FRACUNIT, // radius + 120*FRACUNIT, // height 0, // display offset 0, // mass 0, // damage sfx_None, // activesound - MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags + MF_SCENERY|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_SHRINK_CHAIN + -1, // doomednum + S_SHRINK_GUN, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // 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 + 120*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_SHRINK_LASER + -1, // doomednum + S_SHRINK_LASER, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // 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 + 33*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_SCENERY|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_SHRINK_PARTICLE + -1, // doomednum + S_SHRINK_PARTICLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // 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 + 16*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_SCENERY|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, diff --git a/src/info.h b/src/info.h index 74771110e..0ff8f7f93 100644 --- a/src/info.h +++ b/src/info.h @@ -1119,6 +1119,7 @@ typedef enum sprite SPR_FLML, // Flame Shield speed lines SPR_FLMF, // Flame Shield flash SPR_HYUU, // Hyudoro + SPR_SHRG, // Shrink gun / laser SPR_SINK, // Kitchen Sink SPR_SITR, // Kitchen Sink Trail SPR_KBLN, // Battle Mode Bumper @@ -4745,6 +4746,11 @@ typedef enum state // Caked-Up Booty-Sheet Ghost S_HYUDORO, + // Shrink + S_SHRINK_GUN, + S_SHRINK_LASER, + S_SHRINK_PARTICLE, + // The legend S_SINK, S_SINK_SHIELD, @@ -6364,7 +6370,10 @@ typedef enum mobj_type MT_HYUDORO_CENTER, MT_SHRINK_POHBEE, + MT_SHRINK_GUN, + MT_SHRINK_CHAIN, MT_SHRINK_LASER, + MT_SHRINK_PARTICLE, MT_SINK, // Kitchen Sink Stuff MT_SINK_SHIELD, diff --git a/src/k_kart.c b/src/k_kart.c index b36009f68..f96f50182 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3643,7 +3643,7 @@ void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 typ P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); } -static void K_RemoveGrowShrink(player_t *player) +void K_RemoveGrowShrink(player_t *player) { if (player->mo && !P_MobjWasRemoved(player->mo)) { diff --git a/src/k_kart.h b/src/k_kart.h index bab501200..4529b2611 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -71,6 +71,7 @@ void K_AwardPlayerRings(player_t *player, INT32 rings, boolean overload); void K_DoInstashield(player_t *player); void K_DoPowerClash(player_t *t1, player_t *t2); void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved); +void K_RemoveGrowShrink(player_t *player); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_TumbleInterrupt(player_t *player); diff --git a/src/k_objects.h b/src/k_objects.h index d0b6f6b8b..45a487c5a 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -10,6 +10,7 @@ void Obj_HyudoroCollide(mobj_t *special, mobj_t *toucher); /* Shrink */ void Obj_PohbeeThinker(mobj_t *pohbee); +boolean Obj_ShrinkLaserCollide(mobj_t *gun, mobj_t *victim); void Obj_CreateShrinkPohbees(player_t *owner); #endif/*k_objects_H*/ diff --git a/src/objects/shrink.c b/src/objects/shrink.c index bde2fdb35..2ea94245f 100644 --- a/src/objects/shrink.c +++ b/src/objects/shrink.c @@ -23,13 +23,13 @@ #include "../z_zone.h" #include "../k_waypoint.h" -#define POHBEE_HOVER (384 << FRACBITS) +#define POHBEE_HOVER (256 << FRACBITS) #define POHBEE_SPEED (128 << FRACBITS) #define POHBEE_TIME (15 * TICRATE) #define POHBEE_DIST (4096 << FRACBITS) -#define LASER_SPEED (20 << FRACBITS) -#define LASER_SWINGTIME (3 * TICRATE) +#define GUN_SWING (ANGLE_90 - ANG10) +#define GUN_SWINGTIME (3 * TICRATE) #define CHAIN_SIZE (16) @@ -44,17 +44,61 @@ enum #define pohbee_timer(o) ((o)->reactiontime) #define pohbee_waypoint_cur(o) ((o)->extravalue1) #define pohbee_waypoint_dest(o) ((o)->extravalue2) +#define pohbee_height(o) ((o)->movefactor) #define pohbee_owner(o) ((o)->target) -#define pohbee_lasers(o) ((o)->hnext) +#define pohbee_guns(o) ((o)->hnext) -#define laser_offset(o) ((o)->movecount) -#define laser_swing(o) ((o)->movedir) -#define laser_numsegs(o) ((o)->extravalue1) +#define gun_offset(o) ((o)->movecount) +#define gun_numsegs(o) ((o)->extravalue1) -#define laser_pohbee(o) ((o)->target) -#define laser_collider(o) ((o)->tracer) -#define laser_chains(o) ((o)->hprev) +#define gun_pohbee(o) ((o)->target) +#define gun_laser(o) ((o)->tracer) +#define gun_chains(o) ((o)->hprev) + +enum +{ + LASER_SHRINK, + LASER_GROW, +}; + +static skincolornum_t ShrinkLaserColor(mobj_t *pohbee) +{ + UINT8 laserState = LASER_SHRINK; + player_t *owner = NULL; + + if (pohbee_owner(pohbee) != NULL && P_MobjWasRemoved(pohbee_owner(pohbee)) == false) + { + owner = pohbee_owner(pohbee)->player; + } + + if (owner != NULL && P_IsDisplayPlayer(owner) == true) + { + laserState = LASER_GROW; + + if (r_splitscreen > 0 && (leveltime & 1)) + { + // TODO: make this properly screen dependent, + // instead of flashing. + laserState = LASER_SHRINK; + } + } + + switch (laserState) + { + default: + case LASER_SHRINK: + return SKINCOLOR_KETCHUP; + + case LASER_GROW: + return SKINCOLOR_SAPPHIRE; + } +} + +static boolean ShrinkLaserActive(mobj_t *pohbee) +{ + return (pohbee_mode(pohbee) == POHBEE_MODE_ACT); +} static void PohbeeMoveTo(mobj_t *pohbee, fixed_t destx, fixed_t desty, fixed_t destz) { @@ -70,9 +114,9 @@ static fixed_t GenericDistance( return P_AproxDistance(P_AproxDistance(destx - curx, desty - cury), destz - curz); } -static fixed_t PohbeeWaypointZ(mobj_t *dest) +static fixed_t PohbeeWaypointZ(mobj_t *pohbee, mobj_t *dest) { - return dest->z + (FixedMul(POHBEE_HOVER, mapobjectscale) * P_MobjFlip(dest)); + return dest->z + (pohbee_height(pohbee) + FixedMul(POHBEE_HOVER, mapobjectscale) * P_MobjFlip(dest)); } static void PohbeeSpawn(mobj_t *pohbee) @@ -110,7 +154,7 @@ static void PohbeeSpawn(mobj_t *pohbee) { fixed_t wpX = curWaypoint->mobj->x; fixed_t wpY = curWaypoint->mobj->y; - fixed_t wpZ = PohbeeWaypointZ(curWaypoint->mobj); + fixed_t wpZ = PohbeeWaypointZ(pohbee, curWaypoint->mobj); fixed_t distToNext = GenericDistance( newX, newY, newZ, @@ -210,17 +254,16 @@ static void PohbeeDespawn(mobj_t *pohbee) pohbee->momz = 16 * pohbee->scale * P_MobjFlip(pohbee); } -static void DoLaserSwing(mobj_t *laser, mobj_t *pohbee) +static void DoGunSwing(mobj_t *gun, mobj_t *pohbee) { - const angle_t angle = laser->angle + ANGLE_90; - const tic_t swingTimer = leveltime + laser_offset(laser); + const angle_t angle = gun->angle + ANGLE_90; + const tic_t swingTimer = leveltime + gun_offset(gun); - const angle_t swingAmt = swingTimer * (ANGLE_MAX / LASER_SWINGTIME); + const angle_t swingAmt = swingTimer * (ANGLE_MAX / GUN_SWINGTIME); const fixed_t swingCos = FINECOSINE(swingAmt >> ANGLETOFINESHIFT); - const fixed_t swing = FixedMul(laser_swing(laser), 9 * swingCos); - const angle_t pitch = -ANGLE_90 + swing; - const fixed_t dist = laser_numsegs(laser) * CHAIN_SIZE * laser->scale; + const angle_t pitch = -ANGLE_90 + FixedMul(swingCos, GUN_SWING); + const fixed_t dist = gun_numsegs(gun) * CHAIN_SIZE * gun->scale; fixed_t offsetX = FixedMul( dist, FixedMul( @@ -240,28 +283,76 @@ static void DoLaserSwing(mobj_t *laser, mobj_t *pohbee) dist, FINESINE(pitch >> ANGLETOFINESHIFT) ); - PohbeeMoveTo(laser, pohbee->x + offsetX, pohbee->y + offsetY, pohbee->z + offsetZ); + PohbeeMoveTo(gun, pohbee->x + offsetX, pohbee->y + offsetY, pohbee->z + offsetZ); } -static void ShrinkLaserThinker(mobj_t *laser) +static void ShrinkLaserThinker(mobj_t *pohbee, mobj_t *gun, mobj_t *laser) { - mobj_t *pohbee = laser_pohbee(laser); + PohbeeMoveTo(laser, gun->x, gun->y, gun->floorz); + + if (ShrinkLaserActive(pohbee) == true) + { + mobj_t *particle = NULL; + + laser->renderflags &= ~RF_DONTDRAW; + laser->color = gun->color; + + if (leveltime & 1) + { + laser->spritexscale = 3*FRACUNIT/2; + } + else + { + laser->spritexscale = FRACUNIT; + } + + laser->spriteyscale = FixedDiv(FixedDiv(gun->z - gun->floorz, mapobjectscale), laser->info->height); + + particle = P_SpawnMobjFromMobj( + laser, + P_RandomRange(-16, 16) * FRACUNIT, + P_RandomRange(-16, 16) * FRACUNIT, + 0, + MT_SHRINK_PARTICLE + ); + + particle->color = laser->color; + + P_SetScale(particle, particle->scale * 2); + particle->destscale = 0; + + particle->momz = 2 * particle->scale * P_MobjFlip(particle); + } + else + { + laser->renderflags |= RF_DONTDRAW; + } +} + +static void ShrinkGunThinker(mobj_t *gun) +{ + mobj_t *pohbee = gun_pohbee(gun); if (pohbee == NULL || P_MobjWasRemoved(pohbee) == true) { - P_RemoveMobj(laser); + P_RemoveMobj(gun); return; } - laser->angle = pohbee->angle; - DoLaserSwing(laser, pohbee); + gun->angle = pohbee->angle; + gun->color = ShrinkLaserColor(pohbee); - //PohbeeMoveTo(laser_collider(laser), laser->x, laser->y, laser->z); + DoGunSwing(gun, pohbee); + + if (gun_laser(gun) != NULL && P_MobjWasRemoved(gun_laser(gun)) == false) + { + ShrinkLaserThinker(pohbee, gun, gun_laser(gun)); + } } void Obj_PohbeeThinker(mobj_t *pohbee) { - mobj_t *laser = NULL; + mobj_t *gun = NULL; pohbee->momx = pohbee->momy = pohbee->momz = 0; @@ -285,11 +376,11 @@ void Obj_PohbeeThinker(mobj_t *pohbee) break; } - laser = pohbee_lasers(pohbee); - while (laser != NULL && P_MobjWasRemoved(laser) == false) + gun = pohbee_guns(pohbee); + while (gun != NULL && P_MobjWasRemoved(gun) == false) { - ShrinkLaserThinker(laser); - laser = pohbee_lasers(laser); + ShrinkGunThinker(gun); + gun = pohbee_guns(gun); } } @@ -298,7 +389,7 @@ void Obj_PohbeeRemoved(mobj_t *pohbee) { mobj_t *chain = NULL; - if (pohbee_laser(pohbee) != NULL) + if (pohbee_guns(pohbee) != NULL) { P_RemoveMobj(pohbee_laser(pohbee)); } @@ -313,6 +404,84 @@ void Obj_PohbeeRemoved(mobj_t *pohbee) } */ +boolean Obj_ShrinkLaserCollide(mobj_t *gun, mobj_t *victim) +{ + mobj_t *pohbee = gun_pohbee(gun); + mobj_t *owner = NULL; + + if (pohbee == NULL || P_MobjWasRemoved(pohbee) == true) + { + return true; + } + + if (ShrinkLaserActive(pohbee) == false) + { + return true; + } + + owner = pohbee_owner(pohbee); + + if (owner != NULL && victim == owner) + { + // Belongs to us. Give us Grow! + if (victim->player->growshrinktimer <= 0) + { + victim->scalespeed = mapobjectscale/TICRATE; + victim->destscale = FixedMul(mapobjectscale, GROW_SCALE); + + if (K_PlayerShrinkCheat(victim->player) == true) + { + victim->destscale = FixedMul(victim->destscale, SHRINK_SCALE); + } + + // TODO: gametyperules + victim->player->growshrinktimer = (gametype == GT_BATTLE ? 8 : 12) * TICRATE; + + if (victim->player->invincibilitytimer > 0) + { + ; // invincibility has priority in P_RestoreMusic, no point in starting here + } + else if (P_IsLocalPlayer(victim->player) == true) + { + S_ChangeMusicSpecial("kgrow"); + } + else //used to be "if (P_IsDisplayPlayer(victim->player) == false)" + { + S_StartSound(victim, (cv_kartinvinsfx.value ? sfx_alarmg : sfx_kgrow)); + } + + P_RestoreMusic(victim->player); + S_StartSound(victim, sfx_kc5a); + } + } + else + { + if (victim->player->growshrinktimer > 0) + { + // Take away Grow. + K_RemoveGrowShrink(victim->player); + } + else + { + // Start shrinking! + K_DropItems(victim->player); + victim->player->growshrinktimer = -(15*TICRATE); + + victim->scalespeed = mapobjectscale/TICRATE; + victim->destscale = FixedMul(mapobjectscale, SHRINK_SCALE); + + if (K_PlayerShrinkCheat(victim->player) == true) + { + victim->destscale = FixedMul(victim->destscale, SHRINK_SCALE); + } + + S_StartSound(victim, sfx_kc59); + } + } + + return true; +} + static waypoint_t *GetPohbeeStart(waypoint_t *anchor) { const UINT32 traveldist = FixedMul(POHBEE_DIST >> 1, mapobjectscale) / FRACUNIT; @@ -373,10 +542,10 @@ static void CreatePohbee(player_t *owner, waypoint_t *start, waypoint_t *end, UI { mobj_t *pohbee = NULL; - fixed_t size = INT32_MAX; + fixed_t size = 0; INT32 baseSegs = INT32_MAX; INT32 segVal = INT32_MAX; - mobj_t *prevLaser = NULL; + mobj_t *prevGun = NULL; size_t i, j; @@ -389,8 +558,8 @@ static void CreatePohbee(player_t *owner, waypoint_t *start, waypoint_t *end, UI } // Calculate number of chain segments added per laser. - size = end->mobj->radius / mapobjectscale; - baseSegs = 1 + (size / CHAIN_SIZE); + size = FixedMul(end->mobj->radius, 3*FRACUNIT/2); + baseSegs = 1 + ((size / start->mobj->scale) / CHAIN_SIZE); if (baseSegs < MAXPLAYERS) { @@ -406,39 +575,42 @@ static void CreatePohbee(player_t *owner, waypoint_t *start, waypoint_t *end, UI pohbee_mode(pohbee) = POHBEE_MODE_SPAWN; pohbee_timer(pohbee) = POHBEE_TIME; + pohbee_height(pohbee) = size; pohbee_waypoint_cur(pohbee) = (INT32)K_GetWaypointHeapIndex(start); pohbee_waypoint_dest(pohbee) = (INT32)K_GetWaypointHeapIndex(end); - prevLaser = pohbee; + prevGun = pohbee; for (i = 0; i < numLasers; i++) { const UINT8 numSegs = segVal * (i + 1); - mobj_t *laser = P_SpawnMobjFromMobj(pohbee, 0, 0, 0, MT_SHRINK_LASER); - //mobj_t *collider = NULL; + mobj_t *gun = P_SpawnMobjFromMobj(pohbee, 0, 0, 0, MT_SHRINK_GUN); + mobj_t *laser = NULL; //mobj_t *prevChain = NULL; - P_SetTarget(&laser_pohbee(laser), pohbee); - P_SetTarget(&pohbee_lasers(prevLaser), laser); + P_SetTarget(&gun_pohbee(gun), pohbee); + P_SetTarget(&pohbee_guns(prevGun), gun); - laser_numsegs(laser) = numSegs; - laser_swing(laser) = (ANGLE_45 * baseSeg) / numSegs; - laser_offset(laser) = P_RandomKey(LASER_SWINGTIME); + gun_numsegs(gun) = numSegs; + gun_offset(gun) = P_RandomKey(GUN_SWINGTIME); + + laser = P_SpawnMobjFromMobj(gun, 0, 0, 0, MT_SHRINK_LASER); + P_SetTarget(&gun_laser(gun), laser); /* - prevChain = laser; + prevChain = gun; for (j = 0; j < numSegs; j++) { - mobj_t *chain = P_SpawnMobjFromMobj(laser, 0, 0, 0, MT_SHRINK_LASER); - P_SetTarget(&laser_chains(prevChain), chain); + mobj_t *chain = P_SpawnMobjFromMobj(gun, 0, 0, 0, MT_SHRINK_CHAIN); + P_SetTarget(&gun_chains(prevChain), chain); prevChain = chain; } */ (void)j; - prevLaser = laser; + prevGun = gun; } } @@ -511,7 +683,7 @@ void Obj_CreateShrinkPohbees(player_t *owner) // Push a new poh-bee pohbees[j].start = GetPohbeeStart(player->nextwaypoint); pohbees[j].end = endWaypoint; - pohbees[j].lasers = 4; + pohbees[j].lasers = 1; numPohbees++; } } diff --git a/src/p_map.c b/src/p_map.c index ad970ee45..5c9b98ef2 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -32,6 +32,7 @@ #include "hu_stuff.h" // SRB2kart #include "i_system.h" // SRB2kart #include "k_terrain.h" +#include "k_objects.h" #include "r_splats.h" @@ -739,6 +740,51 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) // SRB2kart 011617 - Colission[sic] code for kart items //{ + if (thing->type == MT_SHRINK_GUN) + { + if (tmthing->type != MT_PLAYER) + { + return BMIT_CONTINUE; + } + + // Use special collision for the laser gun. + // The laser sprite itself is just a visual, + // the gun itself does the colliding for us. + if (tmthing->z > thing->z) + { + return BMIT_CONTINUE; // overhead + } + + if (tmthing->z + tmthing->height < thing->floorz) + { + return BMIT_CONTINUE; // underneath + } + + return Obj_ShrinkLaserCollide(thing, tmthing) ? BMIT_CONTINUE : BMIT_ABORT; + } + else if (tmthing->type == MT_SHRINK_GUN) + { + if (thing->type != MT_PLAYER) + { + return BMIT_CONTINUE; + } + + // Use special collision for the laser gun. + // The laser sprite itself is just a visual, + // the gun itself does the colliding for us. + if (thing->z > tmthing->z) + { + return BMIT_CONTINUE; // overhead + } + + if (thing->z + thing->height < tmthing->floorz) + { + return BMIT_CONTINUE; // underneath + } + + return Obj_ShrinkLaserCollide(tmthing, thing) ? BMIT_CONTINUE : BMIT_ABORT; + } + if (tmthing->type == MT_SMK_ICEBLOCK) { // see if it went over / under