mirror of
https://github.com/ZDoom/gzdoom-last-svn.git
synced 2025-06-01 17:52:05 +00:00
* 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:
parent
2329ad9f70
commit
faaa683ad5
12 changed files with 75 additions and 26 deletions
|
@ -335,7 +335,7 @@ static void CHolyFindTarget (AActor *actor)
|
||||||
{
|
{
|
||||||
AActor *target;
|
AActor *target;
|
||||||
|
|
||||||
if ( (target = P_RoughMonsterSearch (actor, 6)) )
|
if ( (target = P_RoughMonsterSearch (actor, 6, true)) )
|
||||||
{
|
{
|
||||||
actor->tracer = target;
|
actor->tracer = target;
|
||||||
actor->flags |= MF_NOCLIP|MF_SKULLFLY;
|
actor->flags |= MF_NOCLIP|MF_SKULLFLY;
|
||||||
|
|
|
@ -167,7 +167,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffTrack)
|
||||||
{
|
{
|
||||||
if ((self->tracer == 0) && (pr_mstafftrack()<50))
|
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);
|
P_SeekerMissile (self, ANGLE_1*2, ANGLE_1*10);
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,7 +192,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker)
|
||||||
gender = self->player->userinfo.gender;
|
gender = self->player->userinfo.gender;
|
||||||
|
|
||||||
// Treat voodoo dolls as unknown deaths
|
// Treat voodoo dolls as unknown deaths
|
||||||
if (inflictor && inflictor->player == self->player)
|
if (inflictor && inflictor->player && inflictor->player->mo != inflictor)
|
||||||
MeansOfDeath = NAME_None;
|
MeansOfDeath = NAME_None;
|
||||||
|
|
||||||
if (multiplayer && !deathmatch)
|
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;
|
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)
|
if (messagename != NULL)
|
||||||
message = GStrings(messagename);
|
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);
|
source->Inventory->ModifyDamage(olddam, mod, damage, false);
|
||||||
if (olddam != damage && damage <= 0)
|
if (olddam != damage && damage <= 0)
|
||||||
{ // Still allow FORCEPAIN
|
{ // 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;
|
goto dopain;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -997,8 +1006,11 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
|
||||||
target->Inventory->ModifyDamage(olddam, mod, damage, true);
|
target->Inventory->ModifyDamage(olddam, mod, damage, true);
|
||||||
if (olddam != damage && damage <= 0)
|
if (olddam != damage && damage <= 0)
|
||||||
{ // Still allow FORCEPAIN
|
{ // 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;
|
goto dopain;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1012,8 +1024,11 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
|
||||||
}
|
}
|
||||||
if (damage <= 0)
|
if (damage <= 0)
|
||||||
{ // Still allow FORCEPAIN
|
{ // 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;
|
goto dopain;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1146,8 +1161,11 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
|
||||||
if (damage <= 0)
|
if (damage <= 0)
|
||||||
{
|
{
|
||||||
// If MF6_FORCEPAIN is set, make the player enter the pain state.
|
// If MF6_FORCEPAIN is set, make the player enter the pain state.
|
||||||
if (inflictor != NULL && (inflictor->flags6 & MF6_FORCEPAIN))
|
if (!(target->flags5 & MF5_NOPAIN) && inflictor != NULL &&
|
||||||
goto dopain;
|
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS))
|
||||||
|
{
|
||||||
|
goto dopain;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,7 +350,7 @@ public:
|
||||||
#define PT_DELTA 8 // x2,y2 is passed as a delta, not as an endpoint
|
#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_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
|
// P_MAP
|
||||||
|
|
|
@ -1561,6 +1561,10 @@ bool P_TestMobjZ (AActor *actor, bool quick, AActor **pOnmobj)
|
||||||
{ // Don't clip against self
|
{ // Don't clip against self
|
||||||
continue;
|
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)
|
if (actor->z > thing->z+thing->height)
|
||||||
{ // over thing
|
{ // over thing
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1401,9 +1401,9 @@ FPathTraverse::~FPathTraverse()
|
||||||
// distance is in MAPBLOCKUNITS
|
// 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)
|
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;
|
FBlockNode *link;
|
||||||
|
|
||||||
for (link = blocklinks[index]; link != NULL; link = link->NextActor)
|
for (link = blocklinks[index]; link != NULL; link = link->NextActor)
|
||||||
{
|
{
|
||||||
if (link->Me != mo)
|
if (link->Me != mo)
|
||||||
{
|
{
|
||||||
|
if (onlyseekable && !mo->CanSeek(link->Me))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (mo->IsOkayToAttack (link->Me))
|
if (mo->IsOkayToAttack (link->Me))
|
||||||
{
|
{
|
||||||
return link->Me;
|
return link->Me;
|
||||||
|
|
|
@ -1884,8 +1884,6 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
|
||||||
goto explode;
|
goto explode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Reflect the missile along angle
|
// Reflect the missile along angle
|
||||||
mo->angle = angle;
|
mo->angle = angle;
|
||||||
angle >>= ANGLETOFINESHIFT;
|
angle >>= ANGLETOFINESHIFT;
|
||||||
|
|
|
@ -1438,8 +1438,9 @@ public:
|
||||||
numsides = sidecount;
|
numsides = sidecount;
|
||||||
lines = new line_t[numlines];
|
lines = new line_t[numlines];
|
||||||
sides = new side_t[numsides];
|
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 };
|
short tempalpha[2] = { SHRT_MIN, SHRT_MIN };
|
||||||
|
|
||||||
|
@ -1450,21 +1451,34 @@ public:
|
||||||
if (lines[line].sidedef[sd] != NULL)
|
if (lines[line].sidedef[sd] != NULL)
|
||||||
{
|
{
|
||||||
int mapside = int(intptr_t(lines[line].sidedef[sd]))-1;
|
int mapside = int(intptr_t(lines[line].sidedef[sd]))-1;
|
||||||
sides[side] = ParsedSides[mapside];
|
if (mapside < sidecount)
|
||||||
sides[side].linedef = &lines[line];
|
{
|
||||||
sides[side].sector = §ors[intptr_t(sides[side].sector)];
|
sides[side] = ParsedSides[mapside];
|
||||||
lines[line].sidedef[sd] = &sides[side];
|
sides[side].linedef = &lines[line];
|
||||||
|
sides[side].sector = §ors[intptr_t(sides[side].sector)];
|
||||||
|
lines[line].sidedef[sd] = &sides[side];
|
||||||
|
|
||||||
P_ProcessSideTextures(!isExtended, &sides[side], sides[side].sector, &ParsedSideTextures[mapside],
|
P_ProcessSideTextures(!isExtended, &sides[side], sides[side].sector, &ParsedSideTextures[mapside],
|
||||||
lines[line].special, lines[line].args[0], &tempalpha[sd], missingTex);
|
lines[line].special, lines[line].args[0], &tempalpha[sd], missingTex);
|
||||||
|
|
||||||
side++;
|
side++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lines[line].sidedef[sd] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
P_AdjustLine(&lines[line]);
|
P_AdjustLine(&lines[line]);
|
||||||
P_FinishLoadingLineDef(&lines[line], tempalpha[0]);
|
P_FinishLoadingLineDef(&lines[line], tempalpha[0]);
|
||||||
}
|
}
|
||||||
|
assert(side <= numsides);
|
||||||
|
if (side < numsides)
|
||||||
|
{
|
||||||
|
Printf("Map had %d invalid side references\n", numsides - side);
|
||||||
|
numsides = side;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -365,6 +365,9 @@ void S_Shutdown ()
|
||||||
delete PlayList;
|
delete PlayList;
|
||||||
PlayList = NULL;
|
PlayList = NULL;
|
||||||
}
|
}
|
||||||
|
S_StopMusic (true);
|
||||||
|
mus_playing.name = "";
|
||||||
|
LastSong = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
// This file was automatically generated by the
|
// This file was automatically generated by the
|
||||||
// updaterevision tool. Do not edit by hand.
|
// updaterevision tool. Do not edit by hand.
|
||||||
|
|
||||||
#define ZD_SVN_REVISION_STRING "3568"
|
#define ZD_SVN_REVISION_STRING "3574"
|
||||||
#define ZD_SVN_REVISION_NUMBER 3568
|
#define ZD_SVN_REVISION_NUMBER 3574
|
||||||
|
|
|
@ -501,9 +501,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SeekerMissile)
|
||||||
|
|
||||||
if ((flags & SMF_LOOK) && (self->tracer == 0) && (pr_seekermissile()<chance))
|
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -620,6 +620,7 @@ OB_R_SPLASH = "%o should have stood back.";
|
||||||
OB_ROCKET = "%o should have stood back.";
|
OB_ROCKET = "%o should have stood back.";
|
||||||
OB_KILLEDSELF = "%o killed %hself.";
|
OB_KILLEDSELF = "%o killed %hself.";
|
||||||
|
|
||||||
|
OB_VOODOO = "%o was kill by the power of voodoo.";
|
||||||
OB_STEALTHBABY = "%o thought %g saw an arachnotron.";
|
OB_STEALTHBABY = "%o thought %g saw an arachnotron.";
|
||||||
OB_STEALTHVILE = "%o thought %g saw an archvile.";
|
OB_STEALTHVILE = "%o thought %g saw an archvile.";
|
||||||
OB_STEALTHBARON = "%o thought %g saw a Baron of Hell.";
|
OB_STEALTHBARON = "%o thought %g saw a Baron of Hell.";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue