gzdoom-gles/src/g_hexen/a_spike.cpp
Randy Heit 549712e719 - P_DamageMobj() now returns the amount of damage actually done so that the bleed functions
can perform based on the amount of damage actually taken after all modifications are done to
  it. However, if the damage is canceled away, blood will still spawn for the original damage
  amount rather than the modified amount.

SVN r4012 (trunk)
2013-01-02 04:39:59 +00:00

162 lines
3.9 KiB
C++

/*
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "p_enemy.h"
#include "p_local.h"
#include "a_sharedglobal.h"
#include "s_sound.h"
#include "m_bbox.h"
#include "thingdef/thingdef.h"
*/
static FRandom pr_thrustraise ("ThrustRaise");
// Spike (thrust floor) -----------------------------------------------------
// AThrustFloor is just a container for all the spike states.
// All the real spikes subclass it.
class AThrustFloor : public AActor
{
DECLARE_CLASS (AThrustFloor, AActor)
HAS_OBJECT_POINTERS
public:
void Serialize (FArchive &arc);
void Activate (AActor *activator);
void Deactivate (AActor *activator);
TObjPtr<AActor> DirtClump;
};
IMPLEMENT_POINTY_CLASS (AThrustFloor)
DECLARE_POINTER (DirtClump)
END_POINTERS
void AThrustFloor::Serialize (FArchive &arc)
{
Super::Serialize (arc);
arc << DirtClump;
}
void AThrustFloor::Activate (AActor *activator)
{
if (args[0] == 0)
{
S_Sound (this, CHAN_BODY, "ThrustSpikeLower", 1, ATTN_NORM);
renderflags &= ~RF_INVISIBLE;
if (args[1])
SetState (FindState ("BloodThrustRaise"));
else
SetState (FindState ("ThrustRaise"));
}
}
void AThrustFloor::Deactivate (AActor *activator)
{
if (args[0] == 1)
{
S_Sound (this, CHAN_BODY, "ThrustSpikeRaise", 1, ATTN_NORM);
if (args[1])
SetState (FindState ("BloodThrustLower"));
else
SetState (FindState ("ThrustLower"));
}
}
//===========================================================================
//
// Thrust floor stuff
//
// Thrust Spike Variables
// DirtClump pointer to dirt clump actor
// special2 speed of raise
// args[0] 0 = lowered, 1 = raised
// args[1] 0 = normal, 1 = bloody
//===========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitUp)
{
self->special2 = 5; // Raise speed
self->args[0] = 1; // Mark as up
self->floorclip = 0;
self->flags = MF_SOLID;
self->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP;
self->special1 = 0L;
}
DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitDn)
{
self->special2 = 5; // Raise speed
self->args[0] = 0; // Mark as down
self->floorclip = self->GetDefault()->height;
self->flags = 0;
self->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP;
self->renderflags = RF_INVISIBLE;
static_cast<AThrustFloor *>(self)->DirtClump =
Spawn("DirtClump", self->x, self->y, self->z, ALLOW_REPLACE);
}
DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise)
{
AThrustFloor *actor = static_cast<AThrustFloor *>(self);
if (A_RaiseMobj (actor, self->special2*FRACUNIT))
{ // Reached it's target height
actor->args[0] = 1;
if (actor->args[1])
actor->SetState (actor->FindState ("BloodThrustInit2"), true);
else
actor->SetState (actor->FindState ("ThrustInit2"), true);
}
// Lose the dirt clump
if ((actor->floorclip < actor->height) && actor->DirtClump)
{
actor->DirtClump->Destroy ();
actor->DirtClump = NULL;
}
// Spawn some dirt
if (pr_thrustraise()<40)
P_SpawnDirt (actor, actor->radius);
actor->special2++; // Increase raise speed
}
DEFINE_ACTION_FUNCTION(AActor, A_ThrustLower)
{
if (A_SinkMobj (self, 6*FRACUNIT))
{
self->args[0] = 0;
if (self->args[1])
self->SetState (self->FindState ("BloodThrustInit1"), true);
else
self->SetState (self->FindState ("ThrustInit1"), true);
}
}
DEFINE_ACTION_FUNCTION(AActor, A_ThrustImpale)
{
AActor *thing;
FBlockThingsIterator it(FBoundingBox(self->x, self->y, self->radius));
while ((thing = it.Next()))
{
if (!thing->intersects(self))
{
continue;
}
if (!(thing->flags & MF_SHOOTABLE) )
continue;
if (thing == self)
continue; // don't clip against self
int newdam = P_DamageMobj (thing, self, self, 10001, NAME_Crush);
P_TraceBleed (newdam > 0 ? newdam : 10001, thing);
self->args[1] = 1; // Mark thrust thing as bloody
}
}