mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-16 01:02:03 +00:00
- Fixed: SectorDamage did not work with 3D floors.
SVN r3594 (trunk)
This commit is contained in:
parent
142a15b9c6
commit
3523e4f24a
3 changed files with 79 additions and 55 deletions
|
@ -97,13 +97,6 @@ FRandom pr_acs ("ACS");
|
|||
#define NOT_FLOOR 8
|
||||
#define NOT_CEILING 16
|
||||
|
||||
// Flags for SectorDamage
|
||||
|
||||
#define DAMAGE_PLAYERS 1
|
||||
#define DAMAGE_NONPLAYERS 2
|
||||
#define DAMAGE_IN_AIR 4
|
||||
#define DAMAGE_SUBCLASSES_PROTECT 8
|
||||
|
||||
struct CallReturn
|
||||
{
|
||||
CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, bool discard, FString &str)
|
||||
|
@ -6970,53 +6963,7 @@ int DLevelScript::RunScript ()
|
|||
int flags = STACK(1);
|
||||
sp -= 5;
|
||||
|
||||
int secnum = -1;
|
||||
|
||||
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
|
||||
{
|
||||
AActor *actor, *next;
|
||||
sector_t *sec = §ors[secnum];
|
||||
|
||||
for (actor = sec->thinglist; actor != NULL; actor = next)
|
||||
{
|
||||
next = actor->snext;
|
||||
|
||||
if (!(actor->flags & MF_SHOOTABLE))
|
||||
continue;
|
||||
|
||||
if (!(flags & DAMAGE_NONPLAYERS) && actor->player == NULL)
|
||||
continue;
|
||||
|
||||
if (!(flags & DAMAGE_PLAYERS) && actor->player != NULL)
|
||||
continue;
|
||||
|
||||
if (!(flags & DAMAGE_IN_AIR) && actor->z != sec->floorplane.ZatPoint (actor->x, actor->y) && !actor->waterlevel)
|
||||
continue;
|
||||
|
||||
if (protectClass != NULL)
|
||||
{
|
||||
if (!(flags & DAMAGE_SUBCLASSES_PROTECT))
|
||||
{
|
||||
if (actor->FindInventory (protectClass))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
AInventory *item;
|
||||
|
||||
for (item = actor->Inventory; item != NULL; item = item->Inventory)
|
||||
{
|
||||
if (item->IsKindOf (protectClass))
|
||||
break;
|
||||
}
|
||||
if (item != NULL)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
P_DamageMobj (actor, NULL, NULL, amount, type);
|
||||
}
|
||||
}
|
||||
P_SectorDamage(tag, amount, type, protectClass, flags);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -585,6 +585,77 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
|
|||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_SectorDamage
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
static void DoSectorDamage(AActor *actor, sector_t *sec, int amount, FName type, const PClass *protectClass, int flags)
|
||||
{
|
||||
if (!(actor->flags & MF_SHOOTABLE))
|
||||
return;
|
||||
|
||||
if (!(flags & DAMAGE_NONPLAYERS) && actor->player == NULL)
|
||||
return;
|
||||
|
||||
if (!(flags & DAMAGE_PLAYERS) && actor->player != NULL)
|
||||
return;
|
||||
|
||||
if (!(flags & DAMAGE_IN_AIR) && actor->z != sec->floorplane.ZatPoint(actor->x, actor->y) && !actor->waterlevel)
|
||||
return;
|
||||
|
||||
if (protectClass != NULL)
|
||||
{
|
||||
if (actor->FindInventory(protectClass, !!(flags & DAMAGE_SUBCLASSES_PROTECT)))
|
||||
return;
|
||||
}
|
||||
|
||||
P_DamageMobj (actor, NULL, NULL, amount, type);
|
||||
}
|
||||
|
||||
void P_SectorDamage(int tag, int amount, FName type, const PClass *protectClass, int flags)
|
||||
{
|
||||
int secnum = -1;
|
||||
|
||||
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
|
||||
{
|
||||
AActor *actor, *next;
|
||||
sector_t *sec = §ors[secnum];
|
||||
|
||||
// Do for actors in this sector.
|
||||
for (actor = sec->thinglist; actor != NULL; actor = next)
|
||||
{
|
||||
next = actor->snext;
|
||||
DoSectorDamage(actor, sec, amount, type, protectClass, flags);
|
||||
}
|
||||
// If this is a 3D floor control sector, also do for anything in/on
|
||||
// those 3D floors.
|
||||
for (unsigned i = 0; i < sec->e->XFloor.attached.Size(); ++i)
|
||||
{
|
||||
sector_t *sec2 = sec->e->XFloor.attached[i];
|
||||
|
||||
for (actor = sec2->thinglist; actor != NULL; actor = next)
|
||||
{
|
||||
next = actor->snext;
|
||||
// Only affect actors touching the 3D floor
|
||||
if (actor->z + actor->height > sec->floorplane.ZatPoint(actor->x, actor->y))
|
||||
{
|
||||
// If DAMAGE_IN_AIR is used, anything not beneath the 3D floor will be
|
||||
// damaged (so, anything touching it or above it). Other 3D floors between
|
||||
// the actor and this one will not stop this effect.
|
||||
if ((flags & DAMAGE_IN_AIR) || actor->z <= sec->ceilingplane.ZatPoint(actor->x, actor->y))
|
||||
{
|
||||
// Here we pass the DAMAGE_IN_AIR flag to disable the floor check, since it
|
||||
// only works with the real sector's floor. We did the appropriate height checks
|
||||
// for 3D floors already.
|
||||
DoSectorDamage(actor, NULL, amount, type, protectClass, flags | DAMAGE_IN_AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
|
|
|
@ -145,6 +145,12 @@ bool PIT_PushThing (AActor *thing);
|
|||
// Define values for map objects
|
||||
#define MO_TELEPORTMAN 14
|
||||
|
||||
// Flags for P_SectorDamage
|
||||
#define DAMAGE_PLAYERS 1
|
||||
#define DAMAGE_NONPLAYERS 2
|
||||
#define DAMAGE_IN_AIR 4
|
||||
#define DAMAGE_SUBCLASSES_PROTECT 8
|
||||
|
||||
|
||||
// [RH] If a deathmatch game, checks to see if noexit is enabled.
|
||||
// If so, it kills the player and returns false. Otherwise,
|
||||
|
@ -163,7 +169,7 @@ bool P_TestActivateLine (line_t *ld, AActor *mo, int side, int activationType);
|
|||
|
||||
void P_PlayerInSpecialSector (player_t *player, sector_t * sector=NULL);
|
||||
void P_PlayerOnSpecialFlat (player_t *player, int floorType);
|
||||
|
||||
void P_SectorDamage(int tag, int amount, FName type, const PClass *protectClass, int flags);
|
||||
void P_SetSectorFriction (int tag, int amount, bool alterFlag);
|
||||
|
||||
void P_GiveSecret(AActor *actor, bool printmessage, bool playsound);
|
||||
|
|
Loading…
Reference in a new issue