mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 14:51:46 +00:00
- added RandomSpawner update from Gez's experimental build.
- added thing activation types for BUMPSPECIAL and USESPECIAL. Also added a new ClearSpecial flag to the activation type. - added MBF's code for dogs jumping down, controlled by the MF6_JUMPDOWN flag. SVN r1835 (trunk)
This commit is contained in:
parent
f2a122e076
commit
5910d90a19
9 changed files with 224 additions and 83 deletions
|
@ -1,4 +1,9 @@
|
|||
September 15, 2009 (Changes by Graf Zahl)
|
||||
- added RandomSpawner update from Gez's experimental build.
|
||||
- added thing activation types for BUMPSPECIAL and USESPECIAL. Also added
|
||||
a new ClearSpecial flag to the activation type.
|
||||
- added MBF's code for dogs jumping down, controlled by the MF6_JUMPDOWN
|
||||
flag.
|
||||
- fixed: pr_bounce was declared statically in o_mobj.cpp and redeclared externally
|
||||
in p_map.cpp resulting in a CRC conflict.
|
||||
- fixed: The Dehacked flags parser fix from May 31 (r1624) was undone by
|
||||
|
|
|
@ -441,6 +441,7 @@ enum EThingSpecialActivationType
|
|||
THINGSPEC_TriggerTargets = 4, // The trigger changes its target to the thing
|
||||
THINGSPEC_MonsterTrigger = 8, // The thing can be triggered by a monster
|
||||
THINGSPEC_MissileTrigger = 16, // The thing can be triggered by a projectile
|
||||
THINGSPEC_ClearSpecial = 32, // Clears special after successful activation
|
||||
};
|
||||
|
||||
// [RH] Like msecnode_t, but for the blockmap
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/*
|
||||
** a_randomspawner.cpp
|
||||
** A thing that randomly spawns one item in a list of many, before disappearing.
|
||||
** bouncecount is used to keep track of recursions (so as to prevent infinite loops).
|
||||
** Species is used to store the index of the spawned actor's name.
|
||||
*/
|
||||
|
||||
#include "actor.h"
|
||||
|
@ -21,14 +23,16 @@ class ARandomSpawner : public AActor
|
|||
{
|
||||
DECLARE_CLASS (ARandomSpawner, AActor)
|
||||
|
||||
void PostBeginPlay()
|
||||
// To handle "RandomSpawning" missiles, the code has to be split in two parts.
|
||||
// If the following code is not done in BeginPlay, missiles will use the
|
||||
// random spawner's velocity (0...) instead of their own.
|
||||
void BeginPlay()
|
||||
{
|
||||
AActor *newmobj = NULL;
|
||||
FDropItem *di; // di will be our drop item list iterator
|
||||
FDropItem *drop; // while drop stays as the reference point.
|
||||
int n=0;
|
||||
|
||||
Super::PostBeginPlay();
|
||||
Super::BeginPlay();
|
||||
drop = di = GetDropItems();
|
||||
if (di != NULL)
|
||||
{
|
||||
|
@ -46,7 +50,7 @@ class ARandomSpawner : public AActor
|
|||
// Take a random number...
|
||||
n = pr_randomspawn(n);
|
||||
// And iterate in the array up to the random number chosen.
|
||||
while (n > 0)
|
||||
while (n > -1)
|
||||
{
|
||||
if (di->Name != NAME_None)
|
||||
{
|
||||
|
@ -55,64 +59,109 @@ class ARandomSpawner : public AActor
|
|||
}
|
||||
}
|
||||
// So now we can spawn the dropped item.
|
||||
if (special1 >= MAX_RANDOMSPAWNERS_RECURSION) // Prevents infinite recursions
|
||||
if (bouncecount >= MAX_RANDOMSPAWNERS_RECURSION) // Prevents infinite recursions
|
||||
{
|
||||
Spawn("Unknown", x, y, z, NO_REPLACE); // Show that there's a problem.
|
||||
Destroy(); return;
|
||||
}
|
||||
else if (pr_randomspawn() <= di->probability) // prob 255 = always spawn, prob 0 = never spawn.
|
||||
{
|
||||
newmobj = Spawn(di->Name, x, y, z, ALLOW_REPLACE);
|
||||
// copy everything relevant
|
||||
newmobj->SpawnAngle = newmobj->angle = angle;
|
||||
newmobj->special = special;
|
||||
newmobj->args[0] = args[0];
|
||||
newmobj->args[1] = args[1];
|
||||
newmobj->args[2] = args[2];
|
||||
newmobj->args[3] = args[3];
|
||||
newmobj->args[4] = args[4];
|
||||
newmobj->SpawnFlags = SpawnFlags;
|
||||
newmobj->HandleSpawnFlags();
|
||||
newmobj->tid = tid;
|
||||
newmobj->AddToHash();
|
||||
newmobj->velx = velx;
|
||||
newmobj->vely = vely;
|
||||
newmobj->velz = velz;
|
||||
newmobj->master = master; // For things such as DamageMaster/DamageChildren, transfer mastery.
|
||||
newmobj->target = target;
|
||||
newmobj->tracer = tracer;
|
||||
newmobj->CopyFriendliness(this, false);
|
||||
if (!(flags & MF_DROPPED)) newmobj->flags &= ~MF_DROPPED;
|
||||
|
||||
// Handle special altitude flags
|
||||
if (newmobj->flags & MF_SPAWNCEILING)
|
||||
// Handle replacement here so as to get the proper speed and flags for missiles
|
||||
const PClass * cls; PClass * rep;
|
||||
cls = PClass::FindClass(di->Name);
|
||||
if (cls) rep = cls->ActorInfo->GetReplacement()->Class;
|
||||
if (rep) cls = rep;
|
||||
if (cls)
|
||||
{
|
||||
newmobj->z = newmobj->ceilingz - newmobj->height;
|
||||
Species = cls->TypeName;
|
||||
AActor * defmobj = GetDefaultByType(cls);
|
||||
this->Speed = defmobj->Speed;
|
||||
this->flags |= (defmobj->flags & MF_MISSILE);
|
||||
this->flags2 |= (defmobj->flags2 & MF2_SEEKERMISSILE);
|
||||
this->flags4 |= (defmobj->flags4 & MF4_SPECTRAL);
|
||||
}
|
||||
else if (newmobj->flags2 & MF2_SPAWNFLOAT)
|
||||
{
|
||||
fixed_t space = newmobj->ceilingz - newmobj->height - newmobj->floorz;
|
||||
if (space > 48*FRACUNIT)
|
||||
{
|
||||
space -= 40*FRACUNIT;
|
||||
newmobj->z = MulScale8 (space, pr_randomspawn()) + newmobj->floorz + 40*FRACUNIT;
|
||||
}
|
||||
}
|
||||
|
||||
// Special1 is used to count how many recursions we're in.
|
||||
if (newmobj->IsKindOf(PClass::FindClass("RandomSpawner")))
|
||||
newmobj->special1 = ++special1;
|
||||
|
||||
else Species = NAME_None;
|
||||
}
|
||||
}
|
||||
if ((newmobj != NULL) && ((newmobj->flags4 & MF4_BOSSDEATH) || (newmobj->flags2 & MF2_BOSS)))
|
||||
this->target = newmobj; // If the spawned actor has either of those flags, it's a boss.
|
||||
}
|
||||
|
||||
// The second half of random spawning. Now that the spawner is initialized, the
|
||||
// real actor can be created. If the following code were in BeginPlay instead,
|
||||
// missiles would not have yet obtained certain information that is absolutely
|
||||
// necessary to them -- such as their source and destination.
|
||||
void PostBeginPlay()
|
||||
{
|
||||
AActor * newmobj = NULL;
|
||||
bool boss = false;
|
||||
if (Species == NAME_None) { Destroy(); return; }
|
||||
const PClass * cls = PClass::FindClass(Species);
|
||||
if (this->flags & MF_MISSILE && target && target->target) // Attempting to spawn a missile.
|
||||
{
|
||||
if ((tracer == NULL) && (flags2 & MF2_SEEKERMISSILE)) tracer = target->target;
|
||||
newmobj = P_SpawnMissileXYZ(x, y, z, target, target->target, cls, false);
|
||||
}
|
||||
else newmobj = Spawn(cls, x, y, z, NO_REPLACE);
|
||||
if (newmobj != NULL)
|
||||
{
|
||||
// copy everything relevant
|
||||
newmobj->SpawnAngle = newmobj->angle = angle;
|
||||
newmobj->special = special;
|
||||
newmobj->args[0] = args[0];
|
||||
newmobj->args[1] = args[1];
|
||||
newmobj->args[2] = args[2];
|
||||
newmobj->args[3] = args[3];
|
||||
newmobj->args[4] = args[4];
|
||||
newmobj->SpawnFlags = SpawnFlags;
|
||||
newmobj->HandleSpawnFlags();
|
||||
newmobj->tid = tid;
|
||||
newmobj->AddToHash();
|
||||
newmobj->velx = velx;
|
||||
newmobj->vely = vely;
|
||||
newmobj->velz = velz;
|
||||
newmobj->master = master; // For things such as DamageMaster/DamageChildren, transfer mastery.
|
||||
newmobj->target = target;
|
||||
newmobj->tracer = tracer;
|
||||
newmobj->CopyFriendliness(this, false);
|
||||
// This handles things such as projectiles with the MF4_SPECTRAL flag that have
|
||||
// a health set to -2 after spawning, for internal reasons.
|
||||
if (health != SpawnHealth()) newmobj->health = health;
|
||||
if (!(flags & MF_DROPPED)) newmobj->flags &= ~MF_DROPPED;
|
||||
// Handle special altitude flags
|
||||
if (newmobj->flags & MF_SPAWNCEILING)
|
||||
{
|
||||
newmobj->z = newmobj->ceilingz - newmobj->height;
|
||||
}
|
||||
else if (newmobj->flags2 & MF2_SPAWNFLOAT)
|
||||
{
|
||||
fixed_t space = newmobj->ceilingz - newmobj->height - newmobj->floorz;
|
||||
if (space > 48*FRACUNIT)
|
||||
{
|
||||
space -= 40*FRACUNIT;
|
||||
newmobj->z = MulScale8 (space, pr_randomspawn()) + newmobj->floorz + 40*FRACUNIT;
|
||||
}
|
||||
}
|
||||
if (newmobj->flags & MF_MISSILE)
|
||||
P_CheckMissileSpawn(newmobj);
|
||||
// Bouncecount is used to count how many recursions we're in.
|
||||
if (newmobj->IsKindOf(PClass::FindClass("RandomSpawner")))
|
||||
newmobj->bouncecount = ++bouncecount;
|
||||
// If the spawned actor has either of those flags, it's a boss.
|
||||
if ((newmobj->flags4 & MF4_BOSSDEATH) || (newmobj->flags2 & MF2_BOSS))
|
||||
boss = true;
|
||||
// If a replaced actor has either of those same flags, it's also a boss.
|
||||
AActor * rep = GetDefaultByType(GetClass()->ActorInfo->GetReplacee()->Class);
|
||||
if (rep && (rep->flags4 & MF4_BOSSDEATH) || (rep->flags2 & MF2_BOSS))
|
||||
boss = true;
|
||||
}
|
||||
if (boss) this->tracer = newmobj;
|
||||
else Destroy(); // "else" because a boss-replacing spawner must wait until it can call A_BossDeath.
|
||||
}
|
||||
|
||||
void Tick() // This function is needed for handling boss replacers
|
||||
{
|
||||
Super::Tick();
|
||||
if (target == NULL || target->health <= 0)
|
||||
if (tracer == NULL || tracer->health <= 0)
|
||||
{
|
||||
health = 0;
|
||||
CALL_ACTION(A_BossDeath, this);
|
||||
Destroy();
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ static FRandom pr_dropitem ("DropItem");
|
|||
static FRandom pr_look2 ("LookyLooky");
|
||||
static FRandom pr_look3 ("IGotHooky");
|
||||
static FRandom pr_slook ("SlooK");
|
||||
static FRandom pr_dropoff ("Dropoff");
|
||||
|
||||
static FRandom pr_skiptarget("SkipTarget");
|
||||
|
||||
|
@ -380,6 +381,7 @@ bool P_Move (AActor *actor)
|
|||
int speed = actor->Speed;
|
||||
int movefactor = ORIG_FRICTION_FACTOR;
|
||||
int friction = ORIG_FRICTION;
|
||||
int dropoff = 0;
|
||||
|
||||
if (actor->flags2 & MF2_BLASTED)
|
||||
{
|
||||
|
@ -410,23 +412,18 @@ bool P_Move (AActor *actor)
|
|||
if ((unsigned)actor->movedir >= 8)
|
||||
I_Error ("Weird actor->movedir!");
|
||||
|
||||
speed = actor->Speed;
|
||||
|
||||
#if 0 // todo
|
||||
|
||||
// killough 10/98: allow dogs to drop off of taller ledges sometimes.
|
||||
// dropoff==1 means always allow it, dropoff==2 means only up to 128 high,
|
||||
// and only if the target is immediately on the other side of the line.
|
||||
AActor *target = actor->target;
|
||||
|
||||
if (actor->flags6 & MF6_JUMPDOWN && target &&
|
||||
if ((actor->flags6 & MF6_JUMPDOWN) && target &&
|
||||
!(target->IsFriend(actor)) &&
|
||||
P_AproxDistance(actor->x - target->x,
|
||||
actor->y - target->y) < FRACUNIT*144 &&
|
||||
P_Random(pr_dropoff) < 235)
|
||||
P_AproxDistance(actor->x - target->x, actor->y - target->y) < FRACUNIT*144 &&
|
||||
pr_dropoff() < 235)
|
||||
{
|
||||
dropoff = 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
// [RH] I'm not so sure this is such a good idea
|
||||
// [GZ] That's why it's compat-optioned.
|
||||
|
@ -479,12 +476,12 @@ bool P_Move (AActor *actor)
|
|||
try_ok = true;
|
||||
for(int i=1; i < steps; i++)
|
||||
{
|
||||
try_ok = P_TryMove(actor, origx + Scale(deltax, i, steps), origy + Scale(deltay, i, steps), false, false, tm);
|
||||
try_ok = P_TryMove(actor, origx + Scale(deltax, i, steps), origy + Scale(deltay, i, steps), dropoff, false, tm);
|
||||
if (!try_ok) break;
|
||||
}
|
||||
|
||||
// killough 3/15/98: don't jump over dropoffs:
|
||||
if (try_ok) try_ok = P_TryMove (actor, tryx, tryy, false, false, tm);
|
||||
if (try_ok) try_ok = P_TryMove (actor, tryx, tryy, dropoff, false, tm);
|
||||
|
||||
// [GrafZahl] Interpolating monster movement as it is done here just looks bad
|
||||
// so make it switchable!
|
||||
|
|
|
@ -377,8 +377,8 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm);
|
|||
bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y);
|
||||
AActor *P_CheckOnmobj (AActor *thing);
|
||||
void P_FakeZMovement (AActor *mo);
|
||||
bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, bool dropoff, const secplane_t * onfloor, FCheckPosition &tm);
|
||||
bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, bool dropoff, const secplane_t * onfloor = NULL);
|
||||
bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor, FCheckPosition &tm);
|
||||
bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor = NULL);
|
||||
bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y);
|
||||
void P_ApplyTorque(AActor *mo);
|
||||
bool P_TeleportMove (AActor* thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag); // [RH] Added z and telefrag parameters
|
||||
|
|
|
@ -834,6 +834,29 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
|
|||
P_DamageMobj (thing, NULL, NULL, thing->health, NAME_None, DMG_FORCED); // kill object
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for MF6_BUMPSPECIAL
|
||||
// By default, only players can activate things by bumping into them
|
||||
if ((thing->flags6 & MF6_BUMPSPECIAL))
|
||||
{
|
||||
if (((tm.thing->player != NULL)
|
||||
|| ((thing->activationtype & THINGSPEC_MonsterTrigger) && (thing->flags3 & MF3_ISMONSTER))
|
||||
|| ((thing->activationtype & THINGSPEC_MissileTrigger) && (thing->flags & MF_MISSILE))
|
||||
))
|
||||
{ // Target switching mechanism
|
||||
if (thing->activationtype & THINGSPEC_ThingTargets) thing->target = tm.thing;
|
||||
if (thing->activationtype & THINGSPEC_TriggerTargets) tm.thing->target = thing;
|
||||
// Run the special
|
||||
|
||||
int res = LineSpecials[thing->special] (NULL,
|
||||
((thing->activationtype & THINGSPEC_ThingActs) ? thing : tm.thing), // Who triggers?
|
||||
false, thing->args[0], thing->args[1], thing->args[2], thing->args[3], thing->args[4]);
|
||||
|
||||
if (thing->activationtype & THINGSPEC_ClearSpecial && res) thing->special = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Check for skulls slamming into things
|
||||
if (tm.thing->flags & MF_SKULLFLY)
|
||||
{
|
||||
|
@ -860,13 +883,6 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
// Check for players touching a thing with MF6_BUMPSPECIAL
|
||||
// A blind recreation of what the Skulltag code is probably like.
|
||||
if (tm.thing->player && (thing->flags6 & MF6_BUMPSPECIAL) && thing->special)
|
||||
{
|
||||
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 or non-solid MBF bouncer
|
||||
if (tm.thing->flags & MF_MISSILE || ((tm.thing->BounceFlags & BOUNCE_MBF) && !(tm.thing->flags & MF_SOLID)))
|
||||
{
|
||||
|
@ -1537,7 +1553,7 @@ static void CheckForPushSpecial (line_t *line, int side, AActor *mobj)
|
|||
// crossing special lines unless MF_TELEPORT is set.
|
||||
//
|
||||
bool P_TryMove (AActor *thing, fixed_t x, fixed_t y,
|
||||
bool dropoff, // killough 3/15/98: allow dropoff as option
|
||||
int dropoff, // killough 3/15/98: allow dropoff as option
|
||||
const secplane_t *onfloor, // [RH] Let P_TryMove keep the thing on the floor
|
||||
FCheckPosition &tm)
|
||||
{
|
||||
|
@ -1667,6 +1683,13 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y,
|
|||
dropoff = false;
|
||||
}
|
||||
|
||||
if (dropoff==2 && // large jump down (e.g. dogs)
|
||||
(tm.floorz-tm.dropoffz > 128*FRACUNIT || thing->target == NULL || thing->target->z >tm.dropoffz))
|
||||
{
|
||||
dropoff = false;
|
||||
}
|
||||
|
||||
|
||||
// killough 3/15/98: Allow certain objects to drop off
|
||||
if ((!dropoff && !(thing->flags & (MF_DROPOFF|MF_FLOAT|MF_MISSILE))) || (thing->flags5&MF5_NODROPOFF))
|
||||
{
|
||||
|
@ -1894,7 +1917,7 @@ pushline:
|
|||
}
|
||||
|
||||
bool P_TryMove (AActor *thing, fixed_t x, fixed_t y,
|
||||
bool dropoff, // killough 3/15/98: allow dropoff as option
|
||||
int dropoff, // killough 3/15/98: allow dropoff as option
|
||||
const secplane_t *onfloor) // [RH] Let P_TryMove keep the thing on the floor
|
||||
{
|
||||
FCheckPosition tm;
|
||||
|
@ -3745,12 +3768,20 @@ bool P_UseTraverse(AActor *usething, fixed_t endx, fixed_t endy, bool &foundline
|
|||
// Check thing
|
||||
|
||||
// Check for puzzle item use or USESPECIAL flag
|
||||
// Extended to use the same activationtype mechanism as BUMPSPECIAL does
|
||||
if (in->d.thing->flags5 & MF5_USESPECIAL || in->d.thing->special == UsePuzzleItem)
|
||||
{
|
||||
if (LineSpecials[in->d.thing->special] (NULL, usething, false,
|
||||
{ // Target switching mechanism
|
||||
if (in->d.thing->activationtype & THINGSPEC_ThingTargets) in->d.thing->target = usething;
|
||||
if (in->d.thing->activationtype & THINGSPEC_TriggerTargets) usething->target = in->d.thing;
|
||||
// Run the special
|
||||
if (LineSpecials[in->d.thing->special] (NULL, // Who triggers?
|
||||
((in->d.thing->activationtype & THINGSPEC_ThingActs) ? in->d.thing : usething), false,
|
||||
in->d.thing->args[0], in->d.thing->args[1], in->d.thing->args[2],
|
||||
in->d.thing->args[3], in->d.thing->args[4]))
|
||||
{
|
||||
if (in->d.thing->activationtype & THINGSPEC_ClearSpecial) in->d.thing->special = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Dead things can't talk.
|
||||
if (in->d.thing->health <= 0)
|
||||
|
|
|
@ -395,18 +395,14 @@ void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static int ParseMorphStyle (FScanner &sc)
|
||||
struct FParseValue
|
||||
{
|
||||
static const char * morphstyles[]={
|
||||
"MRF_ADDSTAMINA", "MRF_FULLHEALTH", "MRF_UNDOBYTOMEOFPOWER", "MRF_UNDOBYCHAOSDEVICE",
|
||||
"MRF_FAILNOTELEFRAG", "MRF_FAILNOLAUGH", "MRF_WHENINVULNERABLE", "MRF_LOSEACTUALWEAPON",
|
||||
"MRF_NEWTIDBEHAVIOUR", "MRF_UNDOBYDEATH", "MRF_UNDOBYDEATHFORCED", "MRF_UNDOBYDEATHSAVES", NULL};
|
||||
|
||||
static const int morphstyle_values[]={
|
||||
MORPH_ADDSTAMINA, MORPH_FULLHEALTH, MORPH_UNDOBYTOMEOFPOWER, MORPH_UNDOBYCHAOSDEVICE,
|
||||
MORPH_FAILNOTELEFRAG, MORPH_FAILNOLAUGH, MORPH_WHENINVULNERABLE, MORPH_LOSEACTUALWEAPON,
|
||||
MORPH_NEWTIDBEHAVIOUR, MORPH_UNDOBYDEATH, MORPH_UNDOBYDEATHFORCED, MORPH_UNDOBYDEATHSAVES};
|
||||
const char *Name;
|
||||
int Flag;
|
||||
};
|
||||
|
||||
int ParseFlagExpressionString(FScanner &sc, const FParseValue *vals)
|
||||
{
|
||||
// May be given flags by number...
|
||||
if (sc.CheckNumber())
|
||||
{
|
||||
|
@ -422,7 +418,7 @@ static int ParseMorphStyle (FScanner &sc)
|
|||
do
|
||||
{
|
||||
sc.MustGetString();
|
||||
style |= morphstyle_values[sc.MustMatchString(morphstyles)];
|
||||
style |= vals[sc.MustMatchString(&vals->Name, sizeof (*vals))].Flag;
|
||||
}
|
||||
while (sc.CheckString("|"));
|
||||
if (gotparen)
|
||||
|
@ -433,6 +429,46 @@ static int ParseMorphStyle (FScanner &sc)
|
|||
return style;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int ParseMorphStyle (FScanner &sc)
|
||||
{
|
||||
static const FParseValue morphstyles[]={
|
||||
{ "MRF_ADDSTAMINA", MORPH_ADDSTAMINA},
|
||||
{ "MRF_FULLHEALTH", MORPH_FULLHEALTH},
|
||||
{ "MRF_UNDOBYTOMEOFPOWER", MORPH_UNDOBYTOMEOFPOWER},
|
||||
{ "MRF_UNDOBYCHAOSDEVICE", MORPH_UNDOBYCHAOSDEVICE},
|
||||
{ "MRF_FAILNOTELEFRAG", MORPH_FAILNOTELEFRAG},
|
||||
{ "MRF_FAILNOLAUGH", MORPH_FAILNOLAUGH},
|
||||
{ "MRF_WHENINVULNERABLE", MORPH_WHENINVULNERABLE},
|
||||
{ "MRF_LOSEACTUALWEAPON", MORPH_LOSEACTUALWEAPON},
|
||||
{ "MRF_NEWTIDBEHAVIOUR", MORPH_NEWTIDBEHAVIOUR},
|
||||
{ "MRF_UNDOBYDEATH", MORPH_UNDOBYDEATH},
|
||||
{ "MRF_UNDOBYDEATHFORCED", MORPH_UNDOBYDEATHFORCED},
|
||||
{ "MRF_UNDOBYDEATHSAVES", MORPH_UNDOBYDEATHSAVES},
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
return ParseFlagExpressionString(sc, morphstyles);
|
||||
}
|
||||
|
||||
static int ParseThingActivation (FScanner &sc)
|
||||
{
|
||||
static const FParseValue activationstyles[]={
|
||||
|
||||
{ "THINGSPEC_Default", THINGSPEC_Default},
|
||||
{ "THINGSPEC_ThingActs", THINGSPEC_ThingActs},
|
||||
{ "THINGSPEC_ThingTargets", THINGSPEC_ThingTargets},
|
||||
{ "THINGSPEC_TriggerTargets", THINGSPEC_TriggerTargets},
|
||||
{ "THINGSPEC_MonsterTrigger", THINGSPEC_MonsterTrigger},
|
||||
{ "THINGSPEC_MissileTrigger", THINGSPEC_MissileTrigger},
|
||||
{ "THINGSPEC_ClearSpecial", THINGSPEC_ClearSpecial},
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
return ParseFlagExpressionString(sc, activationstyles);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// For getting a state address from the parent
|
||||
|
|
|
@ -1057,6 +1057,16 @@ DEFINE_PROPERTY(projectile, 0, Actor)
|
|||
if (gameinfo.gametype&GAME_Raven) defaults->flags5|=MF5_BLOODSPLATTER;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(activation, N, Actor)
|
||||
{
|
||||
// How the thing behaves when activated with MF5_USESPECIAL or MF6_BUMPSPECIAL
|
||||
PROP_INT_PARM(val, 0);
|
||||
defaults->activationtype = val;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Special inventory properties
|
||||
|
|
|
@ -61,6 +61,18 @@ const int MRF_UNDOBYDEATHSAVES = 2048;
|
|||
const int RGF_SILENT = 1;
|
||||
const int RGF_NOPIERCING = 2;
|
||||
|
||||
enum
|
||||
{
|
||||
THINGSPEC_Default = 0,
|
||||
THINGSPEC_ThingActs = 1,
|
||||
THINGSPEC_ThingTargets = 2,
|
||||
THINGSPEC_TriggerTargets = 4,
|
||||
THINGSPEC_MonsterTrigger = 8,
|
||||
THINGSPEC_MissileTrigger = 16,
|
||||
THINGSPEC_ClearSpecial = 32,
|
||||
};
|
||||
|
||||
|
||||
// constants for A_PlaySound
|
||||
enum
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue