1 /*
2 #include "info.h"
3 #include "a_pickups.h"
4 #include "d_player.h"
5 #include "gstrings.h"
6 #include "p_local.h"
7 #include "p_spec.h"
8 #include "a_strifeglobal.h"
9 #include "p_lnspec.h"
10 #include "p_enemy.h"
11 #include "s_sound.h"
12 #include "d_event.h"
13 #include "a_keys.h"
14 #include "c_console.h"
15 #include "templates.h"
16 #include "thingdef/thingdef.h"
17 #include "g_level.h"
18 #include "doomstat.h"
19 */
20 // Degnin Ore ---------------------------------------------------------------
21 
22 IMPLEMENT_CLASS(ADegninOre)
23 
DEFINE_ACTION_FUNCTION(AActor,A_RemoveForceField)24 DEFINE_ACTION_FUNCTION(AActor, A_RemoveForceField)
25 {
26 	self->flags &= ~MF_SPECIAL;
27 
28 	for (int i = 0; i < self->Sector->linecount; ++i)
29 	{
30 		line_t *line = self->Sector->lines[i];
31 		if (line->backsector != NULL && line->special == ForceField)
32 		{
33 			line->flags &= ~(ML_BLOCKING|ML_BLOCKEVERYTHING);
34 			line->special = 0;
35 			line->sidedef[0]->SetTexture(side_t::mid, FNullTextureID());
36 			line->sidedef[1]->SetTexture(side_t::mid, FNullTextureID());
37 		}
38 	}
39 }
40 
Use(bool pickup)41 bool ADegninOre::Use (bool pickup)
42 {
43 	if (pickup)
44 	{
45 		return false;
46 	}
47 	else
48 	{
49 		AInventory *drop;
50 
51 		// Increase the amount by one so that when DropInventory decrements it,
52 		// the actor will have the same number of beacons that he started with.
53 		// When we return to UseInventory, it will take care of decrementing
54 		// Amount again and disposing of this item if there are no more.
55 		Amount++;
56 		drop = Owner->DropInventory (this);
57 		if (drop == NULL)
58 		{
59 			Amount--;
60 			return false;
61 		}
62 		return true;
63 	}
64 }
65 
66 // Health Training ----------------------------------------------------------
67 
68 class AHealthTraining : public AInventory
69 {
70 	DECLARE_CLASS (AHealthTraining, AInventory)
71 public:
72 	bool TryPickup (AActor *&toucher);
73 };
74 
IMPLEMENT_CLASS(AHealthTraining)75 IMPLEMENT_CLASS (AHealthTraining)
76 
77 bool AHealthTraining::TryPickup (AActor *&toucher)
78 {
79 	if (Super::TryPickup (toucher))
80 	{
81 		toucher->GiveInventoryType (PClass::FindClass("GunTraining"));
82 		AInventory *coin = Spawn<ACoin> (0,0,0, NO_REPLACE);
83 		if (coin != NULL)
84 		{
85 			coin->Amount = toucher->player->mo->accuracy*5 + 300;
86 			if (!coin->CallTryPickup (toucher))
87 			{
88 				coin->Destroy ();
89 			}
90 		}
91 		return true;
92 	}
93 	return false;
94 }
95 
96 // Scanner ------------------------------------------------------------------
97 
98 class AScanner : public APowerupGiver
99 {
100 	DECLARE_CLASS (AScanner, APowerupGiver)
101 public:
102 	bool Use (bool pickup);
103 };
104 
IMPLEMENT_CLASS(AScanner)105 IMPLEMENT_CLASS (AScanner)
106 
107 bool AScanner::Use (bool pickup)
108 {
109 	if (!(level.flags2 & LEVEL2_ALLMAP))
110 	{
111 		if (Owner->CheckLocalView (consoleplayer))
112 		{
113 			C_MidPrint(SmallFont, GStrings("TXT_NEEDMAP"));
114 		}
115 		return false;
116 	}
117 	return Super::Use (pickup);
118 }
119 
120 // Prison Pass --------------------------------------------------------------
121 
122 class APrisonPass : public AKey
123 {
124 	DECLARE_CLASS (APrisonPass, AKey)
125 public:
126 	bool TryPickup (AActor *&toucher);
127 	bool SpecialDropAction (AActor *dropper);
128 };
129 
IMPLEMENT_CLASS(APrisonPass)130 IMPLEMENT_CLASS (APrisonPass)
131 
132 bool APrisonPass::TryPickup (AActor *&toucher)
133 {
134 	Super::TryPickup (toucher);
135 	EV_DoDoor (DDoor::doorOpen, NULL, toucher, 223, 2*FRACUNIT, 0, 0, 0);
136 	toucher->GiveInventoryType (QuestItemClasses[9]);
137 	return true;
138 }
139 
140 //============================================================================
141 //
142 // APrisonPass :: SpecialDropAction
143 //
144 // Trying to make a monster that drops a prison pass turns it into an
145 // OpenDoor223 item instead. That means the only way to get it in Strife
146 // is through dialog, which is why it doesn't have its own sprite.
147 //
148 //============================================================================
149 
SpecialDropAction(AActor * dropper)150 bool APrisonPass::SpecialDropAction (AActor *dropper)
151 {
152 	EV_DoDoor (DDoor::doorOpen, NULL, dropper, 223, 2*FRACUNIT, 0, 0, 0);
153 	Destroy ();
154 	return true;
155 }
156 
157 
158 //---------------------------------------------------------------------------
159 // Dummy items. They are just used by Strife to perform ---------------------
160 // actions and cannot be held. ----------------------------------------------
161 //---------------------------------------------------------------------------
162 
163 IMPLEMENT_CLASS (ADummyStrifeItem)
164 
165 // Sound the alarm! ---------------------------------------------------------
166 
167 class ARaiseAlarm : public ADummyStrifeItem
168 {
169 	DECLARE_CLASS (ARaiseAlarm, ADummyStrifeItem)
170 public:
171 	bool TryPickup (AActor *&toucher);
172 	bool SpecialDropAction (AActor *dropper);
173 };
174 
IMPLEMENT_CLASS(ARaiseAlarm)175 IMPLEMENT_CLASS (ARaiseAlarm)
176 
177 bool ARaiseAlarm::TryPickup (AActor *&toucher)
178 {
179 	P_NoiseAlert (toucher, toucher);
180 	CALL_ACTION(A_WakeOracleSpectre, toucher);
181 	GoAwayAndDie ();
182 	return true;
183 }
184 
SpecialDropAction(AActor * dropper)185 bool ARaiseAlarm::SpecialDropAction (AActor *dropper)
186 {
187 	P_NoiseAlert (dropper->target, dropper->target);
188 	if (dropper->target->CheckLocalView (consoleplayer))
189 	{
190 		Printf ("You Fool!  You've set off the alarm.\n");
191 	}
192 	Destroy ();
193 	return true;
194 }
195 
196 // Open door tag 222 --------------------------------------------------------
197 
198 class AOpenDoor222 : public ADummyStrifeItem
199 {
200 	DECLARE_CLASS (AOpenDoor222, ADummyStrifeItem)
201 public:
202 	bool TryPickup (AActor *&toucher);
203 };
204 
IMPLEMENT_CLASS(AOpenDoor222)205 IMPLEMENT_CLASS (AOpenDoor222)
206 
207 bool AOpenDoor222::TryPickup (AActor *&toucher)
208 {
209 	EV_DoDoor (DDoor::doorOpen, NULL, toucher, 222, 2*FRACUNIT, 0, 0, 0);
210 	GoAwayAndDie ();
211 	return true;
212 }
213 
214 // Close door tag 222 -------------------------------------------------------
215 
216 class ACloseDoor222 : public ADummyStrifeItem
217 {
218 	DECLARE_CLASS (ACloseDoor222, ADummyStrifeItem)
219 public:
220 	bool TryPickup (AActor *&toucher);
221 	bool SpecialDropAction (AActor *dropper);
222 };
223 
IMPLEMENT_CLASS(ACloseDoor222)224 IMPLEMENT_CLASS (ACloseDoor222)
225 
226 bool ACloseDoor222::TryPickup (AActor *&toucher)
227 {
228 	EV_DoDoor (DDoor::doorClose, NULL, toucher, 222, 2*FRACUNIT, 0, 0, 0);
229 	GoAwayAndDie ();
230 	return true;
231 }
232 
SpecialDropAction(AActor * dropper)233 bool ACloseDoor222::SpecialDropAction (AActor *dropper)
234 {
235 	EV_DoDoor (DDoor::doorClose, NULL, dropper, 222, 2*FRACUNIT, 0, 0, 0);
236 	if (dropper->target->CheckLocalView (consoleplayer))
237 	{
238 		Printf ("You're dead!  You set off the alarm.\n");
239 	}
240 	P_NoiseAlert (dropper->target, dropper->target);
241 	Destroy ();
242 	return true;
243 }
244 
245 // Open door tag 224 --------------------------------------------------------
246 
247 class AOpenDoor224 : public ADummyStrifeItem
248 {
249 	DECLARE_CLASS (AOpenDoor224, ADummyStrifeItem)
250 public:
251 	bool TryPickup (AActor *&toucher);
252 	bool SpecialDropAction (AActor *dropper);
253 };
254 
IMPLEMENT_CLASS(AOpenDoor224)255 IMPLEMENT_CLASS (AOpenDoor224)
256 
257 bool AOpenDoor224::TryPickup (AActor *&toucher)
258 {
259 	EV_DoDoor (DDoor::doorOpen, NULL, toucher, 224, 2*FRACUNIT, 0, 0, 0);
260 	GoAwayAndDie ();
261 	return true;
262 }
263 
SpecialDropAction(AActor * dropper)264 bool AOpenDoor224::SpecialDropAction (AActor *dropper)
265 {
266 	EV_DoDoor (DDoor::doorOpen, NULL, dropper, 224, 2*FRACUNIT, 0, 0, 0);
267 	Destroy ();
268 	return true;
269 }
270 
271 // Ammo ---------------------------------------------------------------------
272 
273 class AAmmoFillup : public ADummyStrifeItem
274 {
275 	DECLARE_CLASS (AAmmoFillup, ADummyStrifeItem)
276 public:
277 	bool TryPickup (AActor *&toucher);
278 };
279 
IMPLEMENT_CLASS(AAmmoFillup)280 IMPLEMENT_CLASS (AAmmoFillup)
281 
282 bool AAmmoFillup::TryPickup (AActor *&toucher)
283 {
284 	const PClass * clip = PClass::FindClass(NAME_ClipOfBullets);
285 	if (clip != NULL)
286 	{
287 		AInventory *item = toucher->FindInventory(clip);
288 		if (item == NULL)
289 		{
290 			item = toucher->GiveInventoryType (clip);
291 			if (item != NULL)
292 			{
293 				item->Amount = 50;
294 			}
295 		}
296 		else if (item->Amount < 50)
297 		{
298 			item->Amount = 50;
299 		}
300 		else
301 		{
302 			return false;
303 		}
304 		GoAwayAndDie ();
305 	}
306 	return true;
307 }
308 
309 // Health -------------------------------------------------------------------
310 
311 class AHealthFillup : public ADummyStrifeItem
312 {
313 	DECLARE_CLASS (AHealthFillup, ADummyStrifeItem)
314 public:
315 	bool TryPickup (AActor *&toucher);
316 };
317 
IMPLEMENT_CLASS(AHealthFillup)318 IMPLEMENT_CLASS (AHealthFillup)
319 
320 bool AHealthFillup::TryPickup (AActor *&toucher)
321 {
322 	static const int skillhealths[5] = { -100, -75, -50, -50, -100 };
323 
324 	int index = clamp<int>(gameskill, 0,4);
325 	if (!P_GiveBody (toucher, skillhealths[index]))
326 	{
327 		return false;
328 	}
329 	GoAwayAndDie ();
330 	return true;
331 }
332 
333 // Upgrade Stamina ----------------------------------------------------------
334 
IMPLEMENT_CLASS(AUpgradeStamina)335 IMPLEMENT_CLASS (AUpgradeStamina)
336 
337 bool AUpgradeStamina::TryPickup (AActor *&toucher)
338 {
339 	if (toucher->player == NULL)
340 		return false;
341 
342 	toucher->player->mo->stamina += Amount;
343 	if (toucher->player->mo->stamina >= MaxAmount)
344 		toucher->player->mo->stamina = MaxAmount;
345 
346 	P_GiveBody (toucher, -100);
347 	GoAwayAndDie ();
348 	return true;
349 }
350 
351 // Upgrade Accuracy ---------------------------------------------------------
352 
IMPLEMENT_CLASS(AUpgradeAccuracy)353 IMPLEMENT_CLASS (AUpgradeAccuracy)
354 
355 bool AUpgradeAccuracy::TryPickup (AActor *&toucher)
356 {
357 	if (toucher->player == NULL || toucher->player->mo->accuracy >= 100)
358 		return false;
359 	toucher->player->mo->accuracy += 10;
360 	GoAwayAndDie ();
361 	return true;
362 }
363 
364 // Start a slideshow --------------------------------------------------------
365 
IMPLEMENT_CLASS(ASlideshowStarter)366 IMPLEMENT_CLASS (ASlideshowStarter)
367 
368 bool ASlideshowStarter::TryPickup (AActor *&toucher)
369 {
370 	gameaction = ga_slideshow;
371 	if (level.levelnum == 10)
372 	{
373 		toucher->GiveInventoryType (QuestItemClasses[16]);
374 	}
375 	GoAwayAndDie ();
376 	return true;
377 }
378