* Updated to ZDoom r3574:

- Being killed by a voodoo doll now has its own obituary, rather than trying to come up with one by treating it as a real player.
- Fixed: The 0-damage FORCEPAIN checks in P_DamageMobj() also need to check the PAINLESS and NOPAIN flags.
- If A_SeekerMissile is used with the SMF_LOOK flag and its targets is unseekable, it now clears its tracer so that it will look for a new target the next time it is called.
- Extended P_RoughMonsterSearch() with a flag to indicate that it should only search for seekable targets.
- Fixed: P_TestMobjZ() should not let missile shooters block their missiles.
- In S_Shutdown(), stop the song and forget traces of it so that people who feel like setting snd_musicvolume in their atexit don't crash because it tries to restart the song at the new volume.
- Don't crash when loading UDMF maps with invalid sidedef references.

git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1360 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
gez 2012-04-19 11:44:25 +00:00
parent 2329ad9f70
commit faaa683ad5
12 changed files with 75 additions and 26 deletions

View file

@ -335,7 +335,7 @@ static void CHolyFindTarget (AActor *actor)
{
AActor *target;
if ( (target = P_RoughMonsterSearch (actor, 6)) )
if ( (target = P_RoughMonsterSearch (actor, 6, true)) )
{
actor->tracer = target;
actor->flags |= MF_NOCLIP|MF_SKULLFLY;

View file

@ -167,7 +167,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffTrack)
{
if ((self->tracer == 0) && (pr_mstafftrack()<50))
{
self->tracer = P_RoughMonsterSearch (self, 10);
self->tracer = P_RoughMonsterSearch (self, 10, true);
}
P_SeekerMissile (self, ANGLE_1*2, ANGLE_1*10);
}

View file

@ -192,7 +192,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker)
gender = self->player->userinfo.gender;
// Treat voodoo dolls as unknown deaths
if (inflictor && inflictor->player == self->player)
if (inflictor && inflictor->player && inflictor->player->mo != inflictor)
MeansOfDeath = NAME_None;
if (multiplayer && !deathmatch)
@ -228,6 +228,12 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker)
case NAME_Fire: if (attacker == NULL) messagename = "OB_LAVA"; break;
}
// Check for being killed by a voodoo doll.
if (inflictor && inflictor->player && inflictor->player->mo != inflictor)
{
messagename = "OB_VOODOO";
}
if (messagename != NULL)
message = GStrings(messagename);
@ -985,8 +991,11 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
source->Inventory->ModifyDamage(olddam, mod, damage, false);
if (olddam != damage && damage <= 0)
{ // Still allow FORCEPAIN
if (inflictor != NULL && (inflictor->flags6 & MF6_FORCEPAIN))
if (!(target->flags5 & MF5_NOPAIN) && inflictor != NULL &&
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS))
{
goto dopain;
}
return;
}
}
@ -997,8 +1006,11 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
target->Inventory->ModifyDamage(olddam, mod, damage, true);
if (olddam != damage && damage <= 0)
{ // Still allow FORCEPAIN
if (inflictor != NULL && (inflictor->flags6 & MF6_FORCEPAIN))
if (!(target->flags5 & MF5_NOPAIN) && inflictor != NULL &&
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS))
{
goto dopain;
}
return;
}
}
@ -1012,8 +1024,11 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
}
if (damage <= 0)
{ // Still allow FORCEPAIN
if (inflictor != NULL && (inflictor->flags6 & MF6_FORCEPAIN))
if (!(target->flags5 & MF5_NOPAIN) && inflictor != NULL &&
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS))
{
goto dopain;
}
return;
}
}
@ -1146,8 +1161,11 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
if (damage <= 0)
{
// If MF6_FORCEPAIN is set, make the player enter the pain state.
if (inflictor != NULL && (inflictor->flags6 & MF6_FORCEPAIN))
goto dopain;
if (!(target->flags5 & MF5_NOPAIN) && inflictor != NULL &&
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS))
{
goto dopain;
}
return;
}
}

View file

@ -350,7 +350,7 @@ public:
#define PT_DELTA 8 // x2,y2 is passed as a delta, not as an endpoint
AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params = NULL);
AActor *P_RoughMonsterSearch (AActor *mo, int distance);
AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false);
//
// P_MAP

View file

