mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-08 22:11:09 +00:00
285 lines
8.5 KiB
C++
285 lines
8.5 KiB
C++
|
#include "actor.h"
|
||
|
#include "m_random.h"
|
||
|
#include "p_local.h"
|
||
|
#include "c_console.h"
|
||
|
#include "p_enemy.h"
|
||
|
#include "a_action.h"
|
||
|
|
||
|
static FRandom pr_bang4cloud ("Bang4Cloud");
|
||
|
static FRandom pr_lightout ("LightOut");
|
||
|
|
||
|
extern const TypeInfo *QuestItemClasses[31];
|
||
|
|
||
|
void A_TossGib (AActor *);
|
||
|
void A_LoopActiveSound (AActor *);
|
||
|
void A_LightGoesOut (AActor *);
|
||
|
|
||
|
class ARubble1 : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (ARubble1, AActor)
|
||
|
};
|
||
|
|
||
|
// A Cloud used for varius explosions ---------------------------------------
|
||
|
// This actor has no direct equivalent in strife. To create this, Strife
|
||
|
// spawned a spark and then changed its state to that of this explosion
|
||
|
// cloud. Weird.
|
||
|
|
||
|
class ABang4Cloud : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (ABang4Cloud, AActor);
|
||
|
public:
|
||
|
void BeginPlay ()
|
||
|
{
|
||
|
momz = FRACUNIT;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
FState ABang4Cloud::States[] =
|
||
|
{
|
||
|
S_BRIGHT (BNG4, 'B', 3, NULL, &States[1]),
|
||
|
S_BRIGHT (BNG4, 'C', 3, NULL, &States[2]),
|
||
|
S_BRIGHT (BNG4, 'D', 3, NULL, &States[3]),
|
||
|
S_BRIGHT (BNG4, 'E', 3, NULL, &States[4]),
|
||
|
S_BRIGHT (BNG4, 'F', 3, NULL, &States[5]),
|
||
|
S_BRIGHT (BNG4, 'G', 3, NULL, &States[6]),
|
||
|
S_BRIGHT (BNG4, 'H', 3, NULL, &States[7]),
|
||
|
S_BRIGHT (BNG4, 'I', 3, NULL, &States[8]),
|
||
|
S_BRIGHT (BNG4, 'J', 3, NULL, &States[9]),
|
||
|
S_BRIGHT (BNG4, 'K', 3, NULL, &States[10]),
|
||
|
S_BRIGHT (BNG4, 'L', 3, NULL, &States[11]),
|
||
|
S_BRIGHT (BNG4, 'M', 3, NULL, &States[12]),
|
||
|
S_BRIGHT (BNG4, 'N', 3, NULL, NULL)
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (ABang4Cloud, Strife, -1, 0)
|
||
|
PROP_SpawnState (0)
|
||
|
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY)
|
||
|
PROP_RenderStyle (STYLE_Add)
|
||
|
END_DEFAULTS
|
||
|
|
||
|
void A_Bang4Cloud (AActor *self)
|
||
|
{
|
||
|
fixed_t spawnx, spawny;
|
||
|
|
||
|
spawnx = self->x + (pr_bang4cloud.Random2() & 3) * 10240;
|
||
|
spawny = self->y + (pr_bang4cloud.Random2() & 3) * 10240;
|
||
|
|
||
|
Spawn<ABang4Cloud> (spawnx, spawny, self->z);
|
||
|
}
|
||
|
|
||
|
// Piston -------------------------------------------------------------------
|
||
|
|
||
|
void A_GiveQuestItem (AActor *self)
|
||
|
{
|
||
|
int questitem = (self->Speed >> FRACBITS) - 1;
|
||
|
|
||
|
// Give one of these quest items to every player in the game
|
||
|
for (int i = 0; i < MAXPLAYERS; ++i)
|
||
|
{
|
||
|
if (playeringame[i])
|
||
|
{
|
||
|
AInventory *item = static_cast<AInventory *>(Spawn (QuestItemClasses[questitem], 0,0,0));
|
||
|
if (!item->TryPickup (players[i].mo))
|
||
|
{
|
||
|
item->Destroy ();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const char *name = QuestItemClasses[questitem]->Meta.GetMetaString (AMETA_StrifeName);
|
||
|
if (name != NULL)
|
||
|
{
|
||
|
C_MidPrint (name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class APiston : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (APiston, AActor);
|
||
|
};
|
||
|
|
||
|
FState APiston::States[] =
|
||
|
{
|
||
|
S_NORMAL (PSTN, 'A', 8, NULL, &States[1]),
|
||
|
S_NORMAL (PSTN, 'B', 8, NULL, &States[0]),
|
||
|
|
||
|
S_BRIGHT (PSTN, 'A', 4, A_Scream, &States[3]),
|
||
|
S_BRIGHT (PSTN, 'B', 4, A_NoBlocking, &States[4]),
|
||
|
S_BRIGHT (PSTN, 'C', 4, A_GiveQuestItem, &States[5]),
|
||
|
S_BRIGHT (PSTN, 'D', 4, A_Bang4Cloud, &States[6]),
|
||
|
S_BRIGHT (PSTN, 'E', 4, A_TossGib, &States[7]),
|
||
|
S_BRIGHT (PSTN, 'F', 4, NULL, &States[8]),
|
||
|
S_BRIGHT (PSTN, 'G', 4, A_Bang4Cloud, &States[9]),
|
||
|
S_NORMAL (PSTN, 'H', 4, NULL, &States[10]),
|
||
|
S_NORMAL (PSTN, 'I', -1, NULL, NULL)
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (APiston, Strife, 45, 0)
|
||
|
PROP_StrifeType (123)
|
||
|
PROP_SpawnHealth (100)
|
||
|
PROP_SpawnState (0)
|
||
|
PROP_DeathState (2)
|
||
|
PROP_SpeedFixed (16) // Was a byte in Strife
|
||
|
PROP_RadiusFixed (20)
|
||
|
PROP_HeightFixed (76)
|
||
|
PROP_MassLong (10000000)
|
||
|
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_NOBLOOD)
|
||
|
PROP_Flags2 (MF2_FLOORCLIP)
|
||
|
PROP_Flags4 (MF4_INCOMBAT)
|
||
|
PROP_DeathSound ("misc/explosion")
|
||
|
END_DEFAULTS
|
||
|
|
||
|
// Computer -----------------------------------------------------------------
|
||
|
|
||
|
class AComputer : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (AComputer, AActor)
|
||
|
};
|
||
|
|
||
|
FState AComputer::States[] =
|
||
|
{
|
||
|
S_BRIGHT (SECR, 'A', 4, NULL, &States[1]),
|
||
|
S_BRIGHT (SECR, 'B', 4, NULL, &States[2]),
|
||
|
S_BRIGHT (SECR, 'C', 4, NULL, &States[3]),
|
||
|
S_BRIGHT (SECR, 'D', 4, NULL, &States[0]),
|
||
|
|
||
|
S_BRIGHT (SECR, 'E', 5, A_Bang4Cloud, &States[5]),
|
||
|
S_BRIGHT (SECR, 'F', 5, A_NoBlocking, &States[6]),
|
||
|
S_BRIGHT (SECR, 'G', 5, A_GiveQuestItem, &States[7]),
|
||
|
S_BRIGHT (SECR, 'H', 5, A_TossGib, &States[8]),
|
||
|
S_BRIGHT (SECR, 'I', 5, A_Bang4Cloud, &States[9]),
|
||
|
S_NORMAL (SECR, 'J', 5, NULL, &States[10]),
|
||
|
S_NORMAL (SECR, 'K', 5, A_Bang4Cloud, &States[11]),
|
||
|
S_NORMAL (SECR, 'L', 5, NULL, &States[12]),
|
||
|
S_NORMAL (SECR, 'M', 5, A_Bang4Cloud, &States[13]),
|
||
|
S_NORMAL (SECR, 'N', 5, NULL, &States[14]),
|
||
|
S_NORMAL (SECR, 'O', 5, A_Bang4Cloud, &States[15]),
|
||
|
S_NORMAL (SECR, 'P',-1, NULL, NULL)
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (AComputer, Strife, 182, 0)
|
||
|
PROP_SpawnState (0)
|
||
|
PROP_SpawnHealth (80)
|
||
|
PROP_DeathState (4)
|
||
|
PROP_SpeedFixed (27) // was a byte in Strife
|
||
|
PROP_RadiusFixed (26)
|
||
|
PROP_HeightFixed (128)
|
||
|
PROP_MassLong (100000)
|
||
|
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_NOBLOOD)
|
||
|
PROP_Flags2 (MF2_FLOORCLIP)
|
||
|
PROP_Flags4 (MF4_INCOMBAT)
|
||
|
PROP_StrifeType (124)
|
||
|
PROP_DeathSound ("misc/explosion")
|
||
|
END_DEFAULTS
|
||
|
|
||
|
// Power Crystal ------------------------------------------------------------
|
||
|
|
||
|
void A_ExtraLightOff (AActor *);
|
||
|
void A_Explode512 (AActor *);
|
||
|
|
||
|
class APowerCrystal : public AActor
|
||
|
{
|
||
|
DECLARE_ACTOR (APowerCrystal, AActor)
|
||
|
};
|
||
|
|
||
|
FState APowerCrystal::States[] =
|
||
|
{
|
||
|
S_BRIGHT (CRYS, 'A', 16, A_LoopActiveSound, &States[1]),
|
||
|
S_BRIGHT (CRYS, 'B', 5, A_LoopActiveSound, &States[2]),
|
||
|
S_BRIGHT (CRYS, 'C', 4, A_LoopActiveSound, &States[3]),
|
||
|
S_BRIGHT (CRYS, 'D', 4, A_LoopActiveSound, &States[4]),
|
||
|
S_BRIGHT (CRYS, 'E', 4, A_LoopActiveSound, &States[5]),
|
||
|
S_BRIGHT (CRYS, 'F', 4, A_LoopActiveSound, &States[0]),
|
||
|
|
||
|
S_BRIGHT (BOOM, 'A', 0, A_Scream, &States[7]), // [RH] This seems like a good idea
|
||
|
S_BRIGHT (BOOM, 'A', 1, A_Explode512, &States[8]),
|
||
|
S_BRIGHT (BOOM, 'B', 3, A_GiveQuestItem, &States[9]),
|
||
|
S_BRIGHT (BOOM, 'C', 2, A_LightGoesOut, &States[10]),
|
||
|
S_BRIGHT (BOOM, 'D', 3, A_Bang4Cloud, &States[11]),
|
||
|
S_BRIGHT (BOOM, 'E', 3, NULL, &States[12]),
|
||
|
S_BRIGHT (BOOM, 'F', 3, NULL, &States[13]),
|
||
|
S_BRIGHT (BOOM, 'G', 3, A_Bang4Cloud, &States[14]),
|
||
|
S_BRIGHT (BOOM, 'H', 1, A_Explode512, &States[15]),
|
||
|
S_BRIGHT (BOOM, 'I', 3, NULL, &States[16]),
|
||
|
S_BRIGHT (BOOM, 'J', 3, A_Bang4Cloud, &States[17]),
|
||
|
S_BRIGHT (BOOM, 'K', 3, A_Bang4Cloud, &States[18]),
|
||
|
S_BRIGHT (BOOM, 'L', 3, A_Bang4Cloud, &States[19]),
|
||
|
S_BRIGHT (BOOM, 'M', 3, NULL, &States[20]),
|
||
|
S_BRIGHT (BOOM, 'N', 3, NULL, &States[21]),
|
||
|
S_BRIGHT (BOOM, 'O', 3, A_Bang4Cloud, &States[22]),
|
||
|
S_BRIGHT (BOOM, 'P', 3, NULL, &States[23]),
|
||
|
S_BRIGHT (BOOM, 'Q', 3, NULL, &States[24]),
|
||
|
S_BRIGHT (BOOM, 'R', 3, NULL, &States[25]),
|
||
|
S_BRIGHT (BOOM, 'S', 3, NULL, &States[26]),
|
||
|
S_BRIGHT (BOOM, 'T', 3, NULL, &States[27]),
|
||
|
S_BRIGHT (BOOM, 'U', 3, A_ExtraLightOff, &States[28]),
|
||
|
S_BRIGHT (BOOM, 'V', 3, NULL, &States[29]),
|
||
|
S_BRIGHT (BOOM, 'W', 3, NULL, &States[30]),
|
||
|
S_BRIGHT (BOOM, 'X', 3, NULL, &States[31]),
|
||
|
S_BRIGHT (BOOM, 'Y', 3, NULL, NULL)
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_ACTOR (APowerCrystal, Strife, 92, 0)
|
||
|
PROP_SpawnState (0)
|
||
|
PROP_SpawnHealth (50)
|
||
|
PROP_DeathState (6)
|
||
|
PROP_SpeedFixed (14) // Was a byte in Strife
|
||
|
PROP_RadiusFixed (20) // This size seems odd, but that's what the mobjinfo says
|
||
|
PROP_HeightFixed (16)
|
||
|
PROP_MassLong (99999999)
|
||
|
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_NOGRAVITY|MF_NOBLOOD)
|
||
|
PROP_Flags2 (MF2_FLOORCLIP)
|
||
|
PROP_StrifeType (201)
|
||
|
PROP_DeathSound ("misc/explosion")
|
||
|
PROP_ActiveSound ("misc/reactor")
|
||
|
END_DEFAULTS
|
||
|
|
||
|
void A_ExtraLightOff (AActor *self)
|
||
|
{
|
||
|
if (self->target != NULL && self->target->player != NULL)
|
||
|
{
|
||
|
self->target->player->extralight = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void A_Explode512 (AActor *self)
|
||
|
{
|
||
|
P_RadiusAttack (self, self->target, 512, 512, MOD_UNKNOWN, true);
|
||
|
if (self->target != NULL && self->target->player != NULL)
|
||
|
{
|
||
|
self->target->player->extralight = 5;
|
||
|
}
|
||
|
if (self->z <= self->floorz + (512<<FRACBITS))
|
||
|
{
|
||
|
P_HitFloor (self);
|
||
|
}
|
||
|
|
||
|
// Strife didn't do this next part, but it looks good
|
||
|
self->RenderStyle = STYLE_Add;
|
||
|
}
|
||
|
|
||
|
void A_LightGoesOut (AActor *self)
|
||
|
{
|
||
|
AActor *foo;
|
||
|
sector_t *sec = self->Sector;
|
||
|
vertex_t *spot;
|
||
|
fixed_t newheight;
|
||
|
|
||
|
sec->lightlevel = 0;
|
||
|
|
||
|
newheight = sec->FindLowestFloorSurrounding (&spot);
|
||
|
sec->floorplane.d = sec->floorplane.PointToDist (spot, newheight);
|
||
|
|
||
|
for (int i = 0; i < 8; ++i)
|
||
|
{
|
||
|
foo = Spawn<ARubble1> (self->x, self->y, self->z);
|
||
|
if (foo != NULL)
|
||
|
{
|
||
|
int t = pr_lightout() & 15;
|
||
|
foo->momx = (t - (pr_lightout() & 7)) << FRACBITS;
|
||
|
foo->momy = (pr_lightout.Random2() & 7) << FRACBITS;
|
||
|
foo->momz = (7 + (pr_lightout() & 3)) << FRACBITS;
|
||
|
}
|
||
|
}
|
||
|
}
|