1 #include "actor.h"
2 #include "info.h"
3 #include "a_pickups.h"
4 #include "a_action.h"
5 #include "m_random.h"
6 #include "p_local.h"
7 #include "s_sound.h"
8 #include "gstrings.h"
9 #include "thingdef/thingdef.h"
10 #include "p_enemy.h"
11 #include "a_specialspot.h"
12 #include "g_level.h"
13 #include "a_sharedglobal.h"
14 #include "templates.h"
15 #include "r_data/r_translate.h"
16 #include "doomstat.h"
17 #include "farchive.h"
18
19 // Include all the other Heretic stuff here to reduce compile time
20 #include "a_chicken.cpp"
21 #include "a_dsparil.cpp"
22 #include "a_hereticartifacts.cpp"
23 #include "a_hereticimp.cpp"
24 #include "a_hereticweaps.cpp"
25 #include "a_ironlich.cpp"
26 #include "a_knight.cpp"
27 #include "a_wizard.cpp"
28
29
30 static FRandom pr_podpain ("PodPain");
31 static FRandom pr_makepod ("MakePod");
32 static FRandom pr_teleg ("TeleGlitter");
33 static FRandom pr_teleg2 ("TeleGlitter2");
34 static FRandom pr_volcano ("VolcanoSet");
35 static FRandom pr_blast ("VolcanoBlast");
36 static FRandom pr_volcimpact ("VolcBallImpact");
37
38 //----------------------------------------------------------------------------
39 //
40 // PROC A_PodPain
41 //
42 //----------------------------------------------------------------------------
43
DEFINE_ACTION_FUNCTION_PARAMS(AActor,A_PodPain)44 DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain)
45 {
46 ACTION_PARAM_START(1);
47 ACTION_PARAM_CLASS(gootype, 0);
48
49 int count;
50 int chance;
51 AActor *goo;
52
53 chance = pr_podpain ();
54 if (chance < 128)
55 {
56 return;
57 }
58 for (count = chance > 240 ? 2 : 1; count; count--)
59 {
60 goo = Spawn(gootype, self->PosPlusZ(48*FRACUNIT), ALLOW_REPLACE);
61 goo->target = self;
62 goo->velx = pr_podpain.Random2() << 9;
63 goo->vely = pr_podpain.Random2() << 9;
64 goo->velz = FRACUNIT/2 + (pr_podpain() << 9);
65 }
66 }
67
68 //----------------------------------------------------------------------------
69 //
70 // PROC A_RemovePod
71 //
72 //----------------------------------------------------------------------------
73
DEFINE_ACTION_FUNCTION(AActor,A_RemovePod)74 DEFINE_ACTION_FUNCTION(AActor, A_RemovePod)
75 {
76 AActor *mo;
77
78 if ( (mo = self->master))
79 {
80 if (mo->special1 > 0)
81 {
82 mo->special1--;
83 }
84 }
85 }
86
87 //----------------------------------------------------------------------------
88 //
89 // PROC A_MakePod
90 //
91 //----------------------------------------------------------------------------
92
93 #define MAX_GEN_PODS 16
94
DEFINE_ACTION_FUNCTION_PARAMS(AActor,A_MakePod)95 DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod)
96 {
97 ACTION_PARAM_START(1);
98 ACTION_PARAM_CLASS(podtype, 0);
99
100 AActor *mo;
101 fixed_t x;
102 fixed_t y;
103
104 if (self->special1 == MAX_GEN_PODS)
105 { // Too many generated pods
106 return;
107 }
108 x = self->X();
109 y = self->Y();
110 mo = Spawn(podtype, x, y, ONFLOORZ, ALLOW_REPLACE);
111 if (!P_CheckPosition (mo, x, y))
112 { // Didn't fit
113 mo->Destroy ();
114 return;
115 }
116 mo->SetState (mo->FindState("Grow"));
117 P_ThrustMobj (mo, pr_makepod()<<24, (fixed_t)(4.5*FRACUNIT));
118 S_Sound (mo, CHAN_BODY, self->AttackSound, 1, ATTN_IDLE);
119 self->special1++; // Increment generated pod count
120 mo->master = self; // Link the generator to the pod
121 return;
122 }
123
124 //----------------------------------------------------------------------------
125 //
126 // PROC A_AccTeleGlitter
127 //
128 //----------------------------------------------------------------------------
129
DEFINE_ACTION_FUNCTION(AActor,A_AccTeleGlitter)130 DEFINE_ACTION_FUNCTION(AActor, A_AccTeleGlitter)
131 {
132 if (++self->health > 35)
133 {
134 self->velz += self->velz/2;
135 }
136 }
137
138
139 //----------------------------------------------------------------------------
140 //
141 // PROC A_VolcanoSet
142 //
143 //----------------------------------------------------------------------------
144
DEFINE_ACTION_FUNCTION(AActor,A_VolcanoSet)145 DEFINE_ACTION_FUNCTION(AActor, A_VolcanoSet)
146 {
147 self->tics = 105 + (pr_volcano() & 127);
148 }
149
150 //----------------------------------------------------------------------------
151 //
152 // PROC A_VolcanoBlast
153 //
154 //----------------------------------------------------------------------------
155
DEFINE_ACTION_FUNCTION(AActor,A_VolcanoBlast)156 DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast)
157 {
158 int i;
159 int count;
160 AActor *blast;
161 angle_t angle;
162
163 count = 1 + (pr_blast() % 3);
164 for (i = 0; i < count; i++)
165 {
166 blast = Spawn("VolcanoBlast", self->PosPlusZ(44*FRACUNIT), ALLOW_REPLACE);
167 blast->target = self;
168 angle = pr_blast () << 24;
169 blast->angle = angle;
170 angle >>= ANGLETOFINESHIFT;
171 blast->velx = FixedMul (1*FRACUNIT, finecosine[angle]);
172 blast->vely = FixedMul (1*FRACUNIT, finesine[angle]);
173 blast->velz = (FRACUNIT*5/2) + (pr_blast() << 10);
174 S_Sound (blast, CHAN_BODY, "world/volcano/shoot", 1, ATTN_NORM);
175 P_CheckMissileSpawn (blast, self->radius);
176 }
177 }
178
179 //----------------------------------------------------------------------------
180 //
181 // PROC A_VolcBallImpact
182 //
183 //----------------------------------------------------------------------------
184
DEFINE_ACTION_FUNCTION(AActor,A_VolcBallImpact)185 DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact)
186 {
187 unsigned int i;
188 AActor *tiny;
189 angle_t angle;
190
191 if (self->Z() <= self->floorz)
192 {
193 self->flags |= MF_NOGRAVITY;
194 self->gravity = FRACUNIT;
195 self->AddZ(28*FRACUNIT);
196 //self->velz = 3*FRACUNIT;
197 }
198 P_RadiusAttack (self, self->target, 25, 25, NAME_Fire, RADF_HURTSOURCE);
199 for (i = 0; i < 4; i++)
200 {
201 tiny = Spawn("VolcanoTBlast", self->Pos(), ALLOW_REPLACE);
202 tiny->target = self;
203 angle = i*ANG90;
204 tiny->angle = angle;
205 angle >>= ANGLETOFINESHIFT;
206 tiny->velx = FixedMul (FRACUNIT*7/10, finecosine[angle]);
207 tiny->vely = FixedMul (FRACUNIT*7/10, finesine[angle]);
208 tiny->velz = FRACUNIT + (pr_volcimpact() << 9);
209 P_CheckMissileSpawn (tiny, self->radius);
210 }
211 }
212
213