gzdoom/src/g_hexen/a_firedemon.cpp
Christoph Oelckers bc63b70d88 Merge branch 'master' into scripting
Conflicts:
	src/actor.h
	src/fragglescript/t_func.cpp
	src/g_doom/a_bossbrain.cpp
	src/g_doom/a_revenant.cpp
	src/g_heretic/a_hereticartifacts.cpp
	src/g_heretic/a_hereticweaps.cpp
	src/g_heretic/a_knight.cpp
	src/g_hexen/a_bishop.cpp
	src/g_hexen/a_clericholy.cpp
	src/g_hexen/a_dragon.cpp
	src/g_hexen/a_firedemon.cpp
	src/g_hexen/a_flechette.cpp
	src/g_hexen/a_heresiarch.cpp
	src/g_hexen/a_hexenspecialdecs.cpp
	src/g_hexen/a_iceguy.cpp
	src/g_hexen/a_korax.cpp
	src/g_hexen/a_magelightning.cpp
	src/g_hexen/a_serpent.cpp
	src/g_hexen/a_spike.cpp
	src/g_hexen/a_wraith.cpp
	src/g_raven/a_minotaur.cpp
	src/g_shared/a_bridge.cpp
	src/g_shared/a_pickups.cpp
	src/g_shared/a_randomspawner.cpp
	src/g_strife/a_alienspectres.cpp
	src/g_strife/a_crusader.cpp
	src/g_strife/a_entityboss.cpp
	src/g_strife/a_inquisitor.cpp
	src/g_strife/a_loremaster.cpp
	src/g_strife/a_programmer.cpp
	src/g_strife/a_sentinel.cpp
	src/g_strife/a_spectral.cpp
	src/g_strife/a_strifestuff.cpp
	src/g_strife/a_strifeweapons.cpp
	src/g_strife/a_thingstoblowup.cpp
	src/p_local.h
	src/r_utility.cpp
2016-01-19 13:43:11 +01:00

251 lines
6 KiB
C++