@ -1561,6 +1561,10 @@ bool P_TestMobjZ (AActor *actor, bool quick, AActor **pOnmobj)
{ // Don't clip against self
continue;
}
if ((actor->flags & MF_MISSILE) && thing == actor->target)
{ // Don't clip against whoever shot the missile.
continue;
}
if (actor->z > thing->z+thing->height)
{ // over thing
continue;

View file

@ -1401,9 +1401,9 @@ FPathTraverse::~FPathTraverse()
// distance is in MAPBLOCKUNITS
//===========================================================================
AActor *P_RoughMonsterSearch (AActor *mo, int distance)
AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable)
{
return P_BlockmapSearch (mo, distance, RoughBlockCheck);
return P_BlockmapSearch (mo, distance, RoughBlockCheck, (void *)onlyseekable);
}
AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params)
@ -1501,14 +1501,19 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in
//
//===========================================================================
static AActor *RoughBlockCheck (AActor *mo, int index, void *)
static AActor *RoughBlockCheck (AActor *mo, int index, void *param)
{
bool onlyseekable = param != NULL;
FBlockNode *link;
for (link = blocklinks[index]; link != NULL; link = link->NextActor)
{
if (link->Me != mo)
{
if (onlyseekable && !mo->CanSeek(link->Me))
{
continue;
}
if (mo->IsOkayToAttack (link->Me))
{
return link->Me;

View file

@ -1884,8 +1884,6 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
goto explode;
}
// Reflect the missile along angle
mo->angle = angle;
angle >>= ANGLETOFINESHIFT;

View file

@ -1438,8 +1438,9 @@ public:
numsides = sidecount;
lines = new line_t[numlines];
sides = new side_t[numsides];
int line, side;
for(int line = 0, side = 0; line < numlines; line++)
for(line = 0, side = 0; line < numlines; line++)
{
short tempalpha[2] = { SHRT_MIN, SHRT_MIN };
@ -1450,21 +1451,34 @@ public:
if (lines[line].sidedef[sd] != NULL)
{
int mapside = int(intptr_t(lines[line].sidedef[sd]))-1;
sides[side] = ParsedSides[mapside];
sides[side].linedef = &lines[line];
sides[side].sector = &sectors[intptr_t(sides[side].sector)];
lines[line].sidedef[sd] = &sides[side];
if (mapside < sidecount)
{
sides[side] = ParsedSides[mapside];
sides[side].linedef = &lines[line];
sides[side].sector = &sectors[intptr_t(sides[side].sector)];
lines[line].sidedef[sd] = &sides[side];
P_ProcessSideTextures(!isExtended, &sides[side], sides[side].sector, &ParsedSideTextures[mapside],
lines[line].special, lines[line].args[0], &tempalpha[sd], missingTex);
P_ProcessSideTextures(!isExtended, &sides[side], sides[side].sector, &ParsedSideTextures[mapside],
lines[line].special, lines[line].args[0], &tempalpha[sd], missingTex);
side++;
side++;
}
else
{
lines[line].sidedef[sd] = NULL;
}
}
}
P_AdjustLine(&lines[line]);
P_FinishLoadingLineDef(&lines[line], tempalpha[0]);
}
assert(side <= numsides);
if (side < numsides)
{
Printf("Map had %d invalid side references\n", numsides - side);
numsides = side;
}
}
//===========================================================================

View file

@ -365,6 +365,9 @@ void S_Shutdown ()
delete PlayList;
PlayList = NULL;
}
S_StopMusic (true);
mus_playing.name = "";
LastSong = "";
}
//==========================================================================

View file

@ -3,5 +3,5 @@
// This file was automatically generated by the
// updaterevision tool. Do not edit by hand.
#define ZD_SVN_REVISION_STRING "3568"
#define ZD_SVN_REVISION_NUMBER 3568
#define ZD_SVN_REVISION_STRING "3574"
#define ZD_SVN_REVISION_NUMBER 3574

View file

@ -501,9 +501,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SeekerMissile)
if ((flags & SMF_LOOK) && (self->tracer == 0) && (pr_seekermissile()<chance))
{
self->tracer = P_RoughMonsterSearch (self, distance);
self->tracer = P_RoughMonsterSearch (self, distance, true);
}
if (!P_SeekerMissile(self, clamp<int>(ang1, 0, 90) * ANGLE_1, clamp<int>(ang2, 0, 90) * ANGLE_1, !!(flags & SMF_PRECISE), !!(flags & SMF_CURSPEED)))
{
if (flags & SMF_LOOK)
{ // This monster is no longer seekable, so let us look for another one next time.
self->tracer = NULL;
}
}
P_SeekerMissile(self, clamp<int>(ang1, 0, 90) * ANGLE_1, clamp<int>(ang2, 0, 90) * ANGLE_1, !!(flags & SMF_PRECISE), !!(flags & SMF_CURSPEED));
}
//==========================================================================

View file

@ -620,6 +620,7 @@ OB_R_SPLASH = "%o should have stood back.";
OB_ROCKET = "%o should have stood back.";
OB_KILLEDSELF = "%o killed %hself.";
OB_VOODOO = "%o was kill by the power of voodoo.";
OB_STEALTHBABY = "%o thought %g saw an arachnotron.";
OB_STEALTHVILE = "%o thought %g saw an archvile.";
OB_STEALTHBARON = "%o thought %g saw a Baron of Hell.";