diff --git a/src/b_bot.c b/src/b_bot.c index 17211b353..651aeb03d 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -140,6 +140,9 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd) void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward, boolean left, boolean right, boolean strafeleft, boolean straferight, boolean jump, boolean spin) { + // don't try to do stuff if your sonic is in a minecart or something + if (players[consoleplayer].powers[pw_carry]) + return; // Turn the virtual keypresses into ticcmd_t. if (twodlevel || mo->flags2 & MF2_TWOD) { if (players[consoleplayer].climbing @@ -218,7 +221,12 @@ boolean B_CheckRespawn(player_t *player) return false; // Low ceiling, do not want! - if (sonic->ceilingz - sonic->z < 2*sonic->height) + if (sonic->eflags & MFE_VERTICALFLIP) + { + if (sonic->z - sonic->floorz < (sonic->player->exiting ? 5 : 2)*sonic->height) + return false; + } + else if (sonic->ceilingz - sonic->z < (sonic->player->exiting ? 6 : 3)*sonic->height) return false; // If you're dead, wait a few seconds to respawn. @@ -252,11 +260,11 @@ void B_RespawnBot(INT32 playernum) y = sonic->y; if (sonic->eflags & MFE_VERTICALFLIP) { tails->eflags |= MFE_VERTICALFLIP; - z = sonic->z - FixedMul(512*FRACUNIT,sonic->scale); + z = sonic->z - (512*sonic->scale); if (z < sonic->floorz) z = sonic->floorz; } else { - z = sonic->z + sonic->height + FixedMul(512*FRACUNIT,sonic->scale); + z = sonic->z + sonic->height + (512*sonic->scale); if (z > sonic->ceilingz - sonic->height) z = sonic->ceilingz - sonic->height; } diff --git a/src/dehacked.c b/src/dehacked.c index ef3e13f4f..15eaa0b0c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5885,7 +5885,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Saloon door "S_SALOONDOOR", - "S_SALOONDOORTHINKER", + "S_SALOONDOORCENTER", // Train cameo "S_TRAINCAMEOSPAWNER_1", @@ -7655,7 +7655,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_MINECARTSIDEMARK", "MT_MINECARTSPARK", "MT_SALOONDOOR", - "MT_SALOONDOORTHINKER", + "MT_SALOONDOORCENTER", "MT_TRAINCAMEOSPAWNER", "MT_TRAINSEG", "MT_TRAINDUSTSPAWNER", diff --git a/src/f_finale.c b/src/f_finale.c index ee22ecb2f..e84d82279 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -637,6 +637,7 @@ static void F_IntroDrawScene(void) } else { + menuanimtimer = animtimer; // Reusing this variable for the intro to fix the scrolling sky, better than changing the function around. F_SkyScroll(80*4, 0, "TITLESKY"); if (timetonext == 6) { diff --git a/src/info.c b/src/info.c index 889402add..fe7ba17a6 100644 --- a/src/info.c +++ b/src/info.c @@ -266,7 +266,6 @@ char sprnames[NUMSPRITES + 1][5] = "ADST", // Arid dust "MCRT", // Minecart "MCSP", // Minecart spark - "NON2", // Saloon door thinker "SALD", // Saloon door "TRAE", // Train cameo locomotive "TRAI", // Train cameo wagon @@ -2486,8 +2485,8 @@ state_t states[NUMSTATES] = {SPR_MCSP, FF_FULLBRIGHT, 1, {A_MinecartSparkThink}, 0, 0, S_MINECARTSPARK}, // S_MINECARTSPARK // Saloon door - {SPR_SALD, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SALOONDOOR - {SPR_NON2, 0, -1, {A_SaloonDoorSpawn}, 0, 0, S_NULL}, // S_SALONDOORTHINKER + {SPR_SALD, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SALOONDOOR + {SPR_NULL, 0, -1, {A_SaloonDoorSpawn}, MT_SALOONDOOR, 48, S_NULL}, // S_SALOONDOORCENTER // Train cameo {SPR_NULL, 0, -1, {NULL}, 0, 0, S_TRAINCAMEOSPAWNER_2}, // S_TRAINCAMEOSPAWNER_1 @@ -4829,7 +4828,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SCENERY|MF_PAIN|MF_NOCLIPHEIGHT|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + MF_SCENERY|MF_PAIN|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_SNAPPER_LEGRAISE // raisestate }, @@ -4856,7 +4855,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_PAIN|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + MF_PAIN|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate }, @@ -12383,7 +12382,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SOLID|MF_SHOOTABLE|MF_ENEMY|MF_PUSHABLE, // flags + MF_SOLID|MF_SHOOTABLE|MF_PUSHABLE, // flags S_NULL // raisestate }, @@ -12711,9 +12710,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_SALOONDOORTHINKER + { // MT_SALOONDOORCENTER 1221, // doomednum - S_SALOONDOORTHINKER, // spawnstate + S_SALOONDOORCENTER, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -12734,7 +12733,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags + MF_SOLID|MF_NOGRAVITY|MF_RUNSPAWNFUNC|MF_PAPERCOLLISION|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, diff --git a/src/info.h b/src/info.h index 6b2de6ac9..1abcc2ee3 100644 --- a/src/info.h +++ b/src/info.h @@ -522,7 +522,6 @@ typedef enum sprite SPR_ADST, // Arid dust SPR_MCRT, // Minecart SPR_MCSP, // Minecart spark - SPR_NON2, // Saloon door thinker SPR_SALD, // Saloon door SPR_TRAE, // Train cameo locomotive SPR_TRAI, // Train cameo wagon @@ -2608,7 +2607,7 @@ typedef enum state // Saloon door S_SALOONDOOR, - S_SALOONDOORTHINKER, + S_SALOONDOORCENTER, // Train cameo S_TRAINCAMEOSPAWNER_1, @@ -4400,7 +4399,7 @@ typedef enum mobj_type MT_MINECARTSIDEMARK, MT_MINECARTSPARK, MT_SALOONDOOR, - MT_SALOONDOORTHINKER, + MT_SALOONDOORCENTER, MT_TRAINCAMEOSPAWNER, MT_TRAINSEG, MT_TRAINDUSTSPAWNER, diff --git a/src/p_enemy.c b/src/p_enemy.c index 81535c345..63b4f693c 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5351,20 +5351,22 @@ static mobj_t *minus; static boolean PIT_MinusCarry(mobj_t *thing) { + if (minus->tracer) + return true; + if (minus->type == thing->type) return true; - if (!(thing->flags & MF_SHOOTABLE) || !(thing->flags & MF_ENEMY)) + if (!(thing->flags & (MF_PUSHABLE|MF_ENEMY))) return true; - if (P_AproxDistance(minus->x - thing->x, minus->y - thing->y) >= minus->radius * 3) + if (P_AproxDistance(minus->x - thing->x, minus->y - thing->y) >= minus->radius*3) return true; if (abs(thing->z - minus->z) > minus->height) return true; P_SetTarget(&minus->tracer, thing); - minus->tracer->flags &= ~MF_PUSHABLE; return true; } @@ -5428,6 +5430,9 @@ void A_MinusDigging(mobj_t *actor) A_Chase(actor); // Carry over shit, maybe + if (P_MobjWasRemoved(actor->tracer) || !actor->tracer->health) + P_SetTarget(&actor->tracer, NULL); + if (!actor->tracer) { fixed_t radius = 3*actor->radius; @@ -5477,7 +5482,6 @@ void A_MinusPopup(mobj_t *actor) else actor->momz = 10*FRACUNIT; - actor->flags |= MF_SPECIAL|MF_SHOOTABLE; S_StartSound(actor, sfx_s3k82); for (i = 1; i <= num; i++) { @@ -5490,6 +5494,7 @@ void A_MinusPopup(mobj_t *actor) if (actor->tracer) P_DamageMobj(actor->tracer, actor, actor, 1, 0); + actor->flags = (actor->flags & ~MF_NOCLIPTHING)|MF_SPECIAL|MF_SHOOTABLE; } // Function: A_MinusCheck @@ -13466,6 +13471,13 @@ void A_TNTExplode(mobj_t *actor) if (LUA_CallAction("A_TNTExplode", actor)) return; #endif + + if (actor->tracer) + { + P_SetTarget(&actor->tracer->tracer, NULL); + P_SetTarget(&actor->tracer, NULL); + } + P_UnsetThingPosition(actor); if (sector_list) { @@ -13679,8 +13691,6 @@ void A_KillSegments(mobj_t *actor) static void P_SnapperLegPlace(mobj_t *mo) { mobj_t *seg = mo->tracer; - fixed_t x0 = mo->x; - fixed_t y0 = mo->y; angle_t a = mo->angle; angle_t fa = (a >> ANGLETOFINESHIFT) & FINEMASK; fixed_t c = FINECOSINE(fa); @@ -13695,7 +13705,8 @@ static void P_SnapperLegPlace(mobj_t *mo) fixed_t rad = mo->radius; INT32 necklen = (32*(mo->info->reactiontime - mo->reactiontime))/mo->info->reactiontime; // Not in FU - P_TeleportMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, mo->z + mo->height/3); + seg->z = mo->z + ((mo->eflags & MFE_VERTICALFLIP) ? (((mo->height<<1)/3) - seg->height) : mo->height/3); + P_TryMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, true); seg->angle = a; // Move as many legs as available. @@ -13715,13 +13726,14 @@ static void P_SnapperLegPlace(mobj_t *mo) { x = c*o2 + s*o1; y = s*o2 - c*o1; - P_TryMove(seg, x0 + x, y0 + y, true); + seg->z = mo->z + (((mo->eflags & MFE_VERTICALFLIP) ? (mo->height - seg->height) : 0)); + P_TryMove(seg, mo->x + x, mo->y + y, true); P_SetMobjState(seg, seg->info->raisestate); } else P_SetMobjState(seg, seg->info->spawnstate); - seg->angle = R_PointToAngle2(x0, y0, seg->x, seg->y); + seg->angle = R_PointToAngle2(mo->x, mo->y, seg->x, seg->y); seg = seg->tracer; } while (seg); @@ -13749,14 +13761,14 @@ void A_SnapperSpawn(mobj_t *actor) #endif // It spawns 1 head. - seg = P_SpawnMobj(actor->x, actor->y, actor->z, headtype); + seg = P_SpawnMobjFromMobj(actor, 0, 0, 0, headtype); P_SetTarget(&ptr->tracer, seg); ptr = seg; // It spawns 4 legs which will be handled in the thinker function. for (i = 1; i <= 4; i++) { - seg = P_SpawnMobj(actor->x, actor->y, actor->z, legtype); + seg = P_SpawnMobjFromMobj(actor, 0, 0, 0, legtype); P_SetTarget(&ptr->tracer, seg); ptr = seg; @@ -13904,51 +13916,43 @@ void A_SnapperThinker(mobj_t *actor) // // Description: Spawns a saloon door. // -// var1 = unused -// var2 = unused +// var1 = mobjtype for sides +// var2 = distance sides should be placed apart // void A_SaloonDoorSpawn(mobj_t *actor) { + INT32 locvar1 = var1; + INT32 locvar2 = var2; angle_t ang = actor->angle; angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK; - fixed_t c = FINECOSINE(fa); - fixed_t s = FINESINE(fa); - INT32 d = 48; - fixed_t x = actor->x; - fixed_t y = actor->y; - fixed_t z = actor->z; + fixed_t c = FINECOSINE(fa)*locvar2; + fixed_t s = FINESINE(fa)*locvar2; mobj_t *door; + mobjflag2_t ambush = (actor->flags & MF2_AMBUSH); #ifdef HAVE_BLUA if (LUA_CallAction("A_SaloonDoorSpawn", actor)) return; #endif - //Front - door = P_SpawnMobj(x + c*d, y + s*d, z, MT_SALOONDOOR); + if (!locvar1) + return; + + // One door... + if (!(door = P_SpawnMobjFromMobj(actor, c, s, 0, locvar1))) return; door->angle = ang + ANGLE_180; + door->extravalue1 = AngleFixed(door->angle); // Origin angle + door->extravalue2 = 0; // Angular speed + P_SetTarget(&door->tracer, actor); // Origin door + door->flags2 |= ambush; // Can be opened by normal players? - // Origin angle - door->extravalue1 = AngleFixed(door->angle); - - // Angular speed - door->extravalue2 = 0; - - // Origin door - P_SetTarget(&door->tracer, actor); - - //Back - door = P_SpawnMobj(x - c*d, y - s*d, z, MT_SALOONDOOR); + // ...two door! + if (!(door = P_SpawnMobjFromMobj(actor, -c, -s, 0, locvar1))) return; door->angle = ang; - - // Origin angle - door->extravalue1 = AngleFixed(door->angle); - - // Angular speed - door->extravalue2 = 0; - - // Origin door - P_SetTarget(&door->tracer, actor); + door->extravalue1 = AngleFixed(door->angle); // Origin angle + door->extravalue2 = 0; // Angular speed + P_SetTarget(&door->tracer, actor); // Origin door + door->flags2 |= ambush; // Can be opened by normal players? } // Function: A_MinecartSparkThink diff --git a/src/p_inter.c b/src/p_inter.c index f46d06cb3..d11fddcda 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1085,7 +1085,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->exiting) return; - if (player->bumpertime < TICRATE/4) + if (player->bumpertime <= (TICRATE/2)-5) { S_StartSound(toucher, special->info->seesound); if (player->powers[pw_carry] == CR_NIGHTSMODE) @@ -1776,7 +1776,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_MINECARTSPAWNER: - if (!special->fuse || player->powers[pw_carry] != CR_MINECART) + if (!player->bot && (special->fuse < TICRATE || player->powers[pw_carry] != CR_MINECART)) { mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); P_SetTarget(&mcart->target, toucher); @@ -1786,7 +1786,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_ResetPlayer(player); player->pflags |= PF_JUMPDOWN; player->powers[pw_carry] = CR_MINECART; - toucher->player->pflags &= ~PF_APPLYAUTOBRAKE; + player->pflags &= ~PF_APPLYAUTOBRAKE; P_SetTarget(&toucher->tracer, mcart); toucher->momx = toucher->momy = toucher->momz = 0; diff --git a/src/p_map.c b/src/p_map.c index a3b11e2dd..ac5459fed 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -208,7 +208,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { angle_t nightsangle = 0; - if (object->player->bumpertime >= TICRATE/4) + if (object->player->bumpertime > (TICRATE/2)-5) return false; if ((object->player->pflags & PF_TRANSFERTOCLOSEST) && object->player->axis1 && object->player->axis2) @@ -640,6 +640,34 @@ static void P_SlapStick(mobj_t *fang, mobj_t *pole) P_SetTarget(&pole->tracer, NULL); } +static void P_PlayerBarrelCollide(mobj_t *toucher, mobj_t *barrel) +{ + if (toucher->momz < 0) + { + if (toucher->z + toucher->momz > barrel->z + barrel->height) + return; + } + else + { + if (toucher->z > barrel->z + barrel->height) + return; + } + + if (toucher->momz > 0) + { + if (toucher->z + toucher->height + toucher->momz < barrel->z) + return; + } + else + { + if (toucher->z + toucher->height < barrel->z) + return; + } + + if (P_PlayerCanDamage(toucher->player, barrel)) + P_DamageMobj(barrel, toucher, toucher, 1, 0); +} + // // PIT_CheckThing // @@ -917,12 +945,11 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_SALOONDOOR && tmthing->player) { - if (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer) && tmthing->tracer->health) + mobj_t *ref = (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)) ? tmthing->tracer : tmthing; + if ((thing->flags & MF2_AMBUSH) || ref != tmthing) { - fixed_t dx = tmthing->tracer->momx; - fixed_t dy = tmthing->tracer->momy; - fixed_t dm = min(FixedHypot(dx, dy), 16*FRACUNIT); - angle_t ang = R_PointToAngle2(0, 0, dx, dy) - thing->angle; + fixed_t dm = min(FixedHypot(ref->momx, ref->momy), 16*FRACUNIT); + angle_t ang = R_PointToAngle2(0, 0, ref->momx, ref->momy) - thing->angle; fixed_t s = FINESINE((ang >> ANGLETOFINESHIFT) & FINEMASK); S_StartSound(tmthing, thing->info->activesound); thing->extravalue2 += 2*FixedMul(s, dm)/3; @@ -930,39 +957,10 @@ static boolean PIT_CheckThing(mobj_t *thing) } } - if (thing->type == MT_TNTBARREL && tmthing->player) + if (thing->type == MT_SALOONDOORCENTER && tmthing->player) { - if (tmthing->momz < 0) - { - if (tmthing->z + tmthing->momz > thing->z + thing->height) - return true; - } - else - { - if (tmthing->z > thing->z + thing->height) - return true; - } - - if (tmthing->momz > 0) - { - if (tmthing->z + tmthing->height + tmthing->momz < thing->z) - return true; - } - else - { - if (tmthing->z + tmthing->height < thing->z) - return true; - } - - if ((tmthing->player->pflags & (PF_SPINNING | PF_GLIDING)) - || ((tmthing->player->pflags & PF_JUMPED) - && (!(tmthing->player->pflags & PF_NOJUMPDAMAGE) - || (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) - || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) - || ((tmthing->player->charflags & SF_STOMPDAMAGE || tmthing->player->pflags & PF_BOUNCING) - && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height / 2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)) - || (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (tmthing->player->pflags & PF_SHIELDABILITY))) - P_DamageMobj(thing, tmthing, tmthing, 1, 0); + if ((thing->flags & MF2_AMBUSH) || (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer))) + return true; } if (thing->type == MT_ROLLOUTROCK && tmthing->player && tmthing->health) @@ -1023,6 +1021,9 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_PTERABYTE && tmthing->player) P_DoPterabyteCarry(tmthing->player, thing); + if (thing->type == MT_TNTBARREL && tmthing->player) + P_PlayerBarrelCollide(tmthing, thing); + if (thing->type == MT_VULTURE && tmthing->type == MT_VULTURE) { fixed_t dx = thing->x - tmthing->x; diff --git a/src/p_mobj.c b/src/p_mobj.c index ce65ed8df..d4d968ea7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2369,9 +2369,9 @@ boolean P_CheckDeathPitCollide(mobj_t *mo) return false; if (((mo->z <= mo->subsector->sector->floorheight - && !(mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR)) + && ((mo->subsector->sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR)) || (mo->z + mo->height >= mo->subsector->sector->ceilingheight - && (mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_CEILING))) + && ((mo->subsector->sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_CEILING))) && (GETSECSPECIAL(mo->subsector->sector->special, 1) == 6 || GETSECSPECIAL(mo->subsector->sector->special, 1) == 7)) return true; @@ -10145,6 +10145,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) } case MT_TNTBARREL: mobj->momx = 1; //stack hack + mobj->flags2 |= MF2_INVERTAIMABLE; break; case MT_MINECARTEND: P_SetTarget(&mobj->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID)); @@ -10478,7 +10479,7 @@ void P_SpawnPrecipitation(void) if (curWeather == PRECIP_SNOW) { // Not in a sector with visible sky -- exception for NiGHTS. - if (!(maptol & TOL_NIGHTS) && precipsector->sector->ceilingpic != skyflatnum) + if ((!(maptol & TOL_NIGHTS) && (precipsector->sector->ceilingpic != skyflatnum)) == !(precipsector->sector->flags & SF_INVERTPRECIP)) continue; rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE); @@ -10491,7 +10492,7 @@ void P_SpawnPrecipitation(void) else // everything else. { // Not in a sector with visible sky. - if (precipsector->sector->ceilingpic != skyflatnum) + if ((precipsector->sector->ceilingpic != skyflatnum) == !(precipsector->sector->flags & SF_INVERTPRECIP)) continue; rainmo = P_SpawnRainMobj(x, y, height, MT_RAIN); diff --git a/src/p_spec.c b/src/p_spec.c index 256ca3453..5b8e25050 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4174,26 +4174,11 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n // Check the 3D floor's type... if (rover->flags & FF_BLOCKPLAYER) { + boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == topheight)); + boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == bottomheight)); // Thing must be on top of the floor to be affected... - if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) - && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) - { - if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight) - continue; - } - else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) - && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) - { - if (!(player->mo->eflags & MFE_VERTICALFLIP) - || player->mo->z + player->mo->height != bottomheight) - continue; - } - else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) - { - if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight) - || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight))) - continue; - } + if (!(floorallowed || ceilingallowed)) + continue; } else { @@ -4234,26 +4219,11 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n // Check the 3D floor's type... if (rover->flags & FF_BLOCKPLAYER) { + boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == topheight)); + boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == bottomheight)); // Thing must be on top of the floor to be affected... - if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) - && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) - { - if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight) - continue; - } - else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) - && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) - { - if (!(player->mo->eflags & MFE_VERTICALFLIP) - || player->mo->z + player->mo->height != bottomheight) - continue; - } - else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) - { - if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight) - || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight))) - continue; - } + if (!(floorallowed || ceilingallowed)) + continue; } else { @@ -4304,26 +4274,11 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar // Check the 3D floor's type... if (rover->flags & FF_BLOCKPLAYER) { + boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == top)); + boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == bottom)); // Thing must be on top of the floor to be affected... - if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) - && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) - { - if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != top) - return false; - } - else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) - && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) - { - if (!(mo->eflags & MFE_VERTICALFLIP) - || mo->z + mo->height != bottom) - return false; - } - else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) - { - if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottom) - || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == top))) - return false; - } + if (!(floorallowed || ceilingallowed)) + continue; } else { @@ -4345,10 +4300,10 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar // static boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec) { - if (mo->eflags & MFE_VERTICALFLIP) - return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING); - else - return (mo->z == P_GetSpecialBottomZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_FLOOR); + boolean floorallowed = ((sec->flags & SF_FLIPSPECIAL_FLOOR) && ((sec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == P_GetSpecialBottomZ(mo, sec, sec))); + boolean ceilingallowed = ((sec->flags & SF_FLIPSPECIAL_CEILING) && ((sec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == P_GetSpecialTopZ(mo, sec, sec))); + // Thing must be on top of the floor to be affected... + return (floorallowed || ceilingallowed); } /** Applies a sector special to a player. @@ -5312,26 +5267,11 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo) if (((rover->flags & FF_BLOCKPLAYER) && mo->player) || ((rover->flags & FF_BLOCKOTHERS) && !mo->player)) { + boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == topheight)); + boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == bottomheight)); // Thing must be on top of the floor to be affected... - if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) - && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) - { - if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != topheight) - continue; - } - else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) - && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) - { - if (!(mo->eflags & MFE_VERTICALFLIP) - || mo->z + mo->height != bottomheight) - continue; - } - else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) - { - if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottomheight) - || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == topheight))) - continue; - } + if (!(floorallowed || ceilingallowed)) + continue; } else { @@ -5374,26 +5314,11 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) // Check the 3D floor's type... if (rover->flags & FF_BLOCKPLAYER) { + boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == topheight)); + boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == bottomheight)); // Thing must be on top of the floor to be affected... - if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) - && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) - { - if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight) - continue; - } - else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) - && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) - { - if (!(player->mo->eflags & MFE_VERTICALFLIP) - || player->mo->z + player->mo->height != bottomheight) - continue; - } - else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) - { - if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight) - || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight))) - continue; - } + if (!(floorallowed || ceilingallowed)) + continue; } else { @@ -5450,38 +5375,16 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) } if (!(po->flags & POF_TESTHEIGHT)) // Don't do height checking - { - } + ; else if (po->flags & POF_SOLID) { + boolean floorallowed = ((polysec->flags & SF_FLIPSPECIAL_FLOOR) && ((polysec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == polysec->ceilingheight)); + boolean ceilingallowed = ((polysec->flags & SF_FLIPSPECIAL_CEILING) && ((polysec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == polysec->floorheight)); // Thing must be on top of the floor to be affected... - if ((polysec->flags & SF_FLIPSPECIAL_FLOOR) - && !(polysec->flags & SF_FLIPSPECIAL_CEILING)) + if (!(floorallowed || ceilingallowed)) { - if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != polysec->ceilingheight) - { - po = (polyobj_t *)(po->link.next); - continue; - } - } - else if ((polysec->flags & SF_FLIPSPECIAL_CEILING) - && !(polysec->flags & SF_FLIPSPECIAL_FLOOR)) - { - if (!(player->mo->eflags & MFE_VERTICALFLIP) - || player->mo->z + player->mo->height != polysec->floorheight) - { - po = (polyobj_t *)(po->link.next); - continue; - } - } - else if (polysec->flags & SF_FLIPSPECIAL_BOTH) - { - if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == polysec->floorheight) - || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == polysec->ceilingheight))) - { - po = (polyobj_t *)(po->link.next); - continue; - } + po = (polyobj_t *)(po->link.next); + continue; } } else @@ -5580,17 +5483,13 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) f_affectpoint = P_GetSpecialBottomZ(player->mo, sector, sector); c_affectpoint = P_GetSpecialTopZ(player->mo, sector, sector); - // Only go further if on the ground - if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint) - return; - - if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != c_affectpoint) - return; - - if ((sector->flags & SF_FLIPSPECIAL_BOTH) - && player->mo->z != f_affectpoint - && player->mo->z + player->mo->height != c_affectpoint) - return; + { + boolean floorallowed = ((sector->flags & SF_FLIPSPECIAL_FLOOR) && ((sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == f_affectpoint)); + boolean ceilingallowed = ((sector->flags & SF_FLIPSPECIAL_CEILING) && ((sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == c_affectpoint)); + // Thing must be on top of the floor to be affected... + if (!(floorallowed || ceilingallowed)) + return; + } P_ProcessSpecialSector(player, sector, NULL); } @@ -6683,6 +6582,11 @@ void P_SpawnSpecials(INT32 fromnetsave) if (lines[i].flags & ML_EFFECT3) sectors[s].flags |= SF_TRIGGERSPECIAL_TOUCH; + if (lines[i].flags & ML_EFFECT2) + sectors[s].flags |= SF_TRIGGERSPECIAL_HEADBUMP; + + if (lines[i].flags & ML_EFFECT1) + sectors[s].flags |= SF_INVERTPRECIP; if (lines[i].frontsector && GETSECSPECIAL(lines[i].frontsector->special, 4) == 12) sectors[s].camsec = sides[*lines[i].sidenum].sector-sectors; diff --git a/src/p_tick.c b/src/p_tick.c index 7606510fe..6b5c7980c 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -482,7 +482,7 @@ static inline void P_DoSpecialStageStuff(void) countspheres += players[i].spheres; // If in water, deplete timer 6x as fast. - if (players[i].mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) + if (players[i].mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER) && !(players[i].powers[pw_shield] & SH_PROTECTWATER)) players[i].nightstime -= 5; if (--players[i].nightstime > 6) { diff --git a/src/p_user.c b/src/p_user.c index 415bea763..ff30778ee 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8892,7 +8892,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) continue; if (mo->type == MT_MINUS && !(mo->flags & (MF_SPECIAL|MF_SHOOTABLE))) - mo->flags |= MF_SPECIAL|MF_SHOOTABLE; + mo->flags = (mo->flags & ~MF_NOCLIPTHING)|MF_SPECIAL|MF_SHOOTABLE; if (mo->type == MT_EGGGUARD && mo->tracer) //nuke Egg Guard's shield! P_KillMobj(mo->tracer, inflictor, source, DMG_NUKE); @@ -10291,7 +10291,7 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *n ffloor_t *rover; for (rover = sec->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) + if (!(rover->flags & (FF_EXISTS|FF_BLOCKOTHERS))) continue; *nz = *rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight; diff --git a/src/r_defs.h b/src/r_defs.h index def7b46f3..6aeb0671c 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -263,10 +263,15 @@ typedef struct pslope_s typedef enum { - SF_FLIPSPECIAL_FLOOR = 1, - SF_FLIPSPECIAL_CEILING = 2, - SF_FLIPSPECIAL_BOTH = 3, - SF_TRIGGERSPECIAL_TOUCH = 4, + // flipspecial - planes with effect + SF_FLIPSPECIAL_FLOOR = 1, + SF_FLIPSPECIAL_CEILING = 1<<1, + SF_FLIPSPECIAL_BOTH = (SF_FLIPSPECIAL_FLOOR|SF_FLIPSPECIAL_CEILING), + // triggerspecial - conditions under which plane touch causes effect + SF_TRIGGERSPECIAL_TOUCH = 1<<2, + SF_TRIGGERSPECIAL_HEADBUMP = 1<<3, + // invertprecip - inverts presence of precipitation + SF_INVERTPRECIP = 1<<4, } sectorflags_t; // diff --git a/src/st_stuff.c b/src/st_stuff.c index 20a132b3a..b9ca0850a 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1857,7 +1857,8 @@ static void ST_drawNiGHTSHUD(void) numbersize = 48/2; if ((oldspecialstage && leveltime & 2) - && (stplyr->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER))) + && (stplyr->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) + && !(stplyr->powers[pw_shield] & SH_PROTECTWATER)) col = SKINCOLOR_ORANGE; ST_DrawNightsOverlayNum((160 + numbersize)<