2008-09-15 14:11:05 +00:00
|
|
|
/*
|
2006-02-24 04:48:15 +00:00
|
|
|
#include "actor.h"
|
|
|
|
#include "info.h"
|
|
|
|
#include "m_random.h"
|
|
|
|
#include "s_sound.h"
|
|
|
|
#include "p_local.h"
|
|
|
|
#include "p_enemy.h"
|
|
|
|
#include "gstrings.h"
|
|
|
|
#include "a_action.h"
|
2007-05-28 14:46:49 +00:00
|
|
|
#include "thingdef/thingdef.h"
|
2008-09-15 14:11:05 +00:00
|
|
|
*/
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// Mancubus attack,
|
|
|
|
// firing three missiles in three different directions?
|
|
|
|
// Doesn't look like it.
|
|
|
|
//
|
|
|
|
#define FATSPREAD (ANG90/8)
|
|
|
|
|
2008-08-10 20:48:55 +00:00
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_FatRaise)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
A_FaceTarget (self);
|
|
|
|
S_Sound (self, CHAN_WEAPON, "fatso/raiseguns", 1, ATTN_NORM);
|
|
|
|
}
|
|
|
|
|
2008-08-12 14:30:07 +00:00
|
|
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
AActor *missile;
|
|
|
|
angle_t an;
|
|
|
|
|
|
|
|
if (!self->target)
|
|
|
|
return;
|
|
|
|
|
2008-08-13 22:54:24 +00:00
|
|
|
ACTION_PARAM_START(1);
|
|
|
|
ACTION_PARAM_CLASS(spawntype, 0);
|
|
|
|
|
2006-11-04 22:26:04 +00:00
|
|
|
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
A_FaceTarget (self);
|
|
|
|
// Change direction to ...
|
|
|
|
self->angle += FATSPREAD;
|
|
|
|
P_SpawnMissile (self, self->target, spawntype);
|
|
|
|
|
|
|
|
missile = P_SpawnMissile (self, self->target, spawntype);
|
|
|
|
if (missile != NULL)
|
|
|
|
{
|
|
|
|
missile->angle += FATSPREAD;
|
|
|
|
an = missile->angle >> ANGLETOFINESHIFT;
|
2009-06-30 20:57:51 +00:00
|
|
|
missile->velx = FixedMul (missile->Speed, finecosine[an]);
|
|
|
|
missile->vely = FixedMul (missile->Speed, finesine[an]);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-08-12 14:30:07 +00:00
|
|
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
AActor *missile;
|
|
|
|
angle_t an;
|
|
|
|
|
|
|
|
if (!self->target)
|
|
|
|
return;
|
|
|
|
|
2008-08-13 22:54:24 +00:00
|
|
|
ACTION_PARAM_START(1);
|
|
|
|
ACTION_PARAM_CLASS(spawntype, 0);
|
|
|
|
|
2006-11-04 22:26:04 +00:00
|
|
|
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
A_FaceTarget (self);
|
|
|
|
// Now here choose opposite deviation.
|
|
|
|
self->angle -= FATSPREAD;
|
|
|
|
P_SpawnMissile (self, self->target, spawntype);
|
|
|
|
|
|
|
|
missile = P_SpawnMissile (self, self->target, spawntype);
|
|
|
|
if (missile != NULL)
|
|
|
|
{
|
|
|
|
missile->angle -= FATSPREAD*2;
|
|
|
|
an = missile->angle >> ANGLETOFINESHIFT;
|
2009-06-30 20:57:51 +00:00
|
|
|
missile->velx = FixedMul (missile->Speed, finecosine[an]);
|
|
|
|
missile->vely = FixedMul (missile->Speed, finesine[an]);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-08-12 14:30:07 +00:00
|
|
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
AActor *missile;
|
|
|
|
angle_t an;
|
|
|
|
|
|
|
|
if (!self->target)
|
|
|
|
return;
|
|
|
|
|
2008-08-13 22:54:24 +00:00
|
|
|
ACTION_PARAM_START(1);
|
|
|
|
ACTION_PARAM_CLASS(spawntype, 0);
|
|
|
|
|
2006-11-04 22:26:04 +00:00
|
|
|
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
A_FaceTarget (self);
|
|
|
|
|
|
|
|
missile = P_SpawnMissile (self, self->target, spawntype);
|
|
|
|
if (missile != NULL)
|
|
|
|
{
|
|
|
|
missile->angle -= FATSPREAD/2;
|
|
|
|
an = missile->angle >> ANGLETOFINESHIFT;
|
2009-06-30 20:57:51 +00:00
|
|
|
missile->velx = FixedMul (missile->Speed, finecosine[an]);
|
|
|
|
missile->vely = FixedMul (missile->Speed, finesine[an]);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
missile = P_SpawnMissile (self, self->target, spawntype);
|
|
|
|
if (missile != NULL)
|
|
|
|
{
|
|
|
|
missile->angle += FATSPREAD/2;
|
|
|
|
an = missile->angle >> ANGLETOFINESHIFT;
|
2009-06-30 20:57:51 +00:00
|
|
|
missile->velx = FixedMul (missile->Speed, finecosine[an]);
|
|
|
|
missile->vely = FixedMul (missile->Speed, finesine[an]);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// killough 9/98: a mushroom explosion effect, sorta :)
|
|
|
|
// Original idea: Linguica
|
|
|
|
//
|
|
|
|
|
2010-01-30 14:35:52 +00:00
|
|
|
AActor * P_OldSpawnMissile(AActor * source, AActor * owner, AActor * dest, const PClass *type);
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
MSF_Standard = 0,
|
|
|
|
MSF_Classic = 1,
|
|
|
|
MSF_DontHurt = 2,
|
|
|
|
};
|
2009-08-02 10:48:58 +00:00
|
|
|
|
2008-08-12 14:30:07 +00:00
|
|
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2008-08-13 22:54:24 +00:00
|
|
|
int i, j;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2009-09-14 09:41:09 +00:00
|
|
|
ACTION_PARAM_START(5);
|
2008-08-13 22:54:24 +00:00
|
|
|
ACTION_PARAM_CLASS(spawntype, 0);
|
|
|
|
ACTION_PARAM_INT(n, 1);
|
2009-08-02 10:48:58 +00:00
|
|
|
ACTION_PARAM_INT(flags, 2);
|
2009-09-14 09:41:09 +00:00
|
|
|
ACTION_PARAM_FIXED(vrange, 3);
|
|
|
|
ACTION_PARAM_FIXED(hrange, 4);
|
2008-08-13 22:54:24 +00:00
|
|
|
|
2009-09-14 09:41:09 +00:00
|
|
|
if (n == 0) n = self->Damage; // GetMissileDamage (0, 1);
|
2006-11-04 22:26:04 +00:00
|
|
|
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2012-08-30 04:01:50 +00:00
|
|
|
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, (flags & MSF_DontHurt) ? 0 : RADF_HURTSOURCE);
|
2009-10-17 11:30:44 +00:00
|
|
|
P_CheckSplash(self, 128<<FRACBITS);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// Now launch mushroom cloud
|
2008-03-20 21:12:03 +00:00
|
|
|
AActor *target = Spawn("Mapspot", 0, 0, 0, NO_REPLACE); // We need something to aim at.
|
2010-02-07 08:22:23 +00:00
|
|
|
AActor *master = (flags & MSF_DontHurt) ? (AActor*)(self->target) : self;
|
2008-08-10 20:48:55 +00:00
|
|
|
target->height = self->height;
|
2009-09-14 09:41:09 +00:00
|
|
|
for (i = -n; i <= n; i += 8)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2009-09-14 09:41:09 +00:00
|
|
|
for (j = -n; j <= n; j += 8)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2008-03-20 21:12:03 +00:00
|
|
|
AActor *mo;
|
2009-09-14 09:41:09 +00:00
|
|
|
target->x = self->x + (i << FRACBITS); // Aim in many directions from source
|
2008-08-10 20:48:55 +00:00
|
|
|
target->y = self->y + (j << FRACBITS);
|
2009-09-14 09:41:09 +00:00
|
|
|
target->z = self->z + (P_AproxDistance(i,j) * vrange); // Aim up fairly high
|
2010-01-30 14:35:52 +00:00
|
|
|
if ((flags & MSF_Classic) || // Flag explicitely set, or no flags and compat options
|
|
|
|
(flags == 0 && (self->state->DefineFlags & SDF_DEHACKED) && (i_compatflags & COMPATF_MUSHROOM)))
|
|
|
|
{ // Use old function for MBF compatibility
|
|
|
|
mo = P_OldSpawnMissile (self, master, target, spawntype);
|
2009-08-02 10:48:58 +00:00
|
|
|
}
|
2010-01-30 14:35:52 +00:00
|
|
|
else // Use normal function
|
2009-08-02 10:48:58 +00:00
|
|
|
{
|
2010-01-30 14:35:52 +00:00
|
|
|
mo = P_SpawnMissile(self, target, spawntype, master);
|
2009-08-02 10:48:58 +00:00
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
if (mo != NULL)
|
2009-09-14 09:41:09 +00:00
|
|
|
{ // Slow it down a bit
|
|
|
|
mo->velx = FixedMul(mo->velx, hrange);
|
|
|
|
mo->vely = FixedMul(mo->vely, hrange);
|
|
|
|
mo->velz = FixedMul(mo->velz, hrange);
|
2006-02-24 04:48:15 +00:00
|
|
|
mo->flags &= ~MF_NOGRAVITY; // Make debris fall under gravity
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-03-20 21:12:03 +00:00
|
|
|
target->Destroy();
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|