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:
Christoph Oelckers 2009-09-15 06:19:39 +00:00
parent 67a7c1b1b7
commit 2352d102e9
152 changed files with 1991 additions and 445 deletions

View file

@ -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,