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