gzdoom/src/g_hexen/a_magecone.cpp
Christoph Oelckers 269a54a258 - Added more DECORATE conversions by Karate Chris.
SVN r1124 (trunk)
2008-08-07 15:46:52 +00:00

174 lines
4.4 KiB
C++

#include "actor.h"
#include "gi.h"
#include "m_random.h"
#include "s_sound.h"
#include "d_player.h"
#include "a_action.h"
#include "p_local.h"
#include "p_enemy.h"
#include "a_action.h"
#include "p_pspr.h"
#include "gstrings.h"
#include "a_hexenglobal.h"
const int SHARDSPAWN_LEFT = 1;
const int SHARDSPAWN_RIGHT = 2;
const int SHARDSPAWN_UP = 4;
const int SHARDSPAWN_DOWN = 8;
static FRandom pr_cone ("FireConePL1");
void A_FireConePL1 (AActor *actor);
void A_ShedShard (AActor *);
// Frost Missile ------------------------------------------------------------
class AFrostMissile : public AActor
{
DECLARE_CLASS (AFrostMissile, AActor)
public:
int DoSpecialDamage (AActor *victim, int damage);
};
IMPLEMENT_CLASS (AFrostMissile)
int AFrostMissile::DoSpecialDamage (AActor *victim, int damage)
{
if (special2 > 0)
{
damage <<= special2;
}
return damage;
}
//============================================================================
//
// A_FireConePL1
//
//============================================================================
void A_FireConePL1 (AActor *actor)
{
angle_t angle;
int damage;
int slope;
int i;
AActor *mo;
bool conedone=false;
player_t *player;
AActor *linetarget;
if (NULL == (player = actor->player))
{
return;
}
AWeapon *weapon = actor->player->ReadyWeapon;
if (weapon != NULL)
{
if (!weapon->DepleteAmmo (weapon->bAltFire))
return;
}
S_Sound (actor, CHAN_WEAPON, "MageShardsFire", 1, ATTN_NORM);
damage = 90+(pr_cone()&15);
for (i = 0; i < 16; i++)
{
angle = actor->angle+i*(ANG45/16);
slope = P_AimLineAttack (actor, angle, MELEERANGE, &linetarget);
if (linetarget)
{
P_DamageMobj (linetarget, actor, actor, damage, NAME_Ice);
conedone = true;
break;
}
}
// didn't find any creatures, so fire projectiles
if (!conedone)
{
mo = P_SpawnPlayerMissile (actor, RUNTIME_CLASS(AFrostMissile));
if (mo)
{
mo->special1 = SHARDSPAWN_LEFT|SHARDSPAWN_DOWN|SHARDSPAWN_UP
|SHARDSPAWN_RIGHT;
mo->special2 = 3; // Set sperm count (levels of reproductivity)
mo->target = actor;
mo->args[0] = 3; // Mark Initial shard as super damage
}
}
}
//============================================================================
//
// A_ShedShard
//
//============================================================================
void A_ShedShard (AActor *actor)
{
AActor *mo;
int spawndir = actor->special1;
int spermcount = actor->special2;
if (spermcount <= 0) return; // No sperm left
actor->special2 = 0;
spermcount--;
// every so many calls, spawn a new missile in its set directions
if (spawndir & SHARDSPAWN_LEFT)
{
mo = P_SpawnMissileAngleZSpeed (actor, actor->z, RUNTIME_CLASS(AFrostMissile), actor->angle+(ANG45/9),
0, (20+2*spermcount)<<FRACBITS, actor->target);
if (mo)
{
mo->special1 = SHARDSPAWN_LEFT;
mo->special2 = spermcount;
mo->momz = actor->momz;
mo->args[0] = (spermcount==3)?2:0;
}
}
if (spawndir & SHARDSPAWN_RIGHT)
{
mo = P_SpawnMissileAngleZSpeed (actor, actor->z, RUNTIME_CLASS(AFrostMissile), actor->angle-(ANG45/9),
0, (20+2*spermcount)<<FRACBITS, actor->target);
if (mo)
{
mo->special1 = SHARDSPAWN_RIGHT;
mo->special2 = spermcount;
mo->momz = actor->momz;
mo->args[0] = (spermcount==3)?2:0;
}
}
if (spawndir & SHARDSPAWN_UP)
{
mo = P_SpawnMissileAngleZSpeed (actor, actor->z+8*FRACUNIT, RUNTIME_CLASS(AFrostMissile), actor->angle,
0, (15+2*spermcount)<<FRACBITS, actor->target);
if (mo)
{
mo->momz = actor->momz;
if (spermcount & 1) // Every other reproduction
mo->special1 = SHARDSPAWN_UP | SHARDSPAWN_LEFT | SHARDSPAWN_RIGHT;
else
mo->special1 = SHARDSPAWN_UP;
mo->special2 = spermcount;
mo->args[0] = (spermcount==3)?2:0;
}
}
if (spawndir & SHARDSPAWN_DOWN)
{
mo = P_SpawnMissileAngleZSpeed (actor, actor->z-4*FRACUNIT, RUNTIME_CLASS(AFrostMissile), actor->angle,
0, (15+2*spermcount)<<FRACBITS, actor->target);
if (mo)
{
mo->momz = actor->momz;
if (spermcount & 1) // Every other reproduction
mo->special1 = SHARDSPAWN_DOWN | SHARDSPAWN_LEFT | SHARDSPAWN_RIGHT;
else
mo->special1 = SHARDSPAWN_DOWN;
mo->special2 = spermcount;
mo->target = actor->target;
mo->args[0] = (spermcount==3)?2:0;
}
}
}