- Sync scripting branch with what was in trunk on Sunday. I believe that would be revision 2739.
SVN r2790 (scripting)
This commit is contained in:
commit
99670b708c
317 changed files with 17299 additions and 7273 deletions
386
src/p_mobj.cpp
386
src/p_mobj.cpp
|
|
@ -60,6 +60,7 @@
|
|||
#include "colormatcher.h"
|
||||
#include "v_palette.h"
|
||||
#include "p_enemy.h"
|
||||
#include "gstrings.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
|
@ -171,6 +172,7 @@ IMPLEMENT_POINTY_CLASS (AActor)
|
|||
DECLARE_POINTER (Inventory)
|
||||
DECLARE_POINTER (LastHeard)
|
||||
DECLARE_POINTER (master)
|
||||
DECLARE_POINTER (Poisoner)
|
||||
END_POINTERS
|
||||
|
||||
AActor::~AActor ()
|
||||
|
|
@ -345,6 +347,11 @@ void AActor::Serialize (FArchive &arc)
|
|||
WeaveIndexZ = 0;
|
||||
}
|
||||
}
|
||||
if (SaveVersion >= 2450)
|
||||
{
|
||||
arc << PoisonDamageReceived << PoisonDurationReceived << PoisonPeriodReceived << Poisoner;
|
||||
arc << PoisonDamage << PoisonDuration << PoisonPeriod;
|
||||
}
|
||||
|
||||
// Skip past uservar array in old savegames
|
||||
if (SaveVersion < 1933)
|
||||
|
|
@ -354,65 +361,24 @@ void AActor::Serialize (FArchive &arc)
|
|||
arc << foo;
|
||||
}
|
||||
|
||||
if (arc.IsStoring ())
|
||||
if (SaveVersion > 2560)
|
||||
{
|
||||
int convnum = 0;
|
||||
unsigned int i;
|
||||
|
||||
if (Conversation != NULL)
|
||||
{
|
||||
for (i = 0; i < StrifeDialogues.Size(); ++i)
|
||||
{
|
||||
if (StrifeDialogues[i] == GetDefault()->Conversation)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; i + convnum < StrifeDialogues.Size(); ++convnum)
|
||||
{
|
||||
if (StrifeDialogues[i + convnum] == Conversation)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i + convnum < StrifeDialogues.Size())
|
||||
{
|
||||
convnum++;
|
||||
}
|
||||
else
|
||||
{
|
||||
convnum = 0;
|
||||
}
|
||||
}
|
||||
arc.WriteCount (convnum);
|
||||
arc << ConversationRoot << Conversation;
|
||||
}
|
||||
else
|
||||
else // old code which uses relative indexing.
|
||||
{
|
||||
int convnum;
|
||||
unsigned int i;
|
||||
|
||||
convnum = arc.ReadCount();
|
||||
if (convnum == 0 || GetDefault()->Conversation == NULL)
|
||||
if (GetConversation(GetClass()->TypeName) == -1)
|
||||
{
|
||||
Conversation = NULL;
|
||||
ConversationRoot = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < StrifeDialogues.Size(); ++i)
|
||||
{
|
||||
if (StrifeDialogues[i] == GetDefault()->Conversation)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i + convnum <= StrifeDialogues.Size())
|
||||
{
|
||||
Conversation = StrifeDialogues[i + convnum - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
Conversation = GetDefault()->Conversation;
|
||||
}
|
||||
// This cannot be restored anymore.
|
||||
I_Error("Cannot load old savegames with active dialogues");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -528,7 +494,7 @@ int AActor::GetTics(FState * newstate)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool AActor::SetState (FState *newstate)
|
||||
bool AActor::SetState (FState *newstate, bool nofunction)
|
||||
{
|
||||
if (debugfile && player && (player->cheats & CF_PREDICTING))
|
||||
fprintf (debugfile, "for pl %td: SetState while predicting!\n", player-players);
|
||||
|
|
@ -554,37 +520,41 @@ bool AActor::SetState (FState *newstate)
|
|||
tics = GetTics(newstate);
|
||||
renderflags = (renderflags & ~RF_FULLBRIGHT) | newstate->GetFullbright();
|
||||
newsprite = newstate->sprite;
|
||||
if (newsprite != 1)
|
||||
{
|
||||
// Sprite 1 is ----, which means "do not change the sprite"
|
||||
frame = newstate->GetFrame();
|
||||
|
||||
if (!(flags4 & MF4_NOSKIN) && newsprite == SpawnState->sprite)
|
||||
{ // [RH] If the new sprite is the same as the original sprite, and
|
||||
// this actor is attached to a player, use the player's skin's
|
||||
// sprite. If a player is not attached, do not change the sprite
|
||||
// unless it is different from the previous state's sprite; a
|
||||
// player may have been attached, died, and respawned elsewhere,
|
||||
// and we do not want to lose the skin on the body. If it wasn't
|
||||
// for Dehacked, I would move sprite changing out of the states
|
||||
// altogether, since actors rarely change their sprites after
|
||||
// spawning.
|
||||
if (player != NULL)
|
||||
{
|
||||
sprite = skins[player->userinfo.skin].sprite;
|
||||
if (newsprite != SPR_FIXED)
|
||||
{ // okay to change sprite and/or frame
|
||||
if (!newstate->GetSameFrame())
|
||||
{ // okay to change frame
|
||||
frame = newstate->GetFrame();
|
||||
}
|
||||
if (newsprite != SPR_NOCHANGE)
|
||||
{ // okay to change sprite
|
||||
if (!(flags4 & MF4_NOSKIN) && newsprite == SpawnState->sprite)
|
||||
{ // [RH] If the new sprite is the same as the original sprite, and
|
||||
// this actor is attached to a player, use the player's skin's
|
||||
// sprite. If a player is not attached, do not change the sprite
|
||||
// unless it is different from the previous state's sprite; a
|
||||
// player may have been attached, died, and respawned elsewhere,
|
||||
// and we do not want to lose the skin on the body. If it wasn't
|
||||
// for Dehacked, I would move sprite changing out of the states
|
||||
// altogether, since actors rarely change their sprites after
|
||||
// spawning.
|
||||
if (player != NULL)
|
||||
{
|
||||
sprite = skins[player->userinfo.skin].sprite;
|
||||
}
|
||||
else if (newsprite != prevsprite)
|
||||
{
|
||||
sprite = newsprite;
|
||||
}
|
||||
}
|
||||
else if (newsprite != prevsprite)
|
||||
else
|
||||
{
|
||||
sprite = newsprite;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite = newsprite;
|
||||
}
|
||||
}
|
||||
|
||||
if (newstate->CallAction(this, this))
|
||||
if (!nofunction && newstate->CallAction(this, this))
|
||||
{
|
||||
// Check whether the called action function resulted in destroying the actor
|
||||
if (ObjectFlags & OF_EuthanizeMe)
|
||||
|
|
@ -593,67 +563,10 @@ bool AActor::SetState (FState *newstate)
|
|||
newstate = newstate->GetNextState();
|
||||
} while (tics == 0);
|
||||
|
||||
screen->StateChanged(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// FUNC AActor::SetStateNF
|
||||
//
|
||||
// Same as SetState, but does not call the state function.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool AActor::SetStateNF (FState *newstate)
|
||||
{
|
||||
do
|
||||
if (screen != NULL)
|
||||
{
|
||||
if (newstate == NULL)
|
||||
{
|
||||
state = NULL;
|
||||
Destroy ();
|
||||
return false;
|
||||
}
|
||||
int prevsprite, newsprite;
|
||||
|
||||
if (state != NULL)
|
||||
{
|
||||
prevsprite = state->sprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevsprite = -1;
|
||||
}
|
||||
state = newstate;
|
||||
tics = GetTics(newstate);
|
||||
renderflags = (renderflags & ~RF_FULLBRIGHT) | newstate->GetFullbright();
|
||||
newsprite = newstate->sprite;
|
||||
if (newsprite != 1)
|
||||
{
|
||||
// Sprite 1 is ----, which means "do not change the sprite"
|
||||
|
||||
frame = newstate->GetFrame();
|
||||
if (!(flags4 & MF4_NOSKIN) && newsprite == SpawnState->sprite)
|
||||
{
|
||||
if (player != NULL && gameinfo.gametype != GAME_Hexen)
|
||||
{
|
||||
sprite = skins[player->userinfo.skin].sprite;
|
||||
}
|
||||
else if (newsprite != prevsprite)
|
||||
{
|
||||
sprite = newsprite;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite = newsprite;
|
||||
}
|
||||
}
|
||||
newstate = newstate->GetNextState();
|
||||
} while (tics == 0);
|
||||
|
||||
screen->StateChanged(this);
|
||||
screen->StateChanged(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -824,7 +737,7 @@ AInventory *AActor::DropInventory (AInventory *item)
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
AInventory *AActor::FindInventory (PClassActor *type)
|
||||
AInventory *AActor::FindInventory (PClassActor *type, bool subclass)
|
||||
{
|
||||
AInventory *item;
|
||||
|
||||
|
|
@ -834,9 +747,19 @@ AInventory *AActor::FindInventory (PClassActor *type)
|
|||
}
|
||||
for (item = Inventory; item != NULL; item = item->Inventory)
|
||||
{
|
||||
if (item->GetClass() == type)
|
||||
if (!subclass)
|
||||
{
|
||||
break;
|
||||
if (item->GetClass() == type)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item->IsKindOf(type))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return item;
|
||||
|
|
@ -1528,8 +1451,8 @@ bool AActor::CanSeek(AActor *target) const
|
|||
if (target->flags5 & MF5_CANTSEEK) return false;
|
||||
if ((flags2 & MF2_DONTSEEKINVISIBLE) &&
|
||||
((target->flags & MF_SHADOW) ||
|
||||
target->renderflags & RF_INVISIBLE ||
|
||||
target->RenderStyle.IsVisible(target->alpha)
|
||||
(target->renderflags & RF_INVISIBLE) ||
|
||||
!target->RenderStyle.IsVisible(target->alpha)
|
||||
)
|
||||
) return false;
|
||||
return true;
|
||||
|
|
@ -1544,7 +1467,7 @@ bool AActor::CanSeek(AActor *target) const
|
|||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax)
|
||||
bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise)
|
||||
{
|
||||
int dir;
|
||||
int dist;
|
||||
|
|
@ -1580,28 +1503,54 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax)
|
|||
actor->angle -= delta;
|
||||
}
|
||||
angle = actor->angle>>ANGLETOFINESHIFT;
|
||||
actor->velx = FixedMul (actor->Speed, finecosine[angle]);
|
||||
actor->vely = FixedMul (actor->Speed, finesine[angle]);
|
||||
|
||||
if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)))
|
||||
|
||||
if (!precise)
|
||||
{
|
||||
if (actor->z + actor->height < target->z ||
|
||||
target->z + target->height < actor->z)
|
||||
{ // Need to seek vertically
|
||||
dist = P_AproxDistance (target->x - actor->x, target->y - actor->y);
|
||||
dist = dist / actor->Speed;
|
||||
if (dist < 1)
|
||||
{
|
||||
dist = 1;
|
||||
actor->velx = FixedMul (actor->Speed, finecosine[angle]);
|
||||
actor->vely = FixedMul (actor->Speed, finesine[angle]);
|
||||
|
||||
if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)))
|
||||
{
|
||||
if (actor->z + actor->height < target->z ||
|
||||
target->z + target->height < actor->z)
|
||||
{ // Need to seek vertically
|
||||
dist = P_AproxDistance (target->x - actor->x, target->y - actor->y);
|
||||
dist = dist / actor->Speed;
|
||||
if (dist < 1)
|
||||
{
|
||||
dist = 1;
|
||||
}
|
||||
actor->velz = ((target->z+target->height/2) - (actor->z+actor->height/2)) / dist;
|
||||
}
|
||||
actor->velz = ((target->z+target->height/2) - (actor->z+actor->height/2)) / dist;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
angle_t pitch = 0;
|
||||
if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)))
|
||||
{ // Need to seek vertically
|
||||
double dist = MAX(1.0, FVector2(target->x - actor->x, target->y - actor->y).Length());
|
||||
// Aim at a player's eyes and at the middle of the actor for everything else.
|
||||
fixed_t aimheight = target->height/2;
|
||||
if (target->IsKindOf(RUNTIME_CLASS(APlayerPawn)))
|
||||
{
|
||||
aimheight = static_cast<APlayerPawn *>(target)->ViewHeight;
|
||||
}
|
||||
pitch = R_PointToAngle2(0, actor->z + actor->height/2, xs_CRoundToInt(dist), target->z + aimheight);
|
||||
pitch >>= ANGLETOFINESHIFT;
|
||||
}
|
||||
|
||||
fixed_t xyscale = FixedMul(actor->Speed, finecosine[pitch]);
|
||||
actor->velz = FixedMul(actor->Speed, finesine[pitch]);
|
||||
actor->velx = FixedMul(xyscale, finecosine[angle]);
|
||||
actor->vely = FixedMul(xyscale, finesine[angle]);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// P_XYMovement
|
||||
//
|
||||
|
|
@ -3189,41 +3138,27 @@ void AActor::Tick ()
|
|||
velz <= 0 &&
|
||||
floorz == z)
|
||||
{
|
||||
const secplane_t * floorplane = &floorsector->floorplane;
|
||||
static secplane_t copyplane;
|
||||
secplane_t floorplane = floorsector->floorplane;
|
||||
|
||||
#ifdef _3DFLOORS
|
||||
// Check 3D floors as well
|
||||
if (floorsector->e) // apparently this can be called when the data is already gone-
|
||||
for(unsigned int i=0;i<floorsector->e->XFloor.ffloors.Size();i++)
|
||||
{
|
||||
F3DFloor * rover= floorsector->e->XFloor.ffloors[i];
|
||||
if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;
|
||||
|
||||
if (rover->top.plane->ZatPoint(x, y) == floorz)
|
||||
{
|
||||
copyplane = *rover->top.plane;
|
||||
if (copyplane.c<0) copyplane.FlipVert();
|
||||
floorplane = ©plane;
|
||||
break;
|
||||
}
|
||||
}
|
||||
floorplane = P_FindFloorPlane(floorsector, x, y, floorz);
|
||||
#endif
|
||||
|
||||
if (floorplane->c < STEEPSLOPE &&
|
||||
floorplane->ZatPoint (x, y) <= floorz)
|
||||
if (floorplane.c < STEEPSLOPE &&
|
||||
floorplane.ZatPoint (x, y) <= floorz)
|
||||
{
|
||||
const msecnode_t *node;
|
||||
bool dopush = true;
|
||||
|
||||
if (floorplane->c > STEEPSLOPE*2/3)
|
||||
if (floorplane.c > STEEPSLOPE*2/3)
|
||||
{
|
||||
for (node = touching_sectorlist; node; node = node->m_tnext)
|
||||
{
|
||||
const sector_t *sec = node->m_sector;
|
||||
if (sec->floorplane.c >= STEEPSLOPE)
|
||||
{
|
||||
if (floorplane->ZatPoint (x, y) >= z - MaxStepHeight)
|
||||
if (floorplane.ZatPoint (x, y) >= z - MaxStepHeight)
|
||||
{
|
||||
dopush = false;
|
||||
break;
|
||||
|
|
@ -3233,8 +3168,8 @@ void AActor::Tick ()
|
|||
}
|
||||
if (dopush)
|
||||
{
|
||||
velx += floorplane->a;
|
||||
vely += floorplane->b;
|
||||
velx += floorplane.a;
|
||||
vely += floorplane.b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3331,6 +3266,18 @@ void AActor::Tick ()
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for poison damage, but only once per PoisonPeriod tics (or once per second if none).
|
||||
if (PoisonDurationReceived && (level.time % (PoisonPeriodReceived ? PoisonPeriodReceived : TICRATE) == 0))
|
||||
{
|
||||
P_DamageMobj(this, NULL, Poisoner, PoisonDamageReceived, NAME_Poison, 0);
|
||||
|
||||
--PoisonDurationReceived;
|
||||
|
||||
// Must clear damage when duration is done, otherwise it
|
||||
// could be added to with ADDITIVEPOISONDAMAGE.
|
||||
if (!PoisonDurationReceived) PoisonDamageReceived = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// cycle through states, calling action functions at transitions
|
||||
|
|
@ -3495,6 +3442,7 @@ bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash)
|
|||
return false; // we did the splash ourselves
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_SpawnMobj
|
||||
|
|
@ -3517,6 +3465,17 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t
|
|||
|
||||
actor = static_cast<AActor *>(const_cast<PClassActor *>(type)->CreateNew ());
|
||||
|
||||
// Set default dialogue
|
||||
actor->ConversationRoot = GetConversation(actor->GetClass()->TypeName);
|
||||
if (actor->ConversationRoot != -1)
|
||||
{
|
||||
actor->Conversation = StrifeDialogues[actor->ConversationRoot];
|
||||
}
|
||||
else
|
||||
{
|
||||
actor->Conversation = NULL;
|
||||
}
|
||||
|
||||
actor->x = actor->PrevX = ix;
|
||||
actor->y = actor->PrevY = iy;
|
||||
actor->z = actor->PrevZ = iz;
|
||||
|
|
@ -3663,7 +3622,10 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t
|
|||
{
|
||||
level.total_items++;
|
||||
}
|
||||
screen->StateChanged(actor);
|
||||
if (screen != NULL)
|
||||
{
|
||||
screen->StateChanged(actor);
|
||||
}
|
||||
return actor;
|
||||
}
|
||||
|
||||
|
|
@ -3985,7 +3947,6 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer)
|
|||
|
||||
// [GRB] Reset skin
|
||||
p->userinfo.skin = R_FindSkin (skins[p->userinfo.skin].name, p->CurrentPlayerClass);
|
||||
StatusBar->SetFace (&skins[p->userinfo.skin]);
|
||||
|
||||
|
||||
if (!(mobj->flags2 & MF2_DONTTRANSLATE))
|
||||
|
|
@ -4314,6 +4275,11 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
|
|||
mthing->args[0] = mthing->type - 14000;
|
||||
mthing->type = 14065;
|
||||
}
|
||||
else if (mthing->type >= 14101 && mthing->type <= 14164)
|
||||
{
|
||||
mthing->args[0] = mthing->type - 14100;
|
||||
mthing->type = 14165;
|
||||
}
|
||||
// find which type to spawn
|
||||
i = DoomEdMap.FindType (mthing->type);
|
||||
|
||||
|
|
@ -4430,6 +4396,19 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
|
|||
mobj->AddToHash ();
|
||||
|
||||
mobj->PrevAngle = mobj->angle = (DWORD)((mthing->angle * UCONST64(0x100000000)) / 360);
|
||||
|
||||
// Check if this actor's mapthing has a conversation defined
|
||||
if (mthing->Conversation > 0)
|
||||
{
|
||||
// Make sure that this does not partially overwrite the default dialogue settings.
|
||||
int root = GetConversation(mthing->Conversation);
|
||||
if (root != -1)
|
||||
{
|
||||
mobj->ConversationRoot = root;
|
||||
mobj->Conversation = StrifeDialogues[mobj->ConversationRoot];
|
||||
}
|
||||
}
|
||||
|
||||
mobj->BeginPlay ();
|
||||
if (!(mobj->ObjectFlags & OF_EuthanizeMe))
|
||||
{
|
||||
|
|
@ -4522,7 +4501,7 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc
|
|||
if (bloodcls!=NULL && bloodtype <= 1)
|
||||
{
|
||||
z += pr_spawnblood.Random2 () << 10;
|
||||
th = Spawn (bloodcls, x, y, z, ALLOW_REPLACE);
|
||||
th = Spawn (bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement
|
||||
th->velz = FRACUNIT*2;
|
||||
th->angle = dir;
|
||||
if (gameinfo.gametype & GAME_DoomChex)
|
||||
|
|
@ -4585,7 +4564,7 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
|
|||
{
|
||||
AActor *mo;
|
||||
|
||||
mo = Spawn(bloodcls, x, y, z, ALLOW_REPLACE);
|
||||
mo = Spawn(bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement
|
||||
mo->target = originator;
|
||||
mo->velx = pr_splatter.Random2 () << 10;
|
||||
mo->vely = pr_splatter.Random2 () << 10;
|
||||
|
|
@ -4626,7 +4605,7 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
|
|||
x += ((pr_splat()-128)<<11);
|
||||
y += ((pr_splat()-128)<<11);
|
||||
|
||||
mo = Spawn (bloodcls, x, y, z, ALLOW_REPLACE);
|
||||
mo = Spawn (bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement
|
||||
mo->target = originator;
|
||||
|
||||
// colorize the blood!
|
||||
|
|
@ -4665,7 +4644,7 @@ void P_RipperBlood (AActor *mo, AActor *bleeder)
|
|||
if (bloodcls!=NULL && bloodtype <= 1)
|
||||
{
|
||||
AActor *th;
|
||||
th = Spawn (bloodcls, x, y, z, ALLOW_REPLACE);
|
||||
th = Spawn (bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement
|
||||
if (gameinfo.gametype == GAME_Heretic)
|
||||
th->flags |= MF_NOGRAVITY;
|
||||
th->velx = mo->velx >> 1;
|
||||
|
|
@ -4728,6 +4707,20 @@ bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z
|
|||
// don't splash above the object
|
||||
if (checkabove && z > thing->z + (thing->height >> 1)) return false;
|
||||
|
||||
#if 0 // needs some rethinking before activation
|
||||
|
||||
// This avoids spawning splashes on invisible self referencing sectors.
|
||||
// For network consistency do this only in single player though because
|
||||
// it is not guaranteed that all players have GL nodes loaded.
|
||||
if (!multiplayer && thing->subsector->sector != thing->subsector->render_sector)
|
||||
{
|
||||
fixed_t zs = thing->subsector->sector->floorplane.ZatPoint(x, y);
|
||||
fixed_t zr = thing->subsector->render_sector->floorplane.ZatPoint(x, y);
|
||||
|
||||
if (zs > zr && thing->z >= zs) return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _3DFLOORS
|
||||
for(unsigned int i=0;i<sec->e->XFloor.ffloors.Size();i++)
|
||||
{
|
||||
|
|
@ -4846,7 +4839,7 @@ bool P_HitFloor (AActor *thing)
|
|||
{
|
||||
thing->flags6 &= ~MF6_ARMED; // Disarm
|
||||
P_DamageMobj (thing, NULL, NULL, thing->health, NAME_Crush, DMG_FORCED); // kill object
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (thing->flags2 & MF2_FLOATBOB || thing->flags3 & MF3_DONTSPLASH)
|
||||
|
|
@ -4972,7 +4965,7 @@ bool P_CheckMissileSpawn (AActor* th)
|
|||
bool MBFGrenade = (!(th->flags & MF_MISSILE) || (th->BounceFlags & BOUNCE_MBF));
|
||||
|
||||
// killough 3/15/98: no dropoff (really = don't care for missiles)
|
||||
if (!(P_TryMove (th, th->x, th->y, false, false, tm)))
|
||||
if (!(P_TryMove (th, th->x, th->y, false, NULL, tm)))
|
||||
{
|
||||
// [RH] Don't explode ripping missiles that spawn inside something
|
||||
if (th->BlockingMobj == NULL || !(th->flags2 & MF2_RIP) || (th->BlockingMobj->flags5 & MF5_DONTRIP))
|
||||
|
|
@ -5456,10 +5449,10 @@ int AActor::DoSpecialDamage (AActor *target, int damage)
|
|||
{
|
||||
if (target->player)
|
||||
{
|
||||
int poisondamage = GetClass()->PoisonDamage;
|
||||
if (poisondamage > 0)
|
||||
// Only do this for old style poison damage.
|
||||
if (PoisonDamage > 0 && PoisonDuration == INT_MIN)
|
||||
{
|
||||
P_PoisonPlayer (target->player, this, this->target, poisondamage);
|
||||
P_PoisonPlayer (target->player, this, this->target, PoisonDamage);
|
||||
damage >>= 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -5605,9 +5598,26 @@ bool AActor::IsSentient() const
|
|||
|
||||
const char *AActor::GetTag(const char *def) const
|
||||
{
|
||||
if (Tag != NAME_None) return Tag.GetChars();
|
||||
else if (def) return def;
|
||||
else return GetClass()->TypeName.GetChars();
|
||||
if (Tag != NAME_None)
|
||||
{
|
||||
const char *tag = Tag.GetChars();
|
||||
if (tag[0] == '$')
|
||||
{
|
||||
return GStrings(tag + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
else if (def)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetClass()->TypeName.GetChars();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue