gzdoom/src/g_strife/a_programmer.cpp

168 lines
3.7 KiB
C++
Raw Normal View History

2016-03-01 15:47:10 +00:00
/*
#include "actor.h"
#include "m_random.h"
#include "a_action.h"
#include "p_local.h"
#include "p_enemy.h"
#include "s_sound.h"
#include "a_strifeglobal.h"
#include "thingdef/thingdef.h"
#include "g_level.h"
#include "doomstat.h"
*/
static FRandom pr_prog ("Programmer");
// The Programmer level ending thing ----------------------------------------
// [RH] I took some liberties to make this "cooler" than it was in Strife.
class AProgLevelEnder : public AInventory
{
DECLARE_CLASS (AProgLevelEnder, AInventory)
public:
void Tick ();
PalEntry GetBlend ();
};
IMPLEMENT_CLASS (AProgLevelEnder)
//============================================================================
//
// AProgLevelEnder :: Tick
//
// Fade to black, end the level, then unfade.
//
//============================================================================
void AProgLevelEnder::Tick ()
{
if (special2 == 0)
{ // fade out over .66 second
special1 += 255 / (TICRATE*2/3);
if (++special1 >= 255)
{
special1 = 255;
special2 = 1;
G_ExitLevel (0, false);
}
}
else
{ // fade in over two seconds
special1 -= 255 / (TICRATE*2);
if (special1 <= 0)
{
Destroy ();
}
}
}
//============================================================================
//
// AProgLevelEnder :: GetBlend
//
//============================================================================
PalEntry AProgLevelEnder::GetBlend ()
{
return PalEntry ((BYTE)special1, 0, 0, 0);
}
//============================================================================
//
// A_ProgrammerMelee
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_ProgrammerMelee)
{
PARAM_ACTION_PROLOGUE;
int damage;
if (self->target == NULL)
return 0;
A_FaceTarget (self);
if (!self->CheckMeleeRange ())
return 0;
S_Sound (self, CHAN_WEAPON, "programmer/clank", 1, ATTN_NORM);
damage = ((pr_prog() % 10) + 1) * 6;
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
return 0;
}
//============================================================================
//
// A_SpotLightning
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SpotLightning)
{
PARAM_ACTION_PROLOGUE;
AActor *spot;
if (self->target == NULL)
return 0;
spot = Spawn("SpectralLightningSpot", self->target->_f_X(), self->target->_f_Y(), self->target->floorz, ALLOW_REPLACE);
2016-03-01 15:47:10 +00:00
if (spot != NULL)
{
spot->threshold = 25;
spot->target = self;
spot->FriendPlayer = 0;
spot->tracer = self->target;
}
return 0;
}
//============================================================================
//
// A_SpawnProgrammerBase
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SpawnProgrammerBase)
{
PARAM_ACTION_PROLOGUE;
AActor *foo = Spawn("ProgrammerBase", self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE);
if (foo != NULL)
{
foo->Angles.Yaw = self->Angles.Yaw + 180. + pr_prog.Random2() * (360. / 1024.);
foo->VelFromAngle();
foo->Vel.Z = pr_prog() / 128.;
2016-03-01 15:47:10 +00:00
}
return 0;
}
//============================================================================
//
// A_ProgrammerDeath
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_ProgrammerDeath)
{
PARAM_ACTION_PROLOGUE;
if (!CheckBossDeath (self))
return 0;
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i] && players[i].health > 0)
{
players[i].mo->GiveInventoryType (RUNTIME_CLASS(AProgLevelEnder));
break;
}
}
// the sky change scripts are now done as special actions in MAPINFO
A_BossDeath(self);
return 0;
}