mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-07 21:41:07 +00:00
bc63b70d88
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
185 lines
4.5 KiB
C++
185 lines
4.5 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 "a_action.h"
|
|
#include "p_pspr.h"
|
|
#include "gstrings.h"
|
|
#include "a_hexenglobal.h"
|
|
#include "thingdef/thingdef.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, FName damagetype);
|
|
};
|
|
|
|
IMPLEMENT_CLASS (AFrostMissile)
|
|
|
|
int AFrostMissile::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
|
|
{
|
|
if (special2 > 0)
|
|
{
|
|
damage <<= special2;
|
|
}
|
|
return damage;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_FireConePL1
|
|
//
|
|
//============================================================================
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1)
|
|
{
|
|
PARAM_ACTION_PROLOGUE;
|
|
|
|
angle_t angle;
|
|
int damage;
|
|
int slope;
|
|
int i;
|
|
AActor *mo;
|
|
bool conedone=false;
|
|
player_t *player;
|
|
AActor *linetarget;
|
|
|
|
if (NULL == (player = self->player))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
AWeapon *weapon = self->player->ReadyWeapon;
|
|
if (weapon != NULL)
|
|
{
|
|
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
|
return 0;
|
|
}
|
|
S_Sound (self, CHAN_WEAPON, "MageShardsFire", 1, ATTN_NORM);
|
|
|
|
damage = 90+(pr_cone()&15);
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
angle = self->angle+i*(ANG45/16);
|
|
slope = P_AimLineAttack (self, angle, MELEERANGE, &linetarget, 0, ALF_CHECK3D);
|
|
if (linetarget)
|
|
{
|
|
P_DamageMobj (linetarget, self, self, damage, NAME_Ice);
|
|
conedone = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// didn't find any creatures, so fire projectiles
|
|
if (!conedone)
|
|
{
|
|
mo = P_SpawnPlayerMissile (self, 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 = self;
|
|
mo->args[0] = 3; // Mark Initial shard as super damage
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_ShedShard
|
|
//
|
|
//============================================================================
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_ShedShard)
|
|
{
|
|
PARAM_ACTION_PROLOGUE;
|
|
|
|
AActor *mo;
|
|
int spawndir = self->special1;
|
|
int spermcount = self->special2;
|
|
|
|
if (spermcount <= 0)
|
|
{
|
|
return 0; // No sperm left
|
|
}
|
|
self->special2 = 0;
|
|
spermcount--;
|
|
|
|
// every so many calls, spawn a new missile in its set directions
|
|
if (spawndir & SHARDSPAWN_LEFT)
|
|
{
|
|
mo = P_SpawnMissileAngleZSpeed (self, self->Z(), RUNTIME_CLASS(AFrostMissile), self->angle+(ANG45/9),
|
|
0, (20+2*spermcount)<<FRACBITS, self->target);
|
|
if (mo)
|
|
{
|
|
mo->special1 = SHARDSPAWN_LEFT;
|
|
mo->special2 = spermcount;
|
|
mo->velz = self->velz;
|
|
mo->args[0] = (spermcount==3)?2:0;
|
|
}
|
|
}
|
|
if (spawndir & SHARDSPAWN_RIGHT)
|
|
{
|
|
mo = P_SpawnMissileAngleZSpeed (self, self->Z(), RUNTIME_CLASS(AFrostMissile), self->angle-(ANG45/9),
|
|
0, (20+2*spermcount)<<FRACBITS, self->target);
|
|
if (mo)
|
|
{
|
|
mo->special1 = SHARDSPAWN_RIGHT;
|
|
mo->special2 = spermcount;
|
|
mo->velz = self->velz;
|
|
mo->args[0] = (spermcount==3)?2:0;
|
|
}
|
|
}
|
|
if (spawndir & SHARDSPAWN_UP)
|
|
{
|
|
mo = P_SpawnMissileAngleZSpeed (self, self->Z()+8*FRACUNIT, RUNTIME_CLASS(AFrostMissile), self->angle,
|
|
0, (15+2*spermcount)<<FRACBITS, self->target);
|
|
if (mo)
|
|
{
|
|
mo->velz = self->velz;
|
|
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 (self, self->Z()-4*FRACUNIT, RUNTIME_CLASS(AFrostMissile), self->angle,
|
|
0, (15+2*spermcount)<<FRACBITS, self->target);
|
|
if (mo)
|
|
{
|
|
mo->velz = self->velz;
|
|
if (spermcount & 1) // Every other reproduction
|
|
mo->special1 = SHARDSPAWN_DOWN | SHARDSPAWN_LEFT | SHARDSPAWN_RIGHT;
|
|
else
|
|
mo->special1 = SHARDSPAWN_DOWN;
|
|
mo->special2 = spermcount;
|
|
mo->target = self->target;
|
|
mo->args[0] = (spermcount==3)?2:0;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|