/*
#include "actor.h"
#include "info.h"
#include "p_local.h"
#include "s_sound.h"
#include "p_enemy.h"
#include "a_action.h"
#include "m_random.h"
#include "thingdef/thingdef.h"
*/
#define FIREDEMON_ATTACK_RANGE 64*8*FRACUNIT
static FRandom pr_firedemonrock ("FireDemonRock");
static FRandom pr_smbounce ("SMBounce");
static FRandom pr_firedemonchase ("FiredChase");
static FRandom pr_firedemonsplotch ("FiredSplotch");
//============================================================================
// Fire Demon AI
//
// special1 index into floatbob
// special2 whether strafing or not
//============================================================================
//============================================================================
//
// A_FiredSpawnRock
//
//============================================================================
void A_FiredSpawnRock (AActor *actor)
{
AActor *mo;
PClassActor *rtype;
switch (pr_firedemonrock() % 5)
{
case 0:
rtype = PClass::FindActor("FireDemonRock1");
break;
case 1:
rtype = PClass::FindActor("FireDemonRock2");
break;
case 2:
rtype = PClass::FindActor("FireDemonRock3");
break;
case 3:
rtype = PClass::FindActor("FireDemonRock4");
break;
case 4:
default:
rtype = PClass::FindActor("FireDemonRock5");
break;
}
fixedvec3 pos = actor->Vec3Offset(
((pr_firedemonrock() - 128) << 12),
((pr_firedemonrock() - 128) << 12),
( pr_firedemonrock() << 11));
mo = Spawn (rtype, pos, ALLOW_REPLACE);
if (mo)
{
mo->target = actor;
mo->velx = (pr_firedemonrock() - 128) <<10;
mo->vely = (pr_firedemonrock() - 128) <<10;
mo->velz = (pr_firedemonrock() << 10);
mo->special1 = 2; // Number bounces
}
// Initialize fire demon
actor->special2 = 0;
actor->flags &= ~MF_JUSTATTACKED;
}
//============================================================================
//
// A_FiredRocks
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_FiredRocks)
{
PARAM_ACTION_PROLOGUE;
A_FiredSpawnRock (self);
A_FiredSpawnRock (self);
A_FiredSpawnRock (self);
A_FiredSpawnRock (self);
A_FiredSpawnRock (self);
return 0;
}
//============================================================================
//
// A_SmBounce
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_SmBounce)
{
PARAM_ACTION_PROLOGUE;
// give some more velocity (x,y,&z)
self->SetZ(self->floorz + FRACUNIT);
self->velz = (2*FRACUNIT) + (pr_smbounce() << 10);
self->velx = pr_smbounce()%3<<FRACBITS;
self->vely = pr_smbounce()%3<<FRACBITS;
return 0;
}
//============================================================================
//
// A_FiredAttack
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_FiredAttack)
{
PARAM_ACTION_PROLOGUE;
if (self->target == NULL)
return 0;
AActor *mo = P_SpawnMissile (self, self->target, PClass::FindActor("FireDemonMissile"));
if (mo) S_Sound (self, CHAN_BODY, "FireDemonAttack", 1, ATTN_NORM);
return 0;
}
//============================================================================
//
// A_FiredChase
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
{
PARAM_ACTION_PROLOGUE;
int weaveindex = self->special1;
AActor *target = self->target;
angle_t ang;
fixed_t dist;
if (self->reactiontime) self->reactiontime--;
if (self->threshold) self->threshold--;
// Float up and down
self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8);
self->special1 = (weaveindex + 2) & 63;
// Ensure it stays above certain height
if (self->Z() < self->floorz + (64*FRACUNIT))
{
self->AddZ(2*FRACUNIT);
}
if(!self->target || !(self->target->flags&MF_SHOOTABLE))
{ // Invalid target
P_LookForPlayers (self,true, NULL);
return 0;
}
// Strafe
if (self->special2 > 0)
{
self->special2--;
}
else
{
self->special2 = 0;
self->velx = self->vely = 0;
dist = self->AproxDistance (target);
if (dist < FIREDEMON_ATTACK_RANGE)
{
if (pr_firedemonchase() < 30)
{
ang = self->AngleTo(target);
if (pr_firedemonchase() < 128)
ang += ANGLE_90;
else
ang -= ANGLE_90;
ang >>= ANGLETOFINESHIFT;
self->velx = finecosine[ang] << 3; //FixedMul (8*FRACUNIT, finecosine[ang]);
self->vely = finesine[ang] << 3; //FixedMul (8*FRACUNIT, finesine[ang]);
self->special2 = 3; // strafe time
}
}
}
FaceMovementDirection (self);
// Normal movement
if (!self->special2)
{
if (--self->movecount<0 || !P_Move (self))
{
P_NewChaseDir (self);
}
}
// Do missile attack
if (!(self->flags & MF_JUSTATTACKED))
{
if (P_CheckMissileRange (self) && (pr_firedemonchase() < 20))
{
self->SetState (self->MissileState);
self->flags |= MF_JUSTATTACKED;
return 0;
}
}
else
{
self->flags &= ~MF_JUSTATTACKED;
}
// make active sound
if (pr_firedemonchase() < 3)
{
self->PlayActiveSound ();
}
return 0;
}
//============================================================================
//
// A_FiredSplotch
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_FiredSplotch)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
mo = Spawn ("FireDemonSplotch1", self->Pos(), ALLOW_REPLACE);
if (mo)
{
mo->velx = (pr_firedemonsplotch() - 128) << 11;
mo->vely = (pr_firedemonsplotch() - 128) << 11;
mo->velz = (pr_firedemonsplotch() << 10) + FRACUNIT*3;
}
mo = Spawn ("FireDemonSplotch2", self->Pos(), ALLOW_REPLACE);
if (mo)
{
mo->velx = (pr_firedemonsplotch() - 128) << 11;
mo->vely = (pr_firedemonsplotch() - 128) << 11;
mo->velz = (pr_firedemonsplotch() << 10) + FRACUNIT*3;
}
return 0;
}