mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-07 02:20:51 +00:00
e4af82ae96
velocity, and now it's known as such. The actor variables momx/momy/momz are now known as velx/vely/velz, and the ACS functions GetActorMomX/Y/Z are now known as GetActorVelX/Y/Z. For compatibility, momx/momy/momz will continue to work as aliases from DECORATE. The ACS functions, however, require you to use the new name, since they never saw an official release yet. SVN r1689 (trunk)
712 lines
16 KiB
C++
712 lines
16 KiB
C++
#include "actor.h"
|
|
#include "g_level.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_strifeglobal.h"
|
|
#include "p_enemy.h"
|
|
#include "p_lnspec.h"
|
|
#include "c_console.h"
|
|
#include "thingdef/thingdef.h"
|
|
#include "doomstat.h"
|
|
#include "gstrings.h"
|
|
#include "a_keys.h"
|
|
#include "a_sharedglobal.h"
|
|
#include "templates.h"
|
|
#include "d_event.h"
|
|
#include "v_font.h"
|
|
|
|
// Include all the other Strife stuff here to reduce compile time
|
|
#include "a_acolyte.cpp"
|
|
#include "a_alienspectres.cpp"
|
|
#include "a_coin.cpp"
|
|
#include "a_crusader.cpp"
|
|
#include "a_entityboss.cpp"
|
|
#include "a_inquisitor.cpp"
|
|
#include "a_loremaster.cpp"
|
|
#include "a_macil.cpp"
|
|
#include "a_oracle.cpp"
|
|
#include "a_programmer.cpp"
|
|
#include "a_reaver.cpp"
|
|
#include "a_rebels.cpp"
|
|
#include "a_sentinel.cpp"
|
|
#include "a_spectral.cpp"
|
|
#include "a_stalker.cpp"
|
|
#include "a_strifeitems.cpp"
|
|
#include "a_strifeweapons.cpp"
|
|
#include "a_templar.cpp"
|
|
#include "a_thingstoblowup.cpp"
|
|
|
|
// Notes so I don't forget them:
|
|
// Strife does some extra stuff in A_Explode if a player caused the explosion. (probably NoiseAlert)
|
|
// See the instructions @ 21249.
|
|
//
|
|
// Strife's FLOATSPEED is 5 and not 4.
|
|
//
|
|
// In P_CheckMissileRange, mobjtypes 53,54,55,56,57,58 shift the distance right 4 bits (some, but not all the acolytes)
|
|
// mobjtypes 61,63,91 shift it right 1 bit
|
|
//
|
|
// When shooting missiles at something, if MF_SHADOW is set, the angle is adjusted with the formula:
|
|
// angle += pr_spawnmissile.Random2() << 21
|
|
// When MF_STRIFEx4000000 is set, the angle is adjusted similarly:
|
|
// angle += pr_spawnmissile.Random2() << 22
|
|
// Note that these numbers are different from those used by all the other Doom engine games.
|
|
|
|
/* These mobjinfos have been converted:
|
|
|
|
0 ForceFieldGuard
|
|
1 StrifePlayer
|
|
2 WeaponSmith
|
|
3 BarKeep
|
|
4 Armorer
|
|
5 Medic
|
|
6 Peasant1
|
|
7 Peasant2
|
|
8 Peasant3
|
|
9 Peasant4
|
|
10 Peasant5
|
|
11 Peasant6
|
|
12 Peasant7
|
|
13 Peasant8
|
|
14 Peasant9
|
|
15 Peasant10
|
|
16 Peasant11
|
|
17 Peasant12
|
|
18 Peasant13
|
|
19 Peasant14
|
|
20 Peasant15
|
|
21 Peasant16
|
|
22 Peasant17
|
|
23 Peasant18
|
|
24 Peasant19
|
|
25 Peasant20
|
|
26 Peasant21
|
|
27 Peasant22
|
|
28 Zombie
|
|
29 AcolyteToBe
|
|
30 ZombieSpawner
|
|
31 Tank1
|
|
32 Tank2
|
|
33 Tank3
|
|
34 Tank4
|
|
35 Tank5
|
|
36 Tank6
|
|
37 KneelingGuy
|
|
38 Beggar1
|
|
39 Beggar2
|
|
40 Beggar3
|
|
41 Beggar4
|
|
42 Beggar5
|
|
43 Rebel1
|
|
44 Rebel2
|
|
45 Rebel3
|
|
46 Rebel4
|
|
47 Rebel5
|
|
48 Rebel6
|
|
49 Macil1
|
|
50 Macil2
|
|
51 RocketTrail
|
|
52 Reaver
|
|
53 AcolyteTan
|
|
54 AcolyteRed
|
|
55 AcolyteRust
|
|
56 AcolyteGray
|
|
57 AcolyteDGreen
|
|
58 AcolyteGold
|
|
59 AcolyteLGreen
|
|
60 AcolyteBlue
|
|
61 AcolyteShadow
|
|
62 Templar
|
|
63 Crusader
|
|
64 StrifeBishop
|
|
65 Oracle
|
|
66 Loremaster (aka Priest)
|
|
67 AlienSpectre1
|
|
68 AlienChunkSmall
|
|
69 AlienChunkLarge
|
|
70 AlienSpectre2
|
|
71 AlienSpectre3
|
|
72 AlienSpectre4
|
|
73 AlienSpectre5
|
|
74 EntityBoss
|
|
75 EntitySecond
|
|
76 EntityNest
|
|
77 EntityPod
|
|
78 SpectralLightningH1
|
|
79 SpectralLightningH2
|
|
80 SpectralLightningBall1
|
|
81 SpectralLightningBall2
|
|
82 SpectralLightningH3
|
|
83 SpectralLightningHTail
|
|
84 SpectralLightningBigBall1
|
|
85 SpectralLightningBigBall2
|
|
86 SpectralLightningV1
|
|
87 SpectralLightningV2
|
|
88 SpectralLightningSpot
|
|
89 SpectralLightningBigV1
|
|
90 SpectralLightningBigV2
|
|
91 Sentinel
|
|
92 Stalker
|
|
93 Inquisitor
|
|
94 InquisitorArm
|
|
95 Programmer
|
|
96 ProgrammerBase
|
|
97 LoreShot
|
|
98 LoreShot2
|
|
99 MiniMissile
|
|
100 CrusaderMissile
|
|
101 BishopMissile
|
|
102 ElectricBolt
|
|
103 PoisonBolt
|
|
104 SentinelFX1
|
|
105 SentinelFX2
|
|
106 HEGrenade
|
|
107 PhosphorousGrenade
|
|
108 InquisitorShot
|
|
109 PhosphorousFire
|
|
110 MaulerTorpedo
|
|
111 MaulerTorpedoWave
|
|
112 FlameMissile
|
|
113 FastFlameMissile
|
|
114 MaulerPuff
|
|
115 StrifePuff
|
|
116 StrifeSpark
|
|
117 Blood
|
|
118 TeleportFog
|
|
119 ItemFog
|
|
120 --- Doomednum is 14, which makes it a teleport destination. Don't know why it's in the mobjinfo table.
|
|
121 KlaxonWarningLight
|
|
122 CeilingTurret
|
|
123 Piston
|
|
124 Computer
|
|
125 MedPatch
|
|
126 MedicalKit
|
|
127 SurgeryKit
|
|
128 DegninOre
|
|
129 MetalArmor
|
|
130 LeatherArmor
|
|
131 WaterBottle
|
|
132 Mug
|
|
133 BaseKey
|
|
134 GovsKey
|
|
135 Passcard
|
|
136 IDBadge
|
|
137 PrisonKey
|
|
138 SeveredHand
|
|
139 Power1Key
|
|
140 Power2Key
|
|
141 Power3Key
|
|
142 GoldKey
|
|
143 IDCard
|
|
144 SilverKey
|
|
145 OracleKey
|
|
146 MilitaryID
|
|
147 OrderKey
|
|
148 WarehouseKey
|
|
149 BrassKey
|
|
150 RedCrystalKey
|
|
151 BlueCrystalKey
|
|
152 ChapelKey
|
|
153 CatacombKey
|
|
154 SecurityKey
|
|
155 CoreKey
|
|
156 MaulerKey
|
|
157 FactoryKey
|
|
158 MineKey
|
|
159 NewKey5
|
|
160 ShadowArmor
|
|
161 EnvironmentalSuit
|
|
162 GuardUniform
|
|
163 OfficersUniform
|
|
164 StrifeMap
|
|
165 Scanner
|
|
166
|
|
167 Targeter
|
|
168 Coin
|
|
169 Gold10
|
|
170 Gold25
|
|
171 Gold50
|
|
172 Gold300
|
|
173 BeldinsRing
|
|
174 OfferingChalice
|
|
175 Ear
|
|
176 Communicator
|
|
177 HEGrenadeRounds
|
|
178 PhosphorusGrenadeRounds
|
|
179 ClipOfBullets
|
|
180 BoxOfBullets
|
|
181 MiniMissiles
|
|
182 CrateOfMissiles
|
|
183 EnergyPod
|
|
184 EnergyPack
|
|
185 PoisonBolts
|
|
186 ElectricBolts
|
|
187 AmmoSatchel
|
|
188 AssaultGun
|
|
189 AssaultGunStanding
|
|
190 FlameThrower
|
|
191 FlameThrowerParts
|
|
192 MiniMissileLauncher
|
|
193 Mauler
|
|
194 StrifeCrossbow
|
|
195 StrifeGrenadeLauncher
|
|
196 Sigil1
|
|
197 Sigil2
|
|
198 Sigil3
|
|
199 Sigil4
|
|
200 Sigil5
|
|
201 PowerCrystal
|
|
202 RatBuddy
|
|
203 WoodenBarrel
|
|
204 ExplosiveBarrel2
|
|
205 TargetPractice
|
|
206 LightSilverFluorescent
|
|
207 LightBrownFluorescent
|
|
208 LightGoldFluorescent
|
|
209 LightGlobe
|
|
210 PillarTechno
|
|
211 PillarAztec
|
|
212 PillarAztecDamaged
|
|
213 PillarAztecRuined
|
|
214 PillarHugeTech
|
|
215 PillarAlienPower
|
|
216 SStalactiteBig
|
|
217 SStalactiteSmall
|
|
218 SStalagmiteBig
|
|
219 CavePillarTop
|
|
220 CavePillarBottom
|
|
221 SStalagmiteSmall
|
|
222 Candle
|
|
223 StrifeCandelabra
|
|
224 WaterDropOnFloor
|
|
225 WaterfallSplash
|
|
226 WaterDrip
|
|
227 WaterFountain
|
|
228 HeartsInTank
|
|
229 TeleportSwirl
|
|
230 DeadCrusader
|
|
231 DeadStrifePlayer
|
|
232 DeadPeasant
|
|
233 DeadAcolyte
|
|
234 DeadReaver
|
|
235 DeadRebel
|
|
236 SacrificedGuy
|
|
237 PileOfGuts
|
|
238 StrifeBurningBarrel
|
|
239 BurningBowl
|
|
240 BurningBrazier
|
|
241 SmallTorchLit
|
|
242 SmallTorchUnlit
|
|
243 CeilingChain
|
|
244 CageLight
|
|
245 Statue
|
|
246 StatueRuined
|
|
247 MediumTorch
|
|
248 OutsideLamp
|
|
249 PoleLantern
|
|
250 SRock1
|
|
251 SRock2
|
|
252 SRock3
|
|
253 SRock4
|
|
254 StickInWater
|
|
255 Rubble1
|
|
256 Rubble2
|
|
257 Rubble3
|
|
258 Rubble4
|
|
259 Rubble5
|
|
260 Rubble6
|
|
261 Rubble7
|
|
262 Rubble8
|
|
263 SurgeryCrab
|
|
264 LargeTorch
|
|
265 HugeTorch
|
|
266 PalmTree
|
|
267 BigTree2
|
|
268 PottedTree
|
|
269 TreeStub
|
|
270 ShortBush
|
|
271 TallBush
|
|
272 ChimneyStack
|
|
273 BarricadeColumn
|
|
274 Pot
|
|
275 Pitcher
|
|
276 Stool
|
|
277 MetalPot
|
|
278 Tub
|
|
279 Anvil
|
|
280 TechLampSilver
|
|
281 TechLampBrass
|
|
282 Tray
|
|
283 AmmoFiller
|
|
284 SigilBanner
|
|
285 RebelBoots
|
|
286 RebelHelmet
|
|
287 RebelShirt
|
|
288 PowerCoupling
|
|
289 BrokenPowerCoupling
|
|
290 AlienBubbleColumn
|
|
291 AlienFloorBubble
|
|
292 AlienCeilingBubble
|
|
293 AlienAspClimber
|
|
294 AlienSpiderLight
|
|
295 Meat
|
|
296 Junk
|
|
297 FireDroplet
|
|
298 AmmoFillup
|
|
299 HealthFillup
|
|
300 Info
|
|
301 RaiseAlarm
|
|
302 OpenDoor222
|
|
303 CloseDoor222
|
|
304 PrisonPass
|
|
305 OpenDoor224
|
|
306 UpgradeStamina
|
|
307 UpgradeAccuracy
|
|
308 InterrogatorReport (seems to be unused)
|
|
309 HealthTraining
|
|
310 GunTraining
|
|
311 OraclePass
|
|
312 QuestItem1
|
|
313 QuestItem2
|
|
314 QuestItem3
|
|
315 QuestItem4
|
|
316 QuestItem5
|
|
317 QuestItem6
|
|
318 QuestItem7
|
|
319 QuestItem8
|
|
320 QuestItem9
|
|
321 QuestItem10
|
|
322 QuestItem11
|
|
323 QuestItem12
|
|
324 QuestItem13
|
|
325 QuestItem14
|
|
326 QuestItem15
|
|
327 QuestItem16
|
|
328 QuestItem17
|
|
329 QuestItem18
|
|
330 QuestItem19
|
|
331 QuestItem20
|
|
332 QuestItem21
|
|
333 QuestItem22
|
|
334 QuestItem23
|
|
335 QuestItem24
|
|
336 QuestItem25
|
|
337 QuestItem26
|
|
338 QuestItem27
|
|
339 QuestItem28
|
|
340 QuestItem29
|
|
341 QuestItem30
|
|
342 QuestItem31
|
|
343 SlideshowStarter
|
|
*/
|
|
|
|
static FRandom pr_gibtosser ("GibTosser");
|
|
|
|
// Force Field Guard --------------------------------------------------------
|
|
|
|
void A_RemoveForceField (AActor *);
|
|
|
|
class AForceFieldGuard : public AActor
|
|
{
|
|
DECLARE_CLASS (AForceFieldGuard, AActor)
|
|
public:
|
|
int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype);
|
|
};
|
|
|
|
IMPLEMENT_CLASS (AForceFieldGuard)
|
|
|
|
int AForceFieldGuard::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype)
|
|
{
|
|
if (inflictor == NULL || !inflictor->IsKindOf (RUNTIME_CLASS(ADegninOre)))
|
|
{
|
|
return -1;
|
|
}
|
|
return health;
|
|
}
|
|
|
|
// Kneeling Guy -------------------------------------------------------------
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_SetShadow)
|
|
{
|
|
self->flags |= MF_STRIFEx8000000|MF_SHADOW;
|
|
self->RenderStyle = STYLE_Translucent;
|
|
self->alpha = HR_SHADOW;
|
|
}
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_ClearShadow)
|
|
{
|
|
self->flags &= ~(MF_STRIFEx8000000|MF_SHADOW);
|
|
self->RenderStyle = STYLE_Normal;
|
|
self->alpha = OPAQUE;
|
|
}
|
|
|
|
static FRandom pr_gethurt ("HurtMe!");
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_GetHurt)
|
|
{
|
|
self->flags4 |= MF4_INCOMBAT;
|
|
if ((pr_gethurt() % 5) == 0)
|
|
{
|
|
S_Sound (self, CHAN_VOICE, self->PainSound, 1, ATTN_NORM);
|
|
self->health--;
|
|
}
|
|
if (self->health <= 0)
|
|
{
|
|
self->Die (self->target, self->target);
|
|
}
|
|
}
|
|
|
|
// Klaxon Warning Light -----------------------------------------------------
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_TurretLook)
|
|
{
|
|
AActor *target;
|
|
|
|
if (self->flags5 & MF5_INCONVERSATION)
|
|
return;
|
|
|
|
self->threshold = 0;
|
|
target = self->LastHeard;
|
|
if (target != NULL &&
|
|
target->health > 0 &&
|
|
target->flags & MF_SHOOTABLE &&
|
|
(self->flags & MF_FRIENDLY) != (target->flags & MF_FRIENDLY))
|
|
{
|
|
self->target = target;
|
|
if ((self->flags & MF_AMBUSH) && !P_CheckSight (self, target))
|
|
{
|
|
return;
|
|
}
|
|
if (self->SeeSound != 0)
|
|
{
|
|
S_Sound (self, CHAN_VOICE, self->SeeSound, 1, ATTN_NORM);
|
|
}
|
|
self->LastHeard = NULL;
|
|
self->threshold = 10;
|
|
self->SetState (self->SeeState);
|
|
}
|
|
}
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_KlaxonBlare)
|
|
{
|
|
if (--self->reactiontime < 0)
|
|
{
|
|
self->target = NULL;
|
|
self->reactiontime = self->GetDefault()->reactiontime;
|
|
CALL_ACTION(A_TurretLook, self);
|
|
if (self->target == NULL)
|
|
{
|
|
self->SetIdle();
|
|
}
|
|
else
|
|
{
|
|
self->reactiontime = 50;
|
|
}
|
|
}
|
|
if (self->reactiontime == 2)
|
|
{
|
|
// [RH] Unalert monsters near the alarm and not just those in the same sector as it.
|
|
P_NoiseAlert (NULL, self, false);
|
|
}
|
|
else if (self->reactiontime > 50)
|
|
{
|
|
S_Sound (self, CHAN_VOICE, "misc/alarm", 1, ATTN_NORM);
|
|
}
|
|
}
|
|
|
|
// Power Coupling -----------------------------------------------------------
|
|
|
|
class APowerCoupling : public AActor
|
|
{
|
|
DECLARE_CLASS (APowerCoupling, AActor)
|
|
public:
|
|
void Die (AActor *source, AActor *inflictor);
|
|
};
|
|
|
|
IMPLEMENT_CLASS (APowerCoupling)
|
|
|
|
void APowerCoupling::Die (AActor *source, AActor *inflictor)
|
|
{
|
|
Super::Die (source, inflictor);
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < MAXPLAYERS; ++i)
|
|
if (playeringame[i] && players[i].health > 0)
|
|
break;
|
|
|
|
if (i == MAXPLAYERS)
|
|
return;
|
|
|
|
// [RH] In case the player broke it with the dagger, alert the guards now.
|
|
if (LastHeard != source)
|
|
{
|
|
P_NoiseAlert (source, this);
|
|
}
|
|
EV_DoDoor (DDoor::doorClose, NULL, players[i].mo, 225, 2*FRACUNIT, 0, 0, 0);
|
|
EV_DoFloor (DFloor::floorLowerToHighest, NULL, 44, FRACUNIT, 0, 0, 0, false);
|
|
players[i].mo->GiveInventoryType (QuestItemClasses[5]);
|
|
S_Sound (CHAN_VOICE, "svox/voc13", 1, ATTN_NORM);
|
|
players[i].SetLogNumber (13);
|
|
P_DropItem (this, PClass::FindClass("BrokenPowerCoupling"), -1, 256);
|
|
Destroy ();
|
|
}
|
|
|
|
// Gibs for things that bleed -----------------------------------------------
|
|
|
|
class AMeat : public AActor
|
|
{
|
|
DECLARE_CLASS (AMeat, AActor)
|
|
public:
|
|
void BeginPlay ()
|
|
{
|
|
// Strife used mod 19, but there are 20 states. Hmm.
|
|
SetState (SpawnState + pr_gibtosser() % 20);
|
|
}
|
|
};
|
|
|
|
IMPLEMENT_CLASS (AMeat)
|
|
|
|
//==========================================================================
|
|
//
|
|
// A_TossGib
|
|
//
|
|
//==========================================================================
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_TossGib)
|
|
{
|
|
const char *gibtype = (self->flags & MF_NOBLOOD) ? "Junk" : "Meat";
|
|
AActor *gib = Spawn (gibtype, self->x, self->y, self->z + 24*FRACUNIT, ALLOW_REPLACE);
|
|
angle_t an;
|
|
int speed;
|
|
|
|
if (gib == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
an = pr_gibtosser() << 24;
|
|
gib->angle = an;
|
|
speed = pr_gibtosser() & 15;
|
|
gib->velx = speed * finecosine[an >> ANGLETOFINESHIFT];
|
|
gib->vely = speed * finesine[an >> ANGLETOFINESHIFT];
|
|
gib->velz = (pr_gibtosser() & 15) << FRACBITS;
|
|
}
|
|
|
|
//============================================================================
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_FLoopActiveSound)
|
|
{
|
|
if (self->ActiveSound != 0 && !(level.time & 7))
|
|
{
|
|
S_Sound (self, CHAN_VOICE, self->ActiveSound, 1, ATTN_NORM);
|
|
}
|
|
}
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_Countdown)
|
|
{
|
|
if (--self->reactiontime <= 0)
|
|
{
|
|
P_ExplodeMissile (self, NULL, NULL);
|
|
self->flags &= ~MF_SKULLFLY;
|
|
}
|
|
}
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_LoopActiveSound)
|
|
{
|
|
if (self->ActiveSound != 0 && !S_IsActorPlayingSomething (self, CHAN_VOICE, -1))
|
|
{
|
|
S_Sound (self, CHAN_VOICE|CHAN_LOOP, self->ActiveSound, 1, ATTN_NORM);
|
|
}
|
|
}
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain)
|
|
{
|
|
sector_t *sec = self->Sector;
|
|
|
|
if (self->z == sec->floorplane.ZatPoint (self->x, self->y))
|
|
{
|
|
if ((sec->special & 0xFF) == Damage_InstantDeath)
|
|
{
|
|
P_DamageMobj (self, NULL, NULL, 999, NAME_None);
|
|
}
|
|
else if ((sec->special & 0xFF) == Scroll_StrifeCurrent)
|
|
{
|
|
int anglespeed = sec->tag - 100;
|
|
fixed_t speed = (anglespeed % 10) << (FRACBITS - 4);
|
|
angle_t finean = (anglespeed / 10) << (32-3);
|
|
finean >>= ANGLETOFINESHIFT;
|
|
self->velx += FixedMul (speed, finecosine[finean]);
|
|
self->vely += FixedMul (speed, finesine[finean]);
|
|
}
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// A_ClearSoundTarget
|
|
//
|
|
//============================================================================
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_ClearSoundTarget)
|
|
{
|
|
AActor *actor;
|
|
|
|
self->Sector->SoundTarget = NULL;
|
|
for (actor = self->Sector->thinglist; actor != NULL; actor = actor->snext)
|
|
{
|
|
actor->LastHeard = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_ItBurnsItBurns)
|
|
{
|
|
S_Sound (self, CHAN_VOICE, "human/imonfire", 1, ATTN_NORM);
|
|
|
|
if (self->player != NULL && self->player->mo == self)
|
|
{
|
|
P_SetPsprite (self->player, ps_weapon, self->FindState("FireHands"));
|
|
P_SetPsprite (self->player, ps_flash, NULL);
|
|
self->player->ReadyWeapon = NULL;
|
|
self->player->PendingWeapon = WP_NOCHANGE;
|
|
self->player->playerstate = PST_LIVE;
|
|
self->player->extralight = 3;
|
|
}
|
|
}
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_DropFire)
|
|
{
|
|
AActor *drop = Spawn("FireDroplet", self->x, self->y, self->z + 24*FRACUNIT, ALLOW_REPLACE);
|
|
drop->velz = -FRACUNIT;
|
|
P_RadiusAttack (self, self, 64, 64, NAME_Fire, false);
|
|
}
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_CrispyPlayer)
|
|
{
|
|
if (self->player != NULL && self->player->mo == self)
|
|
{
|
|
self->player->playerstate = PST_DEAD;
|
|
P_SetPsprite (self->player, ps_weapon,
|
|
self->player->psprites[ps_weapon].state +
|
|
(self->FindState("FireHandsLower") - self->FindState("FireHands")));
|
|
}
|
|
}
|
|
|
|
DEFINE_ACTION_FUNCTION(AActor, A_HandLower)
|
|
{
|
|
if (self->player != NULL)
|
|
{
|
|
pspdef_t *psp = &self->player->psprites[ps_weapon];
|
|
psp->sy += FRACUNIT*9;
|
|
if (psp->sy > WEAPONBOTTOM*2)
|
|
{
|
|
P_SetPsprite (self->player, ps_weapon, NULL);
|
|
}
|
|
if (self->player->extralight > 0) self->player->extralight--;
|
|
}
|
|
}
|
|
|