mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-15 16:51:31 +00:00
- Added ACS GetChar function.
- Added Gez's submission for polyobjects being able to crush corpses but made it an explicit MAPINFO option only. SVN r1585 (trunk)
This commit is contained in:
parent
a732687548
commit
eb52c9a90e
8 changed files with 136 additions and 96 deletions
|
@ -1,4 +1,7 @@
|
|||
May 15, 2009 (Changes by Graf Zahl)
|
||||
- Added ACS GetChar function.
|
||||
- Added Gez's submission for polyobjects being able to crush corpses but made
|
||||
it an explicit MAPINFO option only.
|
||||
- Changed APlayerPawn::DamageFade to a PalEntry from 3 floats.
|
||||
- Removed #pragma warnings from cmdlib.h and fixed the places where they were
|
||||
still triggered.
|
||||
|
|
|
@ -598,6 +598,9 @@ public:
|
|||
// Die. Now.
|
||||
virtual bool Massacre ();
|
||||
|
||||
// Transforms the actor into a finely-ground paste
|
||||
bool Grind(bool items);
|
||||
|
||||
// Is the other actor on my team?
|
||||
bool IsTeammate (AActor *other);
|
||||
|
||||
|
|
|
@ -197,6 +197,7 @@ enum ELevelFlags
|
|||
LEVEL2_HEXENHACK = 0x00800000, // Level was defined in a Hexen style MAPINFO
|
||||
|
||||
LEVEL2_SMOOTHLIGHTING = 0x01000000, // Level uses the smooth lighting feature.
|
||||
LEVEL2_POLYGRIND = 0x02000000, // Polyobjects grind corpses to gibs.
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1309,6 +1309,8 @@ MapFlagHandlers[] =
|
|||
{ "teamplayoff", MITYPE_SCFLAGS2, LEVEL2_FORCETEAMPLAYOFF, ~LEVEL2_FORCETEAMPLAYON },
|
||||
{ "checkswitchrange", MITYPE_SETFLAG2, LEVEL2_CHECKSWITCHRANGE, 0 },
|
||||
{ "nocheckswitchrange", MITYPE_CLRFLAG2, LEVEL2_CHECKSWITCHRANGE, 0 },
|
||||
{ "grinding_polyobj", MITYPE_SETFLAG2, LEVEL2_POLYGRIND, 0 },
|
||||
{ "no_grinding_polyobj", MITYPE_CLRFLAG2, LEVEL2_POLYGRIND, 0 },
|
||||
{ "unfreezesingleplayerconversations",MITYPE_SETFLAG2, LEVEL2_CONV_SINGLE_UNFREEZE, 0 },
|
||||
{ "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes
|
||||
{ "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX},
|
||||
|
|
|
@ -2795,6 +2795,7 @@ enum EACSFunctions
|
|||
ACSF_SetActivator,
|
||||
ACSF_SetActivatorToTarget,
|
||||
ACSF_GetActorViewHeight,
|
||||
ACSF_GetChar,
|
||||
};
|
||||
|
||||
int DLevelScript::SideFromID(int id, int side)
|
||||
|
@ -2893,6 +2894,19 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
|
|||
}
|
||||
else return 0;
|
||||
|
||||
case ACSF_GetChar:
|
||||
{
|
||||
const char *p = FBehavior::StaticLookupString(args[0]);
|
||||
if (p != NULL && args[1] >= 0 && args[1] < strlen(p))
|
||||
{
|
||||
return p[args[1]];
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "p_effect.h"
|
||||
#include "p_terrain.h"
|
||||
#include "p_trace.h"
|
||||
#include "p_enemy.h"
|
||||
|
||||
#include "s_sound.h"
|
||||
#include "decallib.h"
|
||||
|
@ -4192,101 +4191,7 @@ void P_FindBelowIntersectors (AActor *actor)
|
|||
|
||||
void P_DoCrunch (AActor *thing, FChangePosition *cpos)
|
||||
{
|
||||
// crunch bodies to giblets
|
||||
if ((thing->flags & MF_CORPSE) &&
|
||||
!(thing->flags3 & MF3_DONTGIB) &&
|
||||
(thing->health <= 0))
|
||||
{
|
||||
FState * state = thing->FindState(NAME_Crush);
|
||||
if (state != NULL && !(thing->flags & MF_ICECORPSE))
|
||||
{
|
||||
if (thing->flags4 & MF4_BOSSDEATH)
|
||||
{
|
||||
CALL_ACTION(A_BossDeath, thing);
|
||||
}
|
||||
thing->flags &= ~MF_SOLID;
|
||||
thing->flags3 |= MF3_DONTGIB;
|
||||
thing->height = thing->radius = 0;
|
||||
thing->SetState (state);
|
||||
return;
|
||||
}
|
||||
if (!(thing->flags & MF_NOBLOOD))
|
||||
{
|
||||
if (thing->flags4 & MF4_BOSSDEATH)
|
||||
{
|
||||
CALL_ACTION(A_BossDeath, thing);
|
||||
}
|
||||
|
||||
const PClass *i = PClass::FindClass("RealGibs");
|
||||
|
||||
if (i != NULL)
|
||||
{
|
||||
i = i->ActorInfo->GetReplacement()->Class;
|
||||
|
||||
const AActor *defaults = GetDefaultByType (i);
|
||||
if (defaults->SpawnState == NULL ||
|
||||
sprites[defaults->SpawnState->sprite].numframes == 0)
|
||||
{
|
||||
i = NULL;
|
||||
}
|
||||
}
|
||||
if (i == NULL)
|
||||
{
|
||||
// if there's no gib sprite don't crunch it.
|
||||
thing->flags &= ~MF_SOLID;
|
||||
thing->flags3 |= MF3_DONTGIB;
|
||||
thing->height = thing->radius = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
AActor *gib = Spawn (i, thing->x, thing->y, thing->z, ALLOW_REPLACE);
|
||||
if (gib != NULL)
|
||||
{
|
||||
gib->RenderStyle = thing->RenderStyle;
|
||||
gib->alpha = thing->alpha;
|
||||
gib->height = 0;
|
||||
gib->radius = 0;
|
||||
}
|
||||
S_Sound (thing, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE);
|
||||
|
||||
PalEntry bloodcolor = (PalEntry)thing->GetClass()->Meta.GetMetaInt(AMETA_BloodColor);
|
||||
if (bloodcolor!=0) gib->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
|
||||
}
|
||||
if (thing->flags & MF_ICECORPSE)
|
||||
{
|
||||
thing->tics = 1;
|
||||
thing->momx = thing->momy = thing->momz = 0;
|
||||
}
|
||||
else if (thing->player)
|
||||
{
|
||||
thing->flags |= MF_NOCLIP;
|
||||
thing->flags3 |= MF3_DONTGIB;
|
||||
thing->renderflags |= RF_INVISIBLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
thing->Destroy ();
|
||||
}
|
||||
return; // keep checking
|
||||
}
|
||||
|
||||
// crunch dropped items
|
||||
if (thing->flags & MF_DROPPED)
|
||||
{
|
||||
thing->Destroy ();
|
||||
return; // keep checking
|
||||
}
|
||||
|
||||
if (!(thing->flags & MF_SOLID) || (thing->flags & MF_NOCLIP))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(thing->flags & MF_SHOOTABLE))
|
||||
{
|
||||
return; // assume it is bloody gibs or something
|
||||
}
|
||||
|
||||
if (!(thing && thing->Grind(true) && cpos)) return;
|
||||
cpos->nofit = true;
|
||||
|
||||
if ((cpos->crushchange > 0) && !(level.maptime & 3))
|
||||
|
|
110
src/p_mobj.cpp
110
src/p_mobj.cpp
|
@ -59,6 +59,7 @@
|
|||
#include "d_event.h"
|
||||
#include "colormatcher.h"
|
||||
#include "v_palette.h"
|
||||
#include "p_enemy.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -963,6 +964,115 @@ void AActor::Touch (AActor *toucher)
|
|||
{
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// AActor :: Grind
|
||||
//
|
||||
// Handles the an actor being crushed by a door, crusher or polyobject.
|
||||
// Originally part of P_DoCrunch(), it has been made into its own actor
|
||||
// function so that it could be called from a polyobject without hassle.
|
||||
// Bool items is true if it should destroy() dropped items, false otherwise.
|
||||
//============================================================================
|
||||
|
||||
bool AActor::Grind(bool items)
|
||||
{
|
||||
// crunch bodies to giblets
|
||||
if ((this->flags & MF_CORPSE) &&
|
||||
!(this->flags3 & MF3_DONTGIB) &&
|
||||
(this->health <= 0))
|
||||
{
|
||||
FState * state = this->FindState(NAME_Crush);
|
||||
if (state != NULL && !(this->flags & MF_ICECORPSE))
|
||||
{
|
||||
if (this->flags4 & MF4_BOSSDEATH)
|
||||
{
|
||||
CALL_ACTION(A_BossDeath, this);
|
||||
}
|
||||
this->flags &= ~MF_SOLID;
|
||||
this->flags3 |= MF3_DONTGIB;
|
||||
this->height = this->radius = 0;
|
||||
this->SetState (state);
|
||||
return false;
|
||||
}
|
||||
if (!(this->flags & MF_NOBLOOD))
|
||||
{
|
||||
if (this->flags4 & MF4_BOSSDEATH)
|
||||
{
|
||||
CALL_ACTION(A_BossDeath, this);
|
||||
}
|
||||
|
||||
const PClass *i = PClass::FindClass("RealGibs");
|
||||
|
||||
if (i != NULL)
|
||||
{
|
||||
i = i->ActorInfo->GetReplacement()->Class;
|
||||
|
||||
const AActor *defaults = GetDefaultByType (i);
|
||||
if (defaults->SpawnState == NULL ||
|
||||
sprites[defaults->SpawnState->sprite].numframes == 0)
|
||||
{
|
||||
i = NULL;
|
||||
}
|
||||
}
|
||||
if (i == NULL)
|
||||
{
|
||||
// if there's no gib sprite don't crunch it.
|
||||
this->flags &= ~MF_SOLID;
|
||||
this->flags3 |= MF3_DONTGIB;
|
||||
this->height = this->radius = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
AActor *gib = Spawn (i, this->x, this->y, this->z, ALLOW_REPLACE);
|
||||
if (gib != NULL)
|
||||
{
|
||||
gib->RenderStyle = this->RenderStyle;
|
||||
gib->alpha = this->alpha;
|
||||
gib->height = 0;
|
||||
gib->radius = 0;
|
||||
}
|
||||
S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE);
|
||||
|
||||
PalEntry bloodcolor = (PalEntry)this->GetClass()->Meta.GetMetaInt(AMETA_BloodColor);
|
||||
if (bloodcolor!=0) gib->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
|
||||
}
|
||||
if (this->flags & MF_ICECORPSE)
|
||||
{
|
||||
this->tics = 1;
|
||||
this->momx = this->momy = this->momz = 0;
|
||||
}
|
||||
else if (this->player)
|
||||
{
|
||||
this->flags |= MF_NOCLIP;
|
||||
this->flags3 |= MF3_DONTGIB;
|
||||
this->renderflags |= RF_INVISIBLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Destroy ();
|
||||
}
|
||||
return false; // keep checking
|
||||
}
|
||||
|
||||
// crunch dropped items
|
||||
if (this->flags & MF_DROPPED)
|
||||
{
|
||||
if (items) this->Destroy (); // Only destroy dropped items if wanted
|
||||
return false; // keep checking
|
||||
}
|
||||
|
||||
if (!(this->flags & MF_SOLID) || (this->flags & MF_NOCLIP))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(this->flags & MF_SHOOTABLE))
|
||||
{
|
||||
return false; // assume it is bloody gibs or something
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// AActor :: Massacre
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "r_main.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "r_interpolate.h"
|
||||
#include "g_level.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -780,6 +781,7 @@ void ThrustMobj (AActor *actor, seg_t *seg, FPolyObj *po)
|
|||
P_TraceBleed (po->crush, actor);
|
||||
}
|
||||
}
|
||||
if (level.flags2 & LEVEL2_POLYGRIND) actor->Grind(false); // crush corpses that get caught in a polyobject's way
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
Loading…
Reference in a new issue