mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-12-17 15:50:58 +00:00
543 lines
15 KiB
C++
543 lines
15 KiB
C++
|
#include "actor.h"
|
||
|
#include "info.h"
|
||
|
#include "p_enemy.h"
|
||
|
#include "a_doomglobal.h"
|
||
|
#include "a_hereticglobal.h"
|
||
|
#include "a_pickups.h"
|
||
|
#include "a_action.h"
|
||
|
#include "m_random.h"
|
||
|
#include "p_local.h"
|
||
|
#include "s_sound.h"
|
||
|
#include "gstrings.h"
|
||
|
|
||
|
static FRandom pr_podpain ("PodPain");
|
||
|
static FRandom pr_makepod ("MakePod");
|
||
|
static FRandom pr_teleg ("TeleGlitter");
|
||
|
static FRandom pr_teleg2 ("TeleGlitter2");
|
||
|
static FRandom pr_volcano ("VolcanoSet");
|
||
|
static FRandom pr_blast ("VolcanoBlast");
|
||
|
static FRandom pr_impact ("VolcBallImpact");
|
||
|
|
||
|
// --- Pods -----------------------------------------------------------------
|
||
|
|
||
|
void A_PodPain (AActor *);
|
||
|
void A_RemovePod (AActor *);
|
||
|
void A_MakePod (AActor *);
|
||
|
|
||
|
// Pod ----------------------------------------------------------------------
|
||
|
|
||
|
class APod : public AExplosiveBarrel
|
||
|
{
|
||
|
DECLARE_ACTOR (APod, AExplosiveBarrel)
|
||
|
HAS_OBJECT_POINTERS
|
||
|
public:
|
||
|
void BeginPlay ();
|
||
|
AActor *Generator;
|
||
|
|
||
|
void Serialize (FArchive &arc);
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_POINTY_CLASS (APod)
|
||
|
DECLARE_POINTER (Generator)
|
||
|
END_POINTERS;
|
||
|
|
||
|
void APod::Serialize (FArchive &arc)
|
||
|
{
|
||
|
Super::Serialize (arc);
|
||
|
arc << Generator;
|
||
|
}
|
||
|
|
||
|
FState APod::States[] =
|
||
|
{
|
||
|
#define S_POD_WAIT 0
|
||
|
S_NORMAL (PPOD, 'A', 10, NULL , &States[S_POD_WAIT+0]),
|
||
|
|
||
|
#define S_POD_PAIN (S_POD_WAIT+1)
|
||
|
S_NORMAL (PPOD, 'B', 14, A_PodPain , &States[S_POD_WAIT+0]),
|
||
|
|
||
|
#define S_POD_DIE (S_POD_PAIN+1)
|
||
|
S_BRIGHT (PPOD, 'C', 5, A_RemovePod , &States[S_POD_DIE+1]),
|
||
|
S_BRIGHT (PPOD, 'D', 5, A_Scream , &States[S_POD_DIE+2]),
|
||
|
S_BRIGHT (PPOD, 'E', 5, A_Explode , &States[S_POD_DIE+3]),
|
||
|
S_BRIGHT (PPOD, 'F', 10, NULL , &AActor::States[S_FREETARGMOBJ]),
|
||
|
|
||
|
#define S_POD_GROW (S_POD_DIE+4)
|
||
|
S_NORMAL (PPOD, 'I', 3, NULL , &States[S_POD_GROW+1]),
|
||
|
S_NORMAL (PPOD, 'J', 3, NULL , &States[S_POD_GROW+2]),
|
||
|
S_NORMAL (PPOD, 'K', 3, NULL , &States[S_POD_GROW+3]),
|
||
|
S_NORMAL (PPOD, 'L', 3, NULL , &States[S_POD_GROW+4]),
|
||
|
S_NORMAL (PPOD, 'M', 3, NULL , &States[S_POD_GROW+5]),
|
||
|
S_NORMAL (PPOD, 'N', 3, NULL , &States[S_POD_GROW+6]),
|
||
|
S_NORMAL (PPOD, 'O', 3, NULL , &States[S_POD_GROW+7]),
|
||
|
S_NORMAL (PPOD, 'P', 3, NULL , &States[S_POD_WAIT+0])
|
||
|
};
|
||
|
|
||
|
BEGIN_DEFAULTS (APod, Heretic, 2035, 125)
|
||
|
PROP_SpawnHealth (45)
|
||
|
PROP_RadiusFixed (16)
|
||
|
PROP_HeightFixed (54)
|
||
|
PROP_PainChance (255)
|
||
|
PROP_Flags (MF_SOLID|MF_NOBLOOD|MF_SHOOTABLE|MF_DROPOFF)
|
||
|
PROP_Flags2 (MF2_WINDTHRUST|MF2_PUSHABLE|MF2_SLIDE|MF2_PASSMOBJ|MF2_TELESTOMP)
|
||
|
PROP_Flags3 (MF3_DONTMORPH|MF3_NOBLOCKMONST|MF3_DONTGIB)
|
||
|
|
||
|
PROP_SpawnState (S_POD_WAIT)
|
||
|
PROP_PainState (S_POD_PAIN)
|
||
|
PROP_DeathState (S_POD_DIE)
|
||
|
|
||
|
PROP_DeathSound ("world/podexplode")
|
||
|
END_DEFAULTS
|
||
|
|
||
|
void APod::BeginPlay ()
|
||
|
{
|
||
|
Super::BeginPlay ();
|
||
|
Generator = NULL;
|
||
|
}
|
||
|
|
||
|
// Pod goo (falls from pod when damaged) ------------------------------------
|
||
|
|
||
|
class APodGoo : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (APodGoo, AActor)
|
||
|
};
|
||
|
|
||
|
FState APodGoo::States[] =
|
||
|
{
|
||
|
#define S_PODGOO 0
|
||
|
S_NORMAL (PPOD, 'G', 8, NULL , &States[S_PODGOO+1]),
|
||
|
S_NORMAL (PPOD, 'H', 8, NULL , &States[S_PODGOO+0]),
|
||
|
|
||
|
#define S_PODGOOX (S_PODGOO+2)
|
||
|
S_NORMAL (PPOD, 'G', 10, NULL , NULL)
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (APodGoo, Heretic, -1, 0)
|
||
|
PROP_RadiusFixed (2)
|
||
|
PROP_HeightFixed (4)
|
||
|
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF)
|
||
|
PROP_Flags2 (MF2_NOTELEPORT|MF2_LOGRAV|MF2_CANNOTPUSH)
|
||
|
|
||
|
PROP_SpawnState (S_PODGOO)
|
||
|
END_DEFAULTS
|
||
|
|
||
|
// Pod generator ------------------------------------------------------------
|
||
|
|
||
|
class APodGenerator : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (APodGenerator, AActor)
|
||
|
};
|
||
|
|
||
|
FState APodGenerator::States[] =
|
||
|
{
|
||
|
S_NORMAL (TNT1, 'A', 35, A_MakePod , &States[0])
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (APodGenerator, Heretic, 43, 126)
|
||
|
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR)
|
||
|
PROP_SpawnState (0)
|
||
|
END_DEFAULTS
|
||
|
|
||
|
// --- Pod action functions -------------------------------------------------
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// PROC A_PodPain
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void A_PodPain (AActor *actor)
|
||
|
{
|
||
|
int count;
|
||
|
int chance;
|
||
|
AActor *goo;
|
||
|
|
||
|
chance = pr_podpain ();
|
||
|
if (chance < 128)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
for (count = chance > 240 ? 2 : 1; count; count--)
|
||
|
{
|
||
|
goo = Spawn<APodGoo> (actor->x, actor->y, actor->z + 48*FRACUNIT);
|
||
|
goo->target = actor;
|
||
|
goo->momx = pr_podpain.Random2() << 9;
|
||
|
goo->momy = pr_podpain.Random2() << 9;
|
||
|
goo->momz = FRACUNIT/2 + (pr_podpain() << 9);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// PROC A_RemovePod
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void A_RemovePod (AActor *actor)
|
||
|
{
|
||
|
AActor *mo;
|
||
|
|
||
|
if ( (mo = static_cast<APod *>(actor)->Generator) )
|
||
|
{
|
||
|
if (mo->special1 > 0)
|
||
|
{
|
||
|
mo->special1--;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// PROC A_MakePod
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#define MAX_GEN_PODS 16
|
||
|
|
||
|
void A_MakePod (AActor *actor)
|
||
|
{
|
||
|
APod *mo;
|
||
|
fixed_t x;
|
||
|
fixed_t y;
|
||
|
fixed_t z;
|
||
|
|
||
|
if (actor->special1 == MAX_GEN_PODS)
|
||
|
{ // Too many generated pods
|
||
|
return;
|
||
|
}
|
||
|
x = actor->x;
|
||
|
y = actor->y;
|
||
|
z = actor->z;
|
||
|
mo = Spawn<APod> (x, y, ONFLOORZ);
|
||
|
if (P_CheckPosition (mo, x, y) == false)
|
||
|
{ // Didn't fit
|
||
|
mo->Destroy ();
|
||
|
return;
|
||
|
}
|
||
|
mo->SetState (&APod::States[S_POD_GROW]);
|
||
|
P_ThrustMobj (mo, pr_makepod()<<24, (fixed_t)(4.5*FRACUNIT));
|
||
|
S_Sound (mo, CHAN_BODY, "world/podgrow", 1, ATTN_IDLE);
|
||
|
actor->special1++; // Increment generated pod count
|
||
|
mo->Generator = actor; // Link the generator to the pod
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// --- Teleglitter ----------------------------------------------------------
|
||
|
|
||
|
void A_SpawnTeleGlitter (AActor *);
|
||
|
void A_SpawnTeleGlitter2 (AActor *);
|
||
|
void A_AccTeleGlitter (AActor *);
|
||
|
|
||
|
// Teleglitter generator 1 --------------------------------------------------
|
||
|
|
||
|
class ATeleGlitterGenerator1 : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (ATeleGlitterGenerator1, AActor)
|
||
|
};
|
||
|
|
||
|
FState ATeleGlitterGenerator1::States[] =
|
||
|
{
|
||
|
S_NORMAL (TGLT, 'A', 8, A_SpawnTeleGlitter , &States[0])
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (ATeleGlitterGenerator1, Heretic, 74, 166)
|
||
|
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOSECTOR)
|
||
|
PROP_SpawnState (0)
|
||
|
END_DEFAULTS
|
||
|
|
||
|
// Teleglitter generator 2 --------------------------------------------------
|
||
|
|
||
|
class ATeleGlitterGenerator2 : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (ATeleGlitterGenerator2, AActor)
|
||
|
};
|
||
|
|
||
|
FState ATeleGlitterGenerator2::States[] =
|
||
|
{
|
||
|
S_NORMAL (TGLT, 'F', 8, A_SpawnTeleGlitter2 , &States[0])
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (ATeleGlitterGenerator2, Heretic, 52, 167)
|
||
|
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOSECTOR)
|
||
|
PROP_SpawnState (0)
|
||
|
END_DEFAULTS
|
||
|
|
||
|
// Teleglitter 1 ------------------------------------------------------------
|
||
|
|
||
|
class ATeleGlitter1 : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (ATeleGlitter1, AActor)
|
||
|
};
|
||
|
|
||
|
FState ATeleGlitter1::States[] =
|
||
|
{
|
||
|
S_BRIGHT (TGLT, 'A', 2, NULL , &States[1]),
|
||
|
S_BRIGHT (TGLT, 'B', 2, A_AccTeleGlitter , &States[2]),
|
||
|
S_BRIGHT (TGLT, 'C', 2, NULL , &States[3]),
|
||
|
S_BRIGHT (TGLT, 'D', 2, A_AccTeleGlitter , &States[4]),
|
||
|
S_BRIGHT (TGLT, 'E', 2, NULL , &States[0])
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (ATeleGlitter1, Heretic, -1, 0)
|
||
|
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_MISSILE)
|
||
|
PROP_RenderStyle (STYLE_Add)
|
||
|
PROP_SpawnState (0)
|
||
|
PROP_Damage (0)
|
||
|
END_DEFAULTS
|
||
|
|
||
|
// Teleglitter 2 ------------------------------------------------------------
|
||
|
|
||
|
class ATeleGlitter2 : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (ATeleGlitter2, AActor)
|
||
|
};
|
||
|
|
||
|
FState ATeleGlitter2::States[] =
|
||
|
{
|
||
|
S_BRIGHT (TGLT, 'F', 2, NULL , &States[1]),
|
||
|
S_BRIGHT (TGLT, 'G', 2, A_AccTeleGlitter , &States[2]),
|
||
|
S_BRIGHT (TGLT, 'H', 2, NULL , &States[3]),
|
||
|
S_BRIGHT (TGLT, 'I', 2, A_AccTeleGlitter , &States[4]),
|
||
|
S_BRIGHT (TGLT, 'J', 2, NULL , &States[0])
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (ATeleGlitter2, Heretic, -1, 0)
|
||
|
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_MISSILE)
|
||
|
PROP_RenderStyle (STYLE_Add)
|
||
|
PROP_SpawnState (0)
|
||
|
PROP_Damage (0)
|
||
|
END_DEFAULTS
|
||
|
|
||
|
// --- Teleglitter action functions -----------------------------------------
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// PROC A_SpawnTeleGlitter
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void A_SpawnTeleGlitter (AActor *actor)
|
||
|
{
|
||
|
AActor *mo;
|
||
|
fixed_t x = actor->x+((pr_teleg()&31)-16)*FRACUNIT;
|
||
|
fixed_t y = actor->y+((pr_teleg()&31)-16)*FRACUNIT;
|
||
|
|
||
|
mo = Spawn<ATeleGlitter1> (x, y,
|
||
|
actor->Sector->floorplane.ZatPoint (actor->x, actor->y));
|
||
|
mo->momz = FRACUNIT/4;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// PROC A_SpawnTeleGlitter2
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void A_SpawnTeleGlitter2 (AActor *actor)
|
||
|
{
|
||
|
AActor *mo;
|
||
|
fixed_t x = actor->x+((pr_teleg2()&31)-16)*FRACUNIT;
|
||
|
fixed_t y = actor->y+((pr_teleg2()&31)-16)*FRACUNIT;
|
||
|
|
||
|
mo = Spawn<ATeleGlitter2> (x, y,
|
||
|
actor->Sector->floorplane.ZatPoint (actor->x, actor->y));
|
||
|
mo->momz = FRACUNIT/4;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// PROC A_AccTeleGlitter
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void A_AccTeleGlitter (AActor *actor)
|
||
|
{
|
||
|
if (++actor->health > 35)
|
||
|
{
|
||
|
actor->momz += actor->momz/2;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --- Volcano --------------------------------------------------------------
|
||
|
|
||
|
void A_VolcanoSet (AActor *);
|
||
|
void A_VolcanoBlast (AActor *);
|
||
|
void A_VolcBallImpact (AActor *);
|
||
|
extern void A_BeastPuff (AActor *);
|
||
|
|
||
|
// Volcano ------------------------------------------------------------------
|
||
|
|
||
|
class AVolcano : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (AVolcano, AActor)
|
||
|
};
|
||
|
|
||
|
FState AVolcano::States[] =
|
||
|
{
|
||
|
S_NORMAL (VLCO, 'A', 350, NULL , &States[1]),
|
||
|
S_NORMAL (VLCO, 'A', 35, A_VolcanoSet , &States[2]),
|
||
|
S_NORMAL (VLCO, 'B', 3, NULL , &States[3]),
|
||
|
S_NORMAL (VLCO, 'C', 3, NULL , &States[4]),
|
||
|
S_NORMAL (VLCO, 'D', 3, NULL , &States[5]),
|
||
|
S_NORMAL (VLCO, 'B', 3, NULL , &States[6]),
|
||
|
S_NORMAL (VLCO, 'C', 3, NULL , &States[7]),
|
||
|
S_NORMAL (VLCO, 'D', 3, NULL , &States[8]),
|
||
|
S_NORMAL (VLCO, 'E', 10, A_VolcanoBlast , &States[1])
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (AVolcano, Heretic, 87, 150)
|
||
|
PROP_RadiusFixed (12)
|
||
|
PROP_HeightFixed (20)
|
||
|
PROP_Flags (MF_SOLID)
|
||
|
|
||
|
PROP_SpawnState (0)
|
||
|
END_DEFAULTS
|
||
|
|
||
|
// Volcano blast ------------------------------------------------------------
|
||
|
|
||
|
class AVolcanoBlast : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (AVolcanoBlast, AActor)
|
||
|
};
|
||
|
|
||
|
FState AVolcanoBlast::States[] =
|
||
|
{
|
||
|
#define S_VOLCANOBALL 0
|
||
|
S_NORMAL (VFBL, 'A', 4, A_BeastPuff , &States[S_VOLCANOBALL+1]),
|
||
|
S_NORMAL (VFBL, 'B', 4, A_BeastPuff , &States[S_VOLCANOBALL+0]),
|
||
|
|
||
|
#define S_VOLCANOBALLX (S_VOLCANOBALL+2)
|
||
|
S_NORMAL (XPL1, 'A', 4, A_VolcBallImpact , &States[S_VOLCANOBALLX+1]),
|
||
|
S_NORMAL (XPL1, 'B', 4, NULL , &States[S_VOLCANOBALLX+2]),
|
||
|
S_NORMAL (XPL1, 'C', 4, NULL , &States[S_VOLCANOBALLX+3]),
|
||
|
S_NORMAL (XPL1, 'D', 4, NULL , &States[S_VOLCANOBALLX+4]),
|
||
|
S_NORMAL (XPL1, 'E', 4, NULL , &States[S_VOLCANOBALLX+5]),
|
||
|
S_NORMAL (XPL1, 'F', 4, NULL , NULL)
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (AVolcanoBlast, Heretic, -1, 123)
|
||
|
PROP_RadiusFixed (8)
|
||
|
PROP_HeightFixed (8)
|
||
|
PROP_SpeedFixed (2)
|
||
|
PROP_Damage (2)
|
||
|
PROP_DamageType (MOD_FIRE)
|
||
|
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF)
|
||
|
PROP_Flags2 (MF2_LOGRAV|MF2_NOTELEPORT)
|
||
|
|
||
|
PROP_SpawnState (S_VOLCANOBALL)
|
||
|
PROP_DeathState (S_VOLCANOBALLX)
|
||
|
|
||
|
PROP_DeathSound ("world/volcano/blast")
|
||
|
END_DEFAULTS
|
||
|
|
||
|
// Volcano T Blast ----------------------------------------------------------
|
||
|
|
||
|
class AVolcanoTBlast : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (AVolcanoTBlast, AActor)
|
||
|
};
|
||
|
|
||
|
FState AVolcanoTBlast::States[] =
|
||
|
{
|
||
|
#define S_VOLCANOTBALL 0
|
||
|
S_NORMAL (VTFB, 'A', 4, NULL , &States[S_VOLCANOTBALL+1]),
|
||
|
S_NORMAL (VTFB, 'B', 4, NULL , &States[S_VOLCANOTBALL+0]),
|
||
|
|
||
|
#define S_VOLCANOTBALLX (S_VOLCANOTBALL+2)
|
||
|
S_NORMAL (SFFI, 'C', 4, NULL , &States[S_VOLCANOTBALLX+1]),
|
||
|
S_NORMAL (SFFI, 'B', 4, NULL , &States[S_VOLCANOTBALLX+2]),
|
||
|
S_NORMAL (SFFI, 'A', 4, NULL , &States[S_VOLCANOTBALLX+3]),
|
||
|
S_NORMAL (SFFI, 'B', 4, NULL , &States[S_VOLCANOTBALLX+4]),
|
||
|
S_NORMAL (SFFI, 'C', 4, NULL , &States[S_VOLCANOTBALLX+5]),
|
||
|
S_NORMAL (SFFI, 'D', 4, NULL , &States[S_VOLCANOTBALLX+6]),
|
||
|
S_NORMAL (SFFI, 'E', 4, NULL , NULL)
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (AVolcanoTBlast, Heretic, -1, 124)
|
||
|
PROP_RadiusFixed (8)
|
||
|
PROP_HeightFixed (6)
|
||
|
PROP_SpeedFixed (2)
|
||
|
PROP_Damage (1)
|
||
|
PROP_DamageType (MOD_FIRE)
|
||
|
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF)
|
||
|
PROP_Flags2 (MF2_LOGRAV|MF2_NOTELEPORT)
|
||
|
|
||
|
PROP_SpawnState (S_VOLCANOTBALL)
|
||
|
PROP_DeathState (S_VOLCANOTBALLX)
|
||
|
END_DEFAULTS
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// PROC A_VolcanoSet
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void A_VolcanoSet (AActor *volcano)
|
||
|
{
|
||
|
volcano->tics = 105 + (pr_volcano() & 127);
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// PROC A_VolcanoBlast
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void A_VolcanoBlast (AActor *volcano)
|
||
|
{
|
||
|
int i;
|
||
|
int count;
|
||
|
AActor *blast;
|
||
|
angle_t angle;
|
||
|
|
||
|
count = 1 + (pr_blast() % 3);
|
||
|
for (i = 0; i < count; i++)
|
||
|
{
|
||
|
blast = Spawn<AVolcanoBlast> (volcano->x, volcano->y,
|
||
|
volcano->z + 44*FRACUNIT);
|
||
|
blast->target = volcano;
|
||
|
angle = pr_blast () << 24;
|
||
|
blast->angle = angle;
|
||
|
angle >>= ANGLETOFINESHIFT;
|
||
|
blast->momx = FixedMul (1*FRACUNIT, finecosine[angle]);
|
||
|
blast->momy = FixedMul (1*FRACUNIT, finesine[angle]);
|
||
|
blast->momz = (FRACUNIT*5/2) + (pr_blast() << 10);
|
||
|
S_Sound (blast, CHAN_BODY, "world/volcano/shoot", 1, ATTN_NORM);
|
||
|
P_CheckMissileSpawn (blast);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// PROC A_VolcBallImpact
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void A_VolcBallImpact (AActor *ball)
|
||
|
{
|
||
|
int i;
|
||
|
AActor *tiny;
|
||
|
angle_t angle;
|
||
|
|
||
|
if (ball->z <= ball->floorz)
|
||
|
{
|
||
|
ball->flags |= MF_NOGRAVITY;
|
||
|
ball->flags2 &= ~MF2_LOGRAV;
|
||
|
ball->z += 28*FRACUNIT;
|
||
|
//ball->momz = 3*FRACUNIT;
|
||
|
}
|
||
|
P_RadiusAttack (ball, ball->target, 25, 25, MOD_FIRE, true);
|
||
|
for (i = 0; i < 4; i++)
|
||
|
{
|
||
|
tiny = Spawn<AVolcanoTBlast> (ball->x, ball->y, ball->z);
|
||
|
tiny->target = ball;
|
||
|
angle = i*ANG90;
|
||
|
tiny->angle = angle;
|
||
|
angle >>= ANGLETOFINESHIFT;
|
||
|
tiny->momx = FixedMul (FRACUNIT*7/10, finecosine[angle]);
|
||
|
tiny->momy = FixedMul (FRACUNIT*7/10, finesine[angle]);
|
||
|
tiny->momz = FRACUNIT + (pr_impact() << 9);
|
||
|
P_CheckMissileSpawn (tiny);
|
||
|
}
|
||
|
}
|
||
|
|