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