mirror of
https://github.com/ZDoom/gzdoom-last-svn.git
synced 2025-06-04 19:20:53 +00:00
Update to ZDoom r1831:
fixed: The Dehacked flags parser fix from May 31 (r1624) was undone by yesterday's additions. Changed it so that the parser first checks for the presence of a '-' sign before deciding whether to use strtol or strtoul to convert the string into a number. - Added PinkSilver's A_LookEx fix. - added resources needed for MBF support. - removed unused score items from DECORATE file. - Fixed: Argument count for UsePuzzleItem was wrong. - Added a few things from Gez's experimental build: * MBF Dehacked emulation but removed the COMPATF_MBFDEHACKED flag because it wouldn't work and is more or less useless anyway. * MBF's dog (definition only, no sprites yet.) * User variables. There's an array of 10. They can be set and checked in both DECORATE and ACS. * Made the tag name changeable but eliminated the redundancy of having both the meta property and the individual actor's one. Having one is fully sufficient. TO BE FIXED: Names are case insensitive but this should better be case sensitive. Unfortunately there's currently nothing better than FName to store a string inside an actor without severely complicating matters. Also bumped savegame version to avoid problems with this change. * MBF grenade and bouncing code. * several compatibility options. * info CCMD to print extended actor information (not fully implemented yet) * summonmbf CCMD. * Beta BFG code pointer (but not the related missiles yet.) * PowerInvisibility enhancements. * ScoreItem with one significant change: Added a score variable that can be checked through ACS and DECORATE. The engine itself will do nothing with it. * Nailgun option for A_Explode. * A_PrintBold and A_Log. * A_SetSpecial. * Beta Lost Soul (added DoomEdNum 9037 to it) * A_Mushroom extensions * Vavoom compatible MAPINFO keynames. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@452 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
parent
67a7c1b1b7
commit
2352d102e9
152 changed files with 1991 additions and 445 deletions
149
src/p_map.cpp
149
src/p_map.cpp
|
@ -590,17 +590,25 @@ bool PIT_CheckLine (line_t *ld, const FBoundingBox &box, FCheckPosition &tm)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(tm.thing->flags & MF_MISSILE) || (ld->flags & (ML_BLOCKEVERYTHING|ML_BLOCKPROJECTILE)))
|
||||
{
|
||||
// MBF bouncers are treated as missiles here.
|
||||
bool Projectile = (tm.thing->flags & MF_MISSILE || tm.thing->BounceFlags & BOUNCE_MBF);
|
||||
// MBF considers that friendly monsters are not blocked by monster-blocking lines.
|
||||
// This is added here as a compatibility option. Note that monsters that are dehacked
|
||||
// into being friendly with the MBF flag automatically gain MF3_NOBLOCKMONST, so this
|
||||
// just optionally generalizes the behavior to other friendly monsters.
|
||||
bool NotBlocked = ((tm.thing->flags3 & MF3_NOBLOCKMONST)
|
||||
|| ((i_compatflags & COMPATF_NOBLOCKFRIENDS) && (tm.thing->flags & MF_FRIENDLY)));
|
||||
|
||||
if (!(Projectile) || (ld->flags & (ML_BLOCKEVERYTHING|ML_BLOCKPROJECTILE))) {
|
||||
if (ld->flags & ML_RAILING)
|
||||
{
|
||||
rail = true;
|
||||
}
|
||||
else if ((ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING)) || // explicitly blocking everything
|
||||
(!(tm.thing->flags3 & MF3_NOBLOCKMONST) && (ld->flags & ML_BLOCKMONSTERS)) || // block monsters only
|
||||
(tm.thing->player != NULL && (ld->flags & ML_BLOCK_PLAYERS)) || // block players
|
||||
((tm.thing->flags & MF_MISSILE) && (ld->flags & ML_BLOCKPROJECTILE)) || // block projectiles
|
||||
((ld->flags & ML_BLOCK_FLOATERS) && (tm.thing->flags & MF_FLOAT))) // block floaters
|
||||
else if ((ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING)) || // explicitly blocking everything
|
||||
(!(NotBlocked) && (ld->flags & ML_BLOCKMONSTERS)) || // block monsters only
|
||||
(tm.thing->player != NULL && (ld->flags & ML_BLOCK_PLAYERS)) || // block players
|
||||
((Projectile) && (ld->flags & ML_BLOCKPROJECTILE)) || // block projectiles
|
||||
((tm.thing->flags & MF_FLOAT) && (ld->flags & ML_BLOCK_FLOATERS))) // block floaters
|
||||
{
|
||||
if (tm.thing->flags2 & MF2_BLASTED)
|
||||
{
|
||||
|
@ -754,6 +762,13 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
|
|||
bool solid;
|
||||
int damage;
|
||||
|
||||
if (!((thing->flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE)) || thing->flags6 & MF6_TOUCHY))
|
||||
return true; // can't hit thing
|
||||
|
||||
fixed_t blockdist = thing->radius + tm.thing->radius;
|
||||
if ( abs(thing->x - tm.x) >= blockdist || abs(thing->y - tm.y) >= blockdist)
|
||||
return true;
|
||||
|
||||
// don't clip against self
|
||||
if (thing == tm.thing)
|
||||
return true;
|
||||
|
@ -764,13 +779,6 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
|
|||
if ((tm.thing->flags6 & MF6_THRUSPECIES) && (tm.thing->GetSpecies() == thing->GetSpecies()))
|
||||
return true;
|
||||
|
||||
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE)) )
|
||||
return true; // can't hit thing
|
||||
|
||||
fixed_t blockdist = thing->radius + tm.thing->radius;
|
||||
if ( abs(thing->x - tm.x) >= blockdist || abs(thing->y - tm.y) >= blockdist)
|
||||
return true;
|
||||
|
||||
tm.thing->BlockingMobj = thing;
|
||||
topz = thing->z + thing->height;
|
||||
if (!(i_compatflags & COMPATF_NO_PASSMOBJ) && !(tm.thing->flags & (MF_FLOAT|MF_MISSILE|MF_SKULLFLY|MF_NOGRAVITY)) &&
|
||||
|
@ -806,6 +814,26 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// touchy object is alive, toucher is solid
|
||||
if (thing->flags6 & MF6_TOUCHY && tm.thing->flags & MF_SOLID && thing->health > 0 &&
|
||||
// Thing is an armed mine or a sentient thing
|
||||
(thing->flags6 & MF6_ARMED || thing->IsSentient()) &&
|
||||
// either different classes or players
|
||||
(thing->player || thing->GetClass() != tm.thing->GetClass()) &&
|
||||
// or different species if DONTHARMSPECIES
|
||||
(!(thing->flags6 & MF6_DONTHARMSPECIES) || thing->GetSpecies() != tm.thing->GetSpecies()) &&
|
||||
// touches vertically
|
||||
thing->z + thing->height >= tm.thing->z && tm.thing->z + tm.thing->height >= thing->z &&
|
||||
// prevents lost souls from exploding when fired by pain elementals
|
||||
(thing->master != tm.thing && tm.thing->master != thing))
|
||||
// Difference with MBF: MBF hardcodes the LS/PE check and lets actors of the same species
|
||||
// but different classes trigger the touchiness, but that seems less straightforwards.
|
||||
{
|
||||
thing->flags6 &= ~MF6_ARMED; // Disarm
|
||||
P_DamageMobj (thing, NULL, NULL, thing->health, NAME_None, DMG_FORCED); // kill object
|
||||
return true;
|
||||
}
|
||||
// Check for skulls slamming into things
|
||||
if (tm.thing->flags & MF_SKULLFLY)
|
||||
{
|
||||
|
@ -839,8 +867,8 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
|
|||
LineSpecials[thing->special] (NULL, tm.thing, false, thing->args[0],
|
||||
thing->args[1], thing->args[2], thing->args[3], thing->args[4]);
|
||||
}
|
||||
// Check for missile
|
||||
if (tm.thing->flags & MF_MISSILE)
|
||||
// Check for missile or non-solid MBF bouncer
|
||||
if (tm.thing->flags & MF_MISSILE || ((tm.thing->BounceFlags & BOUNCE_MBF) && !(tm.thing->flags & MF_SOLID)))
|
||||
{
|
||||
// Check for a non-shootable mobj
|
||||
if (thing->flags2 & MF2_NONSHOOTABLE)
|
||||
|
@ -891,7 +919,8 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
|
|||
|
||||
// [RH] What is the point of this check, again? In Hexen, it is unconditional,
|
||||
// but here we only do it if the missile's damage is 0.
|
||||
if ((tm.thing->BounceFlags & BOUNCE_Actors) && tm.thing->Damage == 0)
|
||||
// MBF bouncer might have a non-0 damage value, but they must not deal damage on impact either.
|
||||
if ((tm.thing->BounceFlags & BOUNCE_Actors) && (tm.thing->Damage == 0 || !(tm.thing->flags & MF_MISSILE)))
|
||||
{
|
||||
return (tm.thing->target == thing || !(thing->flags & MF_SOLID));
|
||||
}
|
||||
|
@ -1314,7 +1343,8 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm)
|
|||
|
||||
while ((ld = it.Next()))
|
||||
{
|
||||
if (!PIT_CheckLine(ld, box, tm)) return false;
|
||||
if (!PIT_CheckLine(ld, box, tm))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tm.ceilingz - tm.floorz < thing->height)
|
||||
|
@ -1594,12 +1624,12 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y,
|
|||
#else
|
||||
// When flying, slide up or down blocking lines until the actor
|
||||
// is not blocked.
|
||||
if (thing->z+thing->height > tmceilingz)
|
||||
if (thing->z+thing->height > tm.ceilingz)
|
||||
{
|
||||
thing->velz = -8*FRACUNIT;
|
||||
goto pushline;
|
||||
}
|
||||
else if (thing->z < tmfloorz && tmfloorz-tmdropoffz > thing->MaxDropOffHeight)
|
||||
else if (thing->z < tm.floorz && tm.floorz-tm.dropoffz > thing->MaxDropOffHeight)
|
||||
{
|
||||
thing->velz = 8*FRACUNIT;
|
||||
goto pushline;
|
||||
|
@ -1706,6 +1736,12 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y,
|
|||
oldAboveFakeCeiling = eyez > oldsec->heightsec->ceilingplane.ZatPoint (thing->x, thing->y);
|
||||
}
|
||||
|
||||
// Borrowed from MBF:
|
||||
if (thing->BounceFlags & BOUNCE_MBF && // killough 8/13/98
|
||||
!(thing->flags & (MF_MISSILE|MF_NOGRAVITY)) &&
|
||||
!thing->IsSentient() && tm.floorz - thing->z > 16*FRACUNIT)
|
||||
return false; // too big a step up for MBF bouncers under gravity
|
||||
|
||||
// the move is ok, so link the thing into its new position
|
||||
thing->UnlinkFromWorld ();
|
||||
|
||||
|
@ -1972,8 +2008,6 @@ struct FSlide
|
|||
bool BounceWall (AActor *mo);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// P_HitSlideLine
|
||||
// Adjusts the xmove / ymove
|
||||
|
@ -2152,7 +2186,8 @@ void FSlide::SlideTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_
|
|||
{
|
||||
goto isblocking;
|
||||
}
|
||||
if (li->flags & ML_BLOCKMONSTERS && !(slidemo->flags3 & MF3_NOBLOCKMONST))
|
||||
if (li->flags & ML_BLOCKMONSTERS && !((slidemo->flags3 & MF3_NOBLOCKMONST)
|
||||
|| ((i_compatflags & COMPATF_NOBLOCKFRIENDS) && (slidemo->flags & MF_FRIENDLY))))
|
||||
{
|
||||
goto isblocking;
|
||||
}
|
||||
|
@ -2595,7 +2630,10 @@ bool FSlide::BounceWall (AActor *mo)
|
|||
// The amount of bounces is limited
|
||||
if (mo->bouncecount>0 && --mo->bouncecount==0)
|
||||
{
|
||||
P_ExplodeMissile(mo, NULL, NULL);
|
||||
if (mo->flags & MF_MISSILE)
|
||||
P_ExplodeMissile(mo, NULL, NULL);
|
||||
else
|
||||
mo->Die(NULL, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2636,7 +2674,28 @@ bool P_BounceWall (AActor *mo)
|
|||
return slide.BounceWall(mo);
|
||||
}
|
||||
|
||||
|
||||
extern FRandom pr_bounce ("Bounce");
|
||||
bool P_BounceActor (AActor *mo, AActor * BlockingMobj)
|
||||
{
|
||||
if (mo && BlockingMobj && ((mo->BounceFlags & BOUNCE_AllActors)
|
||||
|| ((mo->flags & MF_MISSILE) && (BlockingMobj->flags2 & MF2_REFLECTIVE)
|
||||
|| ((!BlockingMobj->player) && (!(BlockingMobj->flags3 & MF3_ISMONSTER))))
|
||||
))
|
||||
{
|
||||
fixed_t speed;
|
||||
angle_t angle = R_PointToAngle2 (BlockingMobj->x,
|
||||
BlockingMobj->y, mo->x, mo->y) + ANGLE_1*((pr_bounce()%16)-8);
|
||||
speed = P_AproxDistance (mo->velx, mo->vely);
|
||||
speed = FixedMul (speed, mo->wallbouncefactor); // [GZ] was 0.75, using wallbouncefactor seems more consistent
|
||||
mo->angle = angle;
|
||||
angle >>= ANGLETOFINESHIFT;
|
||||
mo->velx = FixedMul (speed, finecosine[angle]);
|
||||
mo->vely = FixedMul (speed, finesine[angle]);
|
||||
mo->PlayBounceSound(true);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
|
@ -2667,7 +2726,7 @@ struct aim_t
|
|||
bool AimTraverse3DFloors(const divline_t &trace, intercept_t * in);
|
||||
#endif
|
||||
|
||||
void AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy);
|
||||
void AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, bool checknonshootable = false);
|
||||
|
||||
};
|
||||
|
||||
|
@ -2784,7 +2843,7 @@ bool aim_t::AimTraverse3DFloors(const divline_t &trace, intercept_t * in)
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy)
|
||||
void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, bool checknonshootable)
|
||||
{
|
||||
FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES|PT_ADDTHINGS);
|
||||
intercept_t *in;
|
||||
|
@ -2839,18 +2898,20 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
|||
if (th == shootthing)
|
||||
continue; // can't shoot self
|
||||
|
||||
if (!(th->flags&MF_SHOOTABLE))
|
||||
continue; // corpse or something
|
||||
|
||||
// check for physical attacks on a ghost
|
||||
if ((th->flags3 & MF3_GHOST) &&
|
||||
shootthing->player && // [RH] Be sure shootthing is a player
|
||||
shootthing->player->ReadyWeapon &&
|
||||
(shootthing->player->ReadyWeapon->flags2 & MF2_THRUGHOST))
|
||||
if (!checknonshootable) // For info CCMD, ignore stuff about GHOST and SHOOTABLE flags
|
||||
{
|
||||
continue;
|
||||
if (!(th->flags&MF_SHOOTABLE))
|
||||
continue; // corpse or something
|
||||
|
||||
// check for physical attacks on a ghost
|
||||
if ((th->flags3 & MF3_GHOST) &&
|
||||
shootthing->player && // [RH] Be sure shootthing is a player
|
||||
shootthing->player->ReadyWeapon &&
|
||||
(shootthing->player->ReadyWeapon->flags2 & MF2_THRUGHOST))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
dist = FixedMul (attackrange, in->frac);
|
||||
|
||||
#ifdef _3DFLOORS
|
||||
|
@ -2974,6 +3035,11 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
|||
aimpitch=thingpitch;
|
||||
return;
|
||||
}
|
||||
if (checknonshootable)
|
||||
{
|
||||
linetarget=th;
|
||||
aimpitch=thingpitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2982,7 +3048,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
|||
// P_AimLineAttack
|
||||
//
|
||||
//============================================================================
|
||||
fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget, fixed_t vrange, bool forcenosmart, bool check3d)
|
||||
fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget, fixed_t vrange, bool forcenosmart, bool check3d, bool checknonshootable)
|
||||
{
|
||||
fixed_t x2;
|
||||
fixed_t y2;
|
||||
|
@ -3051,7 +3117,7 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p
|
|||
}
|
||||
#endif
|
||||
|
||||
aim.AimTraverse (t1->x, t1->y, x2, y2);
|
||||
aim.AimTraverse (t1->x, t1->y, x2, y2, checknonshootable);
|
||||
|
||||
if (!aim.linetarget)
|
||||
{
|
||||
|
@ -3968,7 +4034,9 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b
|
|||
|
||||
while ((thing = it.Next()))
|
||||
{
|
||||
if (!(thing->flags & MF_SHOOTABLE) )
|
||||
// Vulnerable actors can be damaged by radius attacks even if not shootable
|
||||
// Used to emulate MBF's vulnerability of non-missile bouncers to explosions.
|
||||
if (!((thing->flags & MF_SHOOTABLE) || (thing->flags6 & MF6_VULNERABLE)))
|
||||
continue;
|
||||
|
||||
// Boss spider and cyborg and Heretic's ep >= 2 bosses
|
||||
|
@ -4124,7 +4192,6 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// SECTOR HEIGHT CHANGING
|
||||
// After modifying a sector's floor or ceiling height,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue