1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 *
19 */
20
21 #include "GameScript/GameScript.h"
22
23 #include "GameScript/GSUtils.h"
24 #include "GameScript/Matching.h"
25
26 #include "DialogHandler.h"
27 #include "Game.h"
28 #include "GUI/GameControl.h"
29
30 namespace GemRB {
31
32 //-------------------------------------------------------------
33 // Object Functions
34 //-------------------------------------------------------------
35
36 //in this implementation, Myself will drop the parameter array
37 //i think all object filters could be expected to do so
38 //they should remove unnecessary elements from the parameters
Myself(const Scriptable * Sender,Targets * parameters,int ga_flags)39 Targets *GameScript::Myself(const Scriptable *Sender, Targets* parameters, int ga_flags)
40 {
41 parameters->Clear();
42 // hack to allow all Object methods to take a const Scriptable
43 Scriptable *snd;
44 Map *ca = Sender->GetCurrentArea();
45 if (ca) {
46 snd = ca->GetScriptableByGlobalID(Sender->GetGlobalID());
47 } else {
48 // just in case we're in the middle of a move
49 snd = core->GetGame()->GetActorByGlobalID(Sender->GetGlobalID());
50 }
51 parameters->AddTarget(snd, 0, ga_flags);
52 return parameters;
53 }
54
NearestDoor(const Scriptable *,Targets * parameters,int)55 Targets *GameScript::NearestDoor(const Scriptable */*Sender*/, Targets *parameters, int /*ga_flags*/)
56 {
57 return XthNearestDoor(parameters, 0);
58 }
59
SecondNearestDoor(const Scriptable *,Targets * parameters,int)60 Targets *GameScript::SecondNearestDoor(const Scriptable */*Sender*/, Targets *parameters, int /*ga_flags*/)
61 {
62 return XthNearestDoor(parameters, 1);
63 }
64
ThirdNearestDoor(const Scriptable *,Targets * parameters,int)65 Targets *GameScript::ThirdNearestDoor(const Scriptable */*Sender*/, Targets *parameters, int /*ga_flags*/)
66 {
67 return XthNearestDoor(parameters, 2);
68 }
69
FourthNearestDoor(const Scriptable *,Targets * parameters,int)70 Targets *GameScript::FourthNearestDoor(const Scriptable */*Sender*/, Targets *parameters, int /*ga_flags*/)
71 {
72 return XthNearestDoor(parameters, 3);
73 }
74
FifthNearestDoor(const Scriptable *,Targets * parameters,int)75 Targets *GameScript::FifthNearestDoor(const Scriptable */*Sender*/, Targets *parameters, int /*ga_flags*/)
76 {
77 return XthNearestDoor(parameters, 4);
78 }
79
SixthNearestDoor(const Scriptable *,Targets * parameters,int)80 Targets *GameScript::SixthNearestDoor(const Scriptable */*Sender*/, Targets *parameters, int /*ga_flags*/)
81 {
82 return XthNearestDoor(parameters, 5);
83 }
84
SeventhNearestDoor(const Scriptable *,Targets * parameters,int)85 Targets *GameScript::SeventhNearestDoor(const Scriptable */*Sender*/, Targets *parameters, int /*ga_flags*/)
86 {
87 return XthNearestDoor(parameters, 6);
88 }
89
EighthNearestDoor(const Scriptable *,Targets * parameters,int)90 Targets *GameScript::EighthNearestDoor(const Scriptable */*Sender*/, Targets *parameters, int /*ga_flags*/)
91 {
92 return XthNearestDoor(parameters, 7);
93 }
94
NinthNearestDoor(const Scriptable *,Targets * parameters,int)95 Targets *GameScript::NinthNearestDoor(const Scriptable */*Sender*/, Targets *parameters, int /*ga_flags*/)
96 {
97 return XthNearestDoor(parameters, 8);
98 }
99
TenthNearestDoor(const Scriptable *,Targets * parameters,int)100 Targets *GameScript::TenthNearestDoor(const Scriptable */*Sender*/, Targets *parameters, int /*ga_flags*/)
101 {
102 return XthNearestDoor(parameters, 9);
103 }
104
105 //in bg2 it is same as player1 so far
106 //in iwd2 this is the Gabber!!!
107 //but also, if there is no gabber, it is the first PC
108 //probably it is simply the nearest exportable character...
Protagonist(const Scriptable * Sender,Targets * parameters,int ga_flags)109 Targets *GameScript::Protagonist(const Scriptable *Sender, Targets *parameters, int ga_flags)
110 {
111 parameters->Clear();
112 //this sucks but IWD2 is like that...
113 static bool charnameisgabber = core->HasFeature(GF_CHARNAMEISGABBER);
114 if (charnameisgabber) {
115 const GameControl* gc = core->GetGameControl();
116 if (gc) {
117 parameters->AddTarget(gc->dialoghandler->GetSpeaker(), 0, ga_flags);
118 }
119 if (parameters->Count()) {
120 return parameters;
121 }
122 //ok, this will return the nearest PC in the first slot
123 const Game *game = core->GetGame();
124 int i = game->GetPartySize(false);
125 while(i--) {
126 Actor *target = game->GetPC(i,false);
127 parameters->AddTarget(target, Distance(Sender, target), ga_flags);
128 }
129 return parameters;
130 }
131 parameters->AddTarget(core->GetGame()->GetPC(0, false), 0, ga_flags);
132 return parameters;
133 }
134
135 //last talker
Gabber(const Scriptable *,Targets * parameters,int ga_flags)136 Targets *GameScript::Gabber(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
137 {
138 parameters->Clear();
139 const GameControl *gc = core->GetGameControl();
140 if (gc) {
141 parameters->AddTarget(gc->dialoghandler->GetSpeaker(), 0, ga_flags);
142 }
143 return parameters;
144 }
145
LastTrigger(const Scriptable * Sender,Targets * parameters,int ga_flags)146 Targets *GameScript::LastTrigger(const Scriptable *Sender, Targets *parameters, int ga_flags)
147 {
148 Scriptable *target = parameters->GetTarget(0, -1);
149 parameters->Clear();
150 if (target) {
151 target = Sender->GetCurrentArea()->GetActorByGlobalID(target->LastTrigger);
152 parameters->AddTarget(target, 0, ga_flags);
153 } else if (Sender->LastTrigger) {
154 target = Sender->GetCurrentArea()->GetActorByGlobalID(Sender->LastTrigger);
155 parameters->AddTarget(target, 0, ga_flags);
156 }
157 return parameters;
158 }
159
LastMarkedObject(const Scriptable * Sender,Targets * parameters,int ga_flags)160 Targets *GameScript::LastMarkedObject(const Scriptable *Sender, Targets *parameters, int ga_flags)
161 {
162 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
163 if (!actor) {
164 if (Sender->Type==ST_ACTOR) {
165 actor = (const Actor *) Sender;
166 }
167 }
168 parameters->Clear();
169 if (actor) {
170 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastMarked);
171 if (target) {
172 parameters->AddTarget(target, 0, ga_flags);
173 }
174 }
175 return parameters;
176 }
177
SpellTarget(const Scriptable * Sender,Targets * parameters,int ga_flags)178 Targets *GameScript::SpellTarget(const Scriptable *Sender, Targets *parameters, int ga_flags)
179 {
180 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
181 if (!actor) {
182 if (Sender->Type==ST_ACTOR) {
183 actor = (const Actor *) Sender;
184 }
185 }
186 parameters->Clear();
187 if (actor) {
188 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastSpellTarget);
189 if (target) {
190 parameters->AddTarget(target, 0, ga_flags);
191 }
192 }
193 return parameters;
194 }
195
196 //actions should always use LastMarkedObject, because LastSeen could be deleted
LastSeenBy(const Scriptable * Sender,Targets * parameters,int ga_flags)197 Targets *GameScript::LastSeenBy(const Scriptable *Sender, Targets *parameters, int ga_flags)
198 {
199 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
200 if (!actor) {
201 if (Sender->Type==ST_ACTOR) {
202 actor = (const Actor *) Sender;
203 }
204 }
205 parameters->Clear();
206 if (actor) {
207 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastSeen);
208 if (target) {
209 parameters->AddTarget(target, 0, ga_flags);
210 }
211 }
212 return parameters;
213 }
214
LastHelp(const Scriptable * Sender,Targets * parameters,int ga_flags)215 Targets *GameScript::LastHelp(const Scriptable *Sender, Targets *parameters, int ga_flags)
216 {
217 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
218 if (!actor) {
219 if (Sender->Type==ST_ACTOR) {
220 actor = (const Actor *) Sender;
221 }
222 }
223 parameters->Clear();
224 if (actor) {
225 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastHelp);
226 if (target) {
227 parameters->AddTarget(target, 0, ga_flags);
228 }
229 }
230 return parameters;
231 }
232
LastHeardBy(const Scriptable * Sender,Targets * parameters,int ga_flags)233 Targets *GameScript::LastHeardBy(const Scriptable *Sender, Targets *parameters, int ga_flags)
234 {
235 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
236 if (!actor) {
237 if (Sender->Type==ST_ACTOR) {
238 actor = (const Actor *) Sender;
239 }
240 }
241 parameters->Clear();
242 if (actor) {
243 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastHeard);
244 if (target) {
245 parameters->AddTarget(target, 0, ga_flags);
246 }
247 }
248 return parameters;
249 }
250
251 //i was told that Group means the same specifics, so this is just an
252 //object selector for everyone with the same specifics as the current object
GroupOf(const Scriptable * Sender,Targets * parameters,int ga_flags)253 Targets *GameScript::GroupOf(const Scriptable *Sender, Targets *parameters, int ga_flags)
254 {
255 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
256 if (!actor) {
257 if (Sender->Type==ST_ACTOR) {
258 actor = (const Actor *) Sender;
259 }
260 }
261 parameters->Clear();
262 if (actor) {
263 ieDword tmp = actor->GetStat(IE_SPECIFIC);
264 const Map *cm = Sender->GetCurrentArea();
265 int i = cm->GetActorCount(true);
266 while (i--) {
267 Actor *target=cm->GetActor(i,true);
268 if (target && (target->GetStat(IE_SPECIFIC)==tmp) ) {
269 parameters->AddTarget(target, 0, ga_flags);
270 }
271 }
272 }
273 return parameters;
274 }
275
276 /*this one is tough, but done */
ProtectorOf(const Scriptable * Sender,Targets * parameters,int ga_flags)277 Targets *GameScript::ProtectorOf(const Scriptable *Sender, Targets *parameters, int ga_flags)
278 {
279 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
280 if (!actor) {
281 if (Sender->Type==ST_ACTOR) {
282 actor = (const Actor *) Sender;
283 }
284 }
285 parameters->Clear();
286 /*if (actor) {
287 ieWord tmp = actor->LastProtected;
288 Map *cm = Sender->GetCurrentArea();
289 int i = cm->GetActorCount(true);
290 while (i--) {
291 Actor *target=cm->GetActor(i,true);
292 if (target && (target->LastProtected ==tmp) ) {
293 parameters->AddTarget(target, 0, ga_flags);
294 }
295 }
296 }*/
297 if (actor) {
298 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastProtector);
299 if (target) {
300 parameters->AddTarget(target, 0, ga_flags);
301 }
302 }
303 return parameters;
304 }
305
ProtectedBy(const Scriptable * Sender,Targets * parameters,int ga_flags)306 Targets *GameScript::ProtectedBy(const Scriptable *Sender, Targets *parameters, int ga_flags)
307 {
308 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
309 if (!actor) {
310 if (Sender->Type==ST_ACTOR) {
311 actor = (const Actor *) Sender;
312 }
313 }
314 parameters->Clear();
315 if (actor) {
316 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastProtectee);
317 if (target) {
318 parameters->AddTarget(target, 0, ga_flags);
319 }
320 }
321 return parameters;
322 }
323
LastCommandedBy(const Scriptable * Sender,Targets * parameters,int ga_flags)324 Targets *GameScript::LastCommandedBy(const Scriptable *Sender, Targets *parameters, int ga_flags)
325 {
326 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
327 if (!actor) {
328 if (Sender->Type==ST_ACTOR) {
329 actor = (const Actor *) Sender;
330 }
331 }
332 parameters->Clear();
333 if (actor) {
334 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastCommander);
335 if (target) {
336 parameters->AddTarget(target, 0, ga_flags);
337 }
338 }
339 return parameters;
340 }
341
342 // this is essentially a LastTargetedBy(0) - or MySelf
343 // but IWD2 defines it
MyTarget(const Scriptable * Sender,Targets * parameters,int ga_flags)344 Targets *GameScript::MyTarget(const Scriptable *Sender, Targets *parameters, int ga_flags)
345 {
346 const Scriptable *actor = parameters->GetTarget(0, -1);
347 if (!actor) {
348 actor = Sender;
349 }
350 parameters->Clear();
351 if (actor) {
352 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->MyTarget);
353 if (target) {
354 parameters->AddTarget(target, 0, ga_flags);
355 }
356 }
357 return parameters;
358 }
359
LastTargetedBy(const Scriptable * Sender,Targets * parameters,int ga_flags)360 Targets *GameScript::LastTargetedBy(const Scriptable *Sender, Targets *parameters, int ga_flags)
361 {
362 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
363 return GetMyTarget(Sender, actor, parameters, ga_flags);
364 }
365
LastAttackerOf(const Scriptable * Sender,Targets * parameters,int ga_flags)366 Targets *GameScript::LastAttackerOf(const Scriptable *Sender, Targets *parameters, int ga_flags)
367 {
368 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
369 if (!actor) {
370 if (Sender->Type==ST_ACTOR) {
371 actor = (const Actor *) Sender;
372 }
373 }
374 parameters->Clear();
375 if (actor) {
376 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastAttacker);
377 if (target) {
378 parameters->AddTarget(target, 0, ga_flags);
379 }
380 }
381 return parameters;
382 }
383
LastHitter(const Scriptable * Sender,Targets * parameters,int ga_flags)384 Targets *GameScript::LastHitter(const Scriptable *Sender, Targets *parameters, int ga_flags)
385 {
386 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
387 if (!actor) {
388 if (Sender->Type==ST_ACTOR) {
389 actor = (const Actor *) Sender;
390 }
391 }
392 parameters->Clear();
393 if (actor) {
394 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastHitter);
395 if (target) {
396 parameters->AddTarget(target, 0, ga_flags);
397 }
398 }
399 return parameters;
400 }
401
LeaderOf(const Scriptable * Sender,Targets * parameters,int ga_flags)402 Targets *GameScript::LeaderOf(const Scriptable *Sender, Targets *parameters, int ga_flags)
403 {
404 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
405 if (!actor) {
406 if (Sender->Type==ST_ACTOR) {
407 actor = (const Actor *) Sender;
408 }
409 }
410 parameters->Clear();
411 if (actor) {
412 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastFollowed);
413 if (target) {
414 parameters->AddTarget(target, 0, ga_flags);
415 }
416 }
417 return parameters;
418 }
419
LastTalkedToBy(const Scriptable * Sender,Targets * parameters,int ga_flags)420 Targets *GameScript::LastTalkedToBy(const Scriptable *Sender, Targets *parameters, int ga_flags)
421 {
422 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
423 if (!actor) {
424 if (Sender->Type==ST_ACTOR) {
425 actor = (const Actor *) Sender;
426 }
427 }
428 parameters->Clear();
429 if (actor) {
430 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastTalker);
431 if (target) {
432 parameters->AddTarget(target, 0, ga_flags);
433 }
434 }
435 return parameters;
436 }
437
LastSummonerOf(const Scriptable * Sender,Targets * parameters,int ga_flags)438 Targets *GameScript::LastSummonerOf(const Scriptable *Sender, Targets *parameters, int ga_flags)
439 {
440 const Actor *actor = (Actor *) parameters->GetTarget(0, ST_ACTOR);
441 if (!actor) {
442 if (Sender->Type==ST_ACTOR) {
443 actor = (const Actor *) Sender;
444 }
445 }
446 parameters->Clear();
447 if (actor) {
448 Actor *target = actor->GetCurrentArea()->GetActorByGlobalID(actor->LastSummoner);
449 if (target) {
450 parameters->AddTarget(target, 0, ga_flags);
451 }
452 }
453 return parameters;
454 }
455
PlayerX(Targets * parameters,int ga_flags,unsigned int slot,bool fill=false)456 inline Targets *PlayerX(Targets *parameters, int ga_flags, unsigned int slot, bool fill = false)
457 {
458 parameters->Clear();
459 Actor *pc;
460 if (fill) {
461 pc = core->GetGame()->FindPC(slot + 1);
462 } else {
463 pc = core->GetGame()->GetPC(slot, false);
464 }
465 parameters->AddTarget(pc, 0, ga_flags);
466 return parameters;
467 }
468
Player1(const Scriptable *,Targets * parameters,int ga_flags)469 Targets *GameScript::Player1(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
470 {
471 return PlayerX(parameters, ga_flags, 0);
472 }
473
Player1Fill(const Scriptable *,Targets * parameters,int ga_flags)474 Targets *GameScript::Player1Fill(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
475 {
476 return PlayerX(parameters, ga_flags, 0, true);
477 }
478
Player2(const Scriptable *,Targets * parameters,int ga_flags)479 Targets *GameScript::Player2(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
480 {
481 return PlayerX(parameters, ga_flags, 1);
482 }
483
Player2Fill(const Scriptable *,Targets * parameters,int ga_flags)484 Targets *GameScript::Player2Fill(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
485 {
486 return PlayerX(parameters, ga_flags, 1, true);
487 }
488
Player3(const Scriptable *,Targets * parameters,int ga_flags)489 Targets *GameScript::Player3(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
490 {
491 return PlayerX(parameters, ga_flags, 2);
492 }
493
Player3Fill(const Scriptable *,Targets * parameters,int ga_flags)494 Targets *GameScript::Player3Fill(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
495 {
496 return PlayerX(parameters, ga_flags, 2, true);
497 }
498
Player4(const Scriptable *,Targets * parameters,int ga_flags)499 Targets *GameScript::Player4(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
500 {
501 return PlayerX(parameters, ga_flags, 3);
502 }
503
Player4Fill(const Scriptable *,Targets * parameters,int ga_flags)504 Targets *GameScript::Player4Fill(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
505 {
506 return PlayerX(parameters, ga_flags, 3, true);
507 }
508
Player5(const Scriptable *,Targets * parameters,int ga_flags)509 Targets *GameScript::Player5(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
510 {
511 return PlayerX(parameters, ga_flags, 4);
512 }
513
Player5Fill(const Scriptable *,Targets * parameters,int ga_flags)514 Targets *GameScript::Player5Fill(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
515 {
516 return PlayerX(parameters, ga_flags, 4, true);
517 }
518
Player6(const Scriptable *,Targets * parameters,int ga_flags)519 Targets *GameScript::Player6(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
520 {
521 return PlayerX(parameters, ga_flags, 5);
522 }
523
Player6Fill(const Scriptable *,Targets * parameters,int ga_flags)524 Targets *GameScript::Player6Fill(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
525 {
526 return PlayerX(parameters, ga_flags, 5, true);
527 }
528
Player7(const Scriptable *,Targets * parameters,int ga_flags)529 Targets *GameScript::Player7(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
530 {
531 return PlayerX(parameters, ga_flags, 6);
532 }
533
Player7Fill(const Scriptable *,Targets * parameters,int ga_flags)534 Targets *GameScript::Player7Fill(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
535 {
536 return PlayerX(parameters, ga_flags, 6, true);
537 }
538
Player8(const Scriptable *,Targets * parameters,int ga_flags)539 Targets *GameScript::Player8(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
540 {
541 return PlayerX(parameters, ga_flags, 7);
542 }
543
Player8Fill(const Scriptable *,Targets * parameters,int ga_flags)544 Targets *GameScript::Player8Fill(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
545 {
546 return PlayerX(parameters, ga_flags, 7, true);
547 }
548
Player9(const Scriptable *,Targets * parameters,int ga_flags)549 Targets *GameScript::Player9(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
550 {
551 return PlayerX(parameters, ga_flags, 8);
552 }
553
Player9Fill(const Scriptable *,Targets * parameters,int ga_flags)554 Targets *GameScript::Player9Fill(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
555 {
556 return PlayerX(parameters, ga_flags, 8, true);
557 }
558
Player10(const Scriptable *,Targets * parameters,int ga_flags)559 Targets *GameScript::Player10(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
560 {
561 return PlayerX(parameters, ga_flags, 9);
562 }
563
Player10Fill(const Scriptable *,Targets * parameters,int ga_flags)564 Targets *GameScript::Player10Fill(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
565 {
566 return PlayerX(parameters, ga_flags, 9, true);
567 }
568
569 //This filter works only on the Party - silly restriction, but the dataset expects this
StrongestOfMale(const Scriptable * Sender,Targets * parameters,int ga_flags)570 Targets *GameScript::StrongestOfMale(const Scriptable *Sender, Targets *parameters, int ga_flags)
571 {
572 const Map *area = Sender->GetCurrentArea();
573 const Game *game = core->GetGame();
574 Scriptable* scr = NULL;
575 int besthp = 0;
576 int i = game->GetPartySize(false);
577 while (i--) {
578 Actor *actor = game->GetPC(i, false);
579 if (actor->GetStat(IE_SEX)!=SEX_MALE) continue;
580 if(actor->GetCurrentArea() == area) {
581 int hp = actor->GetStat(IE_HITPOINTS);
582 if (!scr || besthp<hp) {
583 besthp=hp;
584 scr=actor;
585 }
586 }
587 }
588 parameters->Clear();
589 parameters->AddTarget(scr, 0, ga_flags);
590 return parameters;
591 }
592
593 //This filter works only on the Party - silly restriction, but the dataset expects this
StrongestOf(const Scriptable * Sender,Targets * parameters,int ga_flags)594 Targets *GameScript::StrongestOf(const Scriptable *Sender, Targets *parameters, int ga_flags)
595 {
596 const Map *area = Sender->GetCurrentArea();
597 const Game *game = core->GetGame();
598 Scriptable* scr = NULL;
599 int besthp = 0;
600 int i = game->GetPartySize(false);
601 while (i--) {
602 Actor *actor = game->GetPC(i, false);
603 if(actor->GetCurrentArea() == area) {
604 int hp = actor->GetStat(IE_HITPOINTS);
605 if (!scr || besthp<hp) {
606 besthp=hp;
607 scr=actor;
608 }
609 }
610 }
611 parameters->Clear();
612 parameters->AddTarget(scr, 0, ga_flags);
613 return parameters;
614 }
615
616 //This filter works only on the Party - silly restriction, but the dataset expects this
WeakestOf(const Scriptable * Sender,Targets * parameters,int ga_flags)617 Targets *GameScript::WeakestOf(const Scriptable *Sender, Targets *parameters, int ga_flags)
618 {
619 const Map *area = Sender->GetCurrentArea();
620 const Game *game = core->GetGame();
621 Scriptable* scr = NULL;
622 int worsthp = 0;
623 int i = game->GetPartySize(false);
624 while (i--) {
625 Actor *actor = game->GetPC(i, false);
626 if(actor->GetCurrentArea() == area) {
627 int hp = actor->GetStat(IE_HITPOINTS);
628 if (!scr || worsthp>hp) {
629 worsthp=hp;
630 scr=actor;
631 }
632 }
633 }
634 parameters->Clear();
635 parameters->AddTarget(scr, 0, ga_flags);
636 return parameters;
637 }
638
639 //This filter works only on the Party - silly restriction, but the dataset expects this
BestAC(const Scriptable * Sender,Targets * parameters,int ga_flags)640 Targets *GameScript::BestAC(const Scriptable *Sender, Targets *parameters, int ga_flags)
641 {
642 const Map *area = Sender->GetCurrentArea();
643 const Game *game = core->GetGame();
644 Scriptable* scr = NULL;
645 int bestac = 0;
646 int i = game->GetPartySize(false);
647 while (i--) {
648 Actor *actor = game->GetPC(i, false);
649 if(actor->GetCurrentArea() == area) {
650 int ac = actor->AC.GetTotal();
651 if (!scr || bestac>ac) {
652 bestac=ac;
653 scr=actor;
654 }
655 }
656 }
657 parameters->Clear();
658 parameters->AddTarget(scr, 0, ga_flags);
659 return parameters;
660 }
661
662 //This filter works only on the Party - silly restriction, but the dataset expects this
WorstAC(const Scriptable * Sender,Targets * parameters,int ga_flags)663 Targets *GameScript::WorstAC(const Scriptable *Sender, Targets *parameters, int ga_flags)
664 {
665 const Map *area = Sender->GetCurrentArea();
666 const Game *game = core->GetGame();
667 Scriptable* scr = NULL;
668 int worstac = 0;
669 int i = game->GetPartySize(false);
670 while (i--) {
671 Actor *actor = game->GetPC(i, false);
672 if(actor->GetCurrentArea() == area) {
673 int ac = actor->AC.GetTotal();
674 if (!scr || worstac<ac) {
675 worstac=ac;
676 scr=actor;
677 }
678 }
679 }
680 parameters->Clear();
681 parameters->AddTarget(scr, 0, ga_flags);
682 return parameters;
683 }
684
685 //This filter works only on the Party - silly restriction, but the dataset expects this
MostDamagedOf(const Scriptable * Sender,Targets * parameters,int ga_flags)686 Targets *GameScript::MostDamagedOf(const Scriptable *Sender, Targets *parameters, int ga_flags)
687 {
688 const Map *area = Sender->GetCurrentArea();
689 const Game *game = core->GetGame();
690 Scriptable* scr = NULL;
691 int worsthp = 0;
692 int i = game->GetPartySize(false);
693 while (i--) {
694 Actor *actor = game->GetPC(i, false);
695 if(actor->GetCurrentArea() == area) {
696 int hp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
697 if (!scr || hp>worsthp) {
698 worsthp=hp;
699 scr=actor;
700 }
701 }
702 }
703 parameters->Clear();
704 parameters->AddTarget(scr, 0, ga_flags);
705 return parameters;
706 }
707
708 //This filter works only on the Party - silly restriction, but the dataset expects this
709 //For example the beholder01 script
LeastDamagedOf(const Scriptable * Sender,Targets * parameters,int ga_flags)710 Targets *GameScript::LeastDamagedOf(const Scriptable *Sender, Targets *parameters, int ga_flags)
711 {
712 const Map *area = Sender->GetCurrentArea();
713 const Game *game = core->GetGame();
714 Scriptable* scr = NULL;
715 int besthp = 0;
716 int i = game->GetPartySize(false);
717 while (i--) {
718 Actor *actor = game->GetPC(i, false);
719 if(actor->GetCurrentArea() == area) {
720 int hp=actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
721 if (!scr || besthp<hp) {
722 besthp=hp;
723 scr=actor;
724 }
725 }
726 }
727 parameters->Clear();
728 parameters->AddTarget(scr, 0, ga_flags);
729 return parameters;
730 }
731
Farthest(const Scriptable *,Targets * parameters,int ga_flags)732 Targets *GameScript::Farthest(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
733 {
734 const targettype *t = parameters->GetLastTarget(ST_ACTOR);
735 parameters->Clear();
736 if (t) {
737 parameters->AddTarget(t->actor, 0, ga_flags);
738 }
739 return parameters;
740 }
741
FarthestEnemyOf(const Scriptable *,Targets * parameters,int ga_flags)742 Targets *GameScript::FarthestEnemyOf(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
743 {
744 return XthNearestEnemyOf(parameters, -1, ga_flags);
745 }
746
NearestEnemyOf(const Scriptable *,Targets * parameters,int ga_flags)747 Targets *GameScript::NearestEnemyOf(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
748 {
749 return XthNearestEnemyOf(parameters, 0, ga_flags);
750 }
751
SecondNearestEnemyOf(const Scriptable *,Targets * parameters,int ga_flags)752 Targets *GameScript::SecondNearestEnemyOf(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
753 {
754 return XthNearestEnemyOf(parameters, 1, ga_flags);
755 }
756
ThirdNearestEnemyOf(const Scriptable *,Targets * parameters,int ga_flags)757 Targets *GameScript::ThirdNearestEnemyOf(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
758 {
759 return XthNearestEnemyOf(parameters, 2, ga_flags);
760 }
761
FourthNearestEnemyOf(const Scriptable *,Targets * parameters,int ga_flags)762 Targets *GameScript::FourthNearestEnemyOf(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
763 {
764 return XthNearestEnemyOf(parameters, 3, ga_flags);
765 }
766
FifthNearestEnemyOf(const Scriptable *,Targets * parameters,int ga_flags)767 Targets *GameScript::FifthNearestEnemyOf(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
768 {
769 return XthNearestEnemyOf(parameters, 4, ga_flags);
770 }
771
SixthNearestEnemyOf(const Scriptable *,Targets * parameters,int ga_flags)772 Targets *GameScript::SixthNearestEnemyOf(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
773 {
774 return XthNearestEnemyOf(parameters, 5, ga_flags);
775 }
776
SeventhNearestEnemyOf(const Scriptable *,Targets * parameters,int ga_flags)777 Targets *GameScript::SeventhNearestEnemyOf(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
778 {
779 return XthNearestEnemyOf(parameters, 6, ga_flags);
780 }
781
EighthNearestEnemyOf(const Scriptable *,Targets * parameters,int ga_flags)782 Targets *GameScript::EighthNearestEnemyOf(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
783 {
784 return XthNearestEnemyOf(parameters, 7, ga_flags);
785 }
786
NinthNearestEnemyOf(const Scriptable *,Targets * parameters,int ga_flags)787 Targets *GameScript::NinthNearestEnemyOf(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
788 {
789 return XthNearestEnemyOf(parameters, 8, ga_flags);
790 }
791
TenthNearestEnemyOf(const Scriptable *,Targets * parameters,int ga_flags)792 Targets *GameScript::TenthNearestEnemyOf(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
793 {
794 return XthNearestEnemyOf(parameters, 9, ga_flags);
795 }
796
NearestEnemySummoned(const Scriptable * Sender,Targets * parameters,int ga_flags)797 Targets *GameScript::NearestEnemySummoned(const Scriptable *Sender, Targets *parameters, int ga_flags)
798 {
799 return ClosestEnemySummoned(Sender, parameters, ga_flags);
800 }
801
NearestEnemyOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)802 Targets *GameScript::NearestEnemyOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
803 {
804 return XthNearestEnemyOfType(Sender, parameters, 0, ga_flags);
805 }
806
SecondNearestEnemyOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)807 Targets *GameScript::SecondNearestEnemyOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
808 {
809 return XthNearestEnemyOfType(Sender, parameters, 1, ga_flags);
810 }
811
ThirdNearestEnemyOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)812 Targets *GameScript::ThirdNearestEnemyOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
813 {
814 return XthNearestEnemyOfType(Sender, parameters, 2, ga_flags);
815 }
816
FourthNearestEnemyOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)817 Targets *GameScript::FourthNearestEnemyOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
818 {
819 return XthNearestEnemyOfType(Sender, parameters, 3, ga_flags);
820 }
821
FifthNearestEnemyOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)822 Targets *GameScript::FifthNearestEnemyOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
823 {
824 return XthNearestEnemyOfType(Sender, parameters, 4, ga_flags);
825 }
826
SixthNearestEnemyOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)827 Targets *GameScript::SixthNearestEnemyOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
828 {
829 return XthNearestEnemyOfType(Sender, parameters, 5, ga_flags);
830 }
831
SeventhNearestEnemyOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)832 Targets *GameScript::SeventhNearestEnemyOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
833 {
834 return XthNearestEnemyOfType(Sender, parameters, 6, ga_flags);
835 }
836
EighthNearestEnemyOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)837 Targets *GameScript::EighthNearestEnemyOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
838 {
839 return XthNearestEnemyOfType(Sender, parameters, 7, ga_flags);
840 }
841
NinthNearestEnemyOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)842 Targets *GameScript::NinthNearestEnemyOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
843 {
844 return XthNearestEnemyOfType(Sender, parameters, 8, ga_flags);
845 }
846
TenthNearestEnemyOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)847 Targets *GameScript::TenthNearestEnemyOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
848 {
849 return XthNearestEnemyOfType(Sender, parameters, 9, ga_flags);
850 }
851
NearestMyGroupOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)852 Targets *GameScript::NearestMyGroupOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
853 {
854 return XthNearestMyGroupOfType(Sender, parameters, 0, ga_flags);
855 }
856
SecondNearestMyGroupOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)857 Targets *GameScript::SecondNearestMyGroupOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
858 {
859 return XthNearestMyGroupOfType(Sender, parameters, 1, ga_flags);
860 }
861
ThirdNearestMyGroupOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)862 Targets *GameScript::ThirdNearestMyGroupOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
863 {
864 return XthNearestMyGroupOfType(Sender, parameters, 2, ga_flags);
865 }
866
FourthNearestMyGroupOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)867 Targets *GameScript::FourthNearestMyGroupOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
868 {
869 return XthNearestMyGroupOfType(Sender, parameters, 3, ga_flags);
870 }
871
FifthNearestMyGroupOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)872 Targets *GameScript::FifthNearestMyGroupOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
873 {
874 return XthNearestMyGroupOfType(Sender, parameters, 4, ga_flags);
875 }
876
SixthNearestMyGroupOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)877 Targets *GameScript::SixthNearestMyGroupOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
878 {
879 return XthNearestMyGroupOfType(Sender, parameters, 5, ga_flags);
880 }
881
SeventhNearestMyGroupOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)882 Targets *GameScript::SeventhNearestMyGroupOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
883 {
884 return XthNearestMyGroupOfType(Sender, parameters, 6, ga_flags);
885 }
886
EighthNearestMyGroupOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)887 Targets *GameScript::EighthNearestMyGroupOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
888 {
889 return XthNearestMyGroupOfType(Sender, parameters, 7, ga_flags);
890 }
891
NinthNearestMyGroupOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)892 Targets *GameScript::NinthNearestMyGroupOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
893 {
894 return XthNearestMyGroupOfType(Sender, parameters, 8, ga_flags);
895 }
896
TenthNearestMyGroupOfType(const Scriptable * Sender,Targets * parameters,int ga_flags)897 Targets *GameScript::TenthNearestMyGroupOfType(const Scriptable *Sender, Targets *parameters, int ga_flags)
898 {
899 return XthNearestMyGroupOfType(Sender, parameters, 9, ga_flags);
900 }
901
902 /* returns only living PC's? if not, alter getpartysize/getpc flag*/
NearestPC(const Scriptable * Sender,Targets * parameters,int ga_flags)903 Targets *GameScript::NearestPC(const Scriptable *Sender, Targets *parameters, int ga_flags)
904 {
905 parameters->Clear();
906 const Map *map = Sender->GetCurrentArea();
907 const Game *game = core->GetGame();
908 int i = game->GetPartySize(true);
909 int mindist = -1;
910 Actor *ac = NULL;
911 while (i--) {
912 Actor *newactor=game->GetPC(i,true);
913 //NearestPC for PC's will not give themselves as a result
914 //this might be different from the original engine
915 if (Sender->Type == ST_ACTOR && (newactor == (const Actor *) Sender)) {
916 continue;
917 }
918 if (newactor->GetCurrentArea()!=map) {
919 continue;
920 }
921 int dist = Distance(Sender, newactor);
922 if ( (mindist == -1) || (dist<mindist) ) {
923 ac = newactor;
924 mindist = dist;
925 }
926 }
927 if (ac) {
928 parameters->AddTarget(ac, 0, ga_flags);
929 }
930 return parameters;
931 }
932
Nearest(const Scriptable *,Targets * parameters,int ga_flags)933 Targets *GameScript::Nearest(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
934 {
935 return XthNearestOf(parameters, 0, ga_flags);
936 }
937
SecondNearest(const Scriptable *,Targets * parameters,int ga_flags)938 Targets *GameScript::SecondNearest(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
939 {
940 return XthNearestOf(parameters, 1, ga_flags);
941 }
942
ThirdNearest(const Scriptable *,Targets * parameters,int ga_flags)943 Targets *GameScript::ThirdNearest(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
944 {
945 return XthNearestOf(parameters, 2, ga_flags);
946 }
947
FourthNearest(const Scriptable *,Targets * parameters,int ga_flags)948 Targets *GameScript::FourthNearest(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
949 {
950 return XthNearestOf(parameters, 3, ga_flags);
951 }
952
FifthNearest(const Scriptable *,Targets * parameters,int ga_flags)953 Targets *GameScript::FifthNearest(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
954 {
955 return XthNearestOf(parameters, 4, ga_flags);
956 }
957
SixthNearest(const Scriptable *,Targets * parameters,int ga_flags)958 Targets *GameScript::SixthNearest(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
959 {
960 return XthNearestOf(parameters, 5, ga_flags);
961 }
962
SeventhNearest(const Scriptable *,Targets * parameters,int ga_flags)963 Targets *GameScript::SeventhNearest(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
964 {
965 return XthNearestOf(parameters, 6, ga_flags);
966 }
967
EighthNearest(const Scriptable *,Targets * parameters,int ga_flags)968 Targets *GameScript::EighthNearest(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
969 {
970 return XthNearestOf(parameters, 7, ga_flags);
971 }
972
NinthNearest(const Scriptable *,Targets * parameters,int ga_flags)973 Targets *GameScript::NinthNearest(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
974 {
975 return XthNearestOf(parameters, 8, ga_flags);
976 }
977
TenthNearest(const Scriptable *,Targets * parameters,int ga_flags)978 Targets *GameScript::TenthNearest(const Scriptable */*Sender*/, Targets *parameters, int ga_flags)
979 {
980 return XthNearestOf(parameters, 9, ga_flags);
981 }
982
SelectedCharacter(const Scriptable * Sender,Targets * parameters,int ga_flags)983 Targets *GameScript::SelectedCharacter(const Scriptable *Sender, Targets *parameters, int ga_flags)
984 {
985 const Map *cm = Sender->GetCurrentArea();
986 parameters->Clear();
987 int i = cm->GetActorCount(true);
988 while (i--) {
989 Actor *ac=cm->GetActor(i,true);
990 if (ac->GetCurrentArea()!=cm) {
991 continue;
992 }
993 if (ac->IsSelected()) {
994 parameters->AddTarget(ac, Distance(Sender, ac), ga_flags );
995 }
996 }
997 return parameters;
998 }
999
Nothing(const Scriptable *,Targets * parameters,int)1000 Targets *GameScript::Nothing(const Scriptable */*Sender*/, Targets* parameters, int /*ga_flags*/)
1001 {
1002 parameters->Clear();
1003 return parameters;
1004 }
1005
1006 //-------------------------------------------------------------
1007 // IDS Functions
1008 //-------------------------------------------------------------
1009
ID_Alignment(const Actor * actor,int parameter)1010 int GameScript::ID_Alignment(const Actor *actor, int parameter)
1011 {
1012 int value = actor->GetStat( IE_ALIGNMENT );
1013 int a = parameter&15;
1014 if (a) {
1015 if (a != ( value & 15 )) {
1016 return 0;
1017 }
1018 }
1019 a = parameter & 240;
1020 if (a) {
1021 if (a != ( value & 240 )) {
1022 return 0;
1023 }
1024 }
1025 return 1;
1026 }
1027
ID_Allegiance(const Actor * actor,int parameter)1028 int GameScript::ID_Allegiance(const Actor *actor, int parameter)
1029 {
1030 int value = actor->GetStat( IE_EA );
1031 switch (parameter) {
1032 case EA_GOODCUTOFF:
1033 return value <= EA_GOODCUTOFF;
1034
1035 case EA_NOTGOOD:
1036 return value >= EA_NOTGOOD;
1037
1038 case EA_NOTNEUTRAL:
1039 return value >=EA_EVILCUTOFF || value <= EA_GOODCUTOFF;
1040
1041 case EA_NOTEVIL:
1042 return value <= EA_NOTEVIL;
1043
1044 case EA_EVILCUTOFF:
1045 return value >= EA_EVILCUTOFF;
1046
1047 case 0:
1048 case EA_ANYTHING:
1049 return true;
1050
1051 }
1052 //default
1053 return parameter == value;
1054 }
1055
1056 // *_ALL constants are different in iwd2 due to different classes (see note below)
1057 // bard, cleric, druid, fighter, mage, paladin, ranger, thief
1058 static const int all_bg_classes[] = { 206, 204, 208, 203, 202, 207, 209, 205 };
1059 static const int all_iwd2_classes[] = { 202, 203, 204, 205, 209, 206, 207, 208 };
1060
1061 // Dual-classed characters will detect only as their new class until their
1062 // original class is re-activated, when they will detect as a multi-class
1063 // GetClassLevel takes care of this automatically!
idclass(const Actor * actor,int parameter,bool iwd2)1064 inline bool idclass(const Actor *actor, int parameter, bool iwd2) {
1065 int value = 0;
1066 if (parameter < 202 || parameter > 209) {
1067 value = actor->GetActiveClass();
1068 return parameter==value;
1069 }
1070
1071 const int *classes;
1072 if (iwd2) {
1073 classes = all_iwd2_classes;
1074 } else {
1075 classes = all_bg_classes;
1076 }
1077
1078 // FIXME: unhardcode this ugly mess
1079 // in IWD2, mage_all = sorcerer or wizard
1080 // fighter_all = fighter, paladin or ranger (but not monk)
1081 // cleric_all = druid or cleric
1082 // thief_all = thief
1083 // bard_all = bard
1084 // paladin_all = paladin
1085 // druid_all = druid
1086 // ranger_all = ranger
1087
1088 // we got one of the *_ALL values
1089 if (parameter == classes[4]) {
1090 // MAGE_ALL (also sorcerers)
1091 value = actor->GetMageLevel() + actor->GetSorcererLevel();
1092 } else if (parameter == classes[3]) {
1093 // FIGHTER_ALL (also monks)
1094 if (iwd2) {
1095 value = actor->GetFighterLevel() + actor->GetPaladinLevel() + actor->GetRangerLevel();
1096 } else {
1097 value = actor->GetFighterLevel() + actor->GetMonkLevel();
1098 }
1099 } else if (parameter == classes[1]) {
1100 // CLERIC_ALL
1101 if (iwd2) {
1102 value = actor->GetClericLevel() + actor->GetDruidLevel();
1103 } else {
1104 value = actor->GetClericLevel();
1105 }
1106 } else if (parameter == classes[7]) {
1107 // THIEF_ALL
1108 value = actor->GetThiefLevel();
1109 } else if (parameter == classes[0]) {
1110 // BARD_ALL
1111 value = actor->GetBardLevel();
1112 } else if (parameter == classes[5]) {
1113 // PALADIN_ALL
1114 value = actor->GetPaladinLevel();
1115 } else if (parameter == classes[2]) {
1116 // DRUID_ALL
1117 value = actor->GetDruidLevel();
1118 } else if (parameter == classes[6]) {
1119 // RANGER_ALL
1120 value = actor->GetRangerLevel();
1121 }
1122 return value > 0;
1123 }
1124
ID_Class(const Actor * actor,int parameter)1125 int GameScript::ID_Class(const Actor *actor, int parameter)
1126 {
1127 if (core->HasFeature(GF_3ED_RULES)) {
1128 //iwd2 has different values, see also the note for AVClass
1129 return idclass(actor, parameter, 1);
1130 }
1131 return idclass(actor, parameter, 0);
1132 }
1133
1134 // IE_CLASS holds only one class, not a bitmask like with iwd2 kits. The ids values
1135 // are friendly to binary comparison, so we just need to build such a class value
ID_ClassMask(const Actor * actor,int parameter)1136 int GameScript::ID_ClassMask(const Actor *actor, int parameter)
1137 {
1138 // maybe we're lucky...
1139 int value = actor->GetActiveClass();
1140 if (parameter&(1<<(value-1))) return 1;
1141
1142 // otherwise iterate over all the classes
1143 value = actor->GetClassMask();
1144
1145 if (parameter&value) return 1;
1146 return 0;
1147 }
1148
1149 // this is only present in iwd2
1150 // the function is identical to ID_Class, but uses the class20 IDS,
1151 // iwd2's class.ids is different than the rest, while class20 is identical (remnant)
ID_AVClass(const Actor * actor,int parameter)1152 int GameScript::ID_AVClass(const Actor *actor, int parameter)
1153 {
1154 return idclass(actor, parameter, 0);
1155 }
1156
ID_Race(const Actor * actor,int parameter)1157 int GameScript::ID_Race(const Actor *actor, int parameter)
1158 {
1159 int value = actor->GetStat(IE_RACE);
1160 return parameter==value;
1161 }
1162
ID_Subrace(const Actor * actor,int parameter)1163 int GameScript::ID_Subrace(const Actor *actor, int parameter)
1164 {
1165 int value = actor->GetStat(IE_SUBRACE);
1166 return parameter==value;
1167 }
1168
ID_Faction(const Actor * actor,int parameter)1169 int GameScript::ID_Faction(const Actor *actor, int parameter)
1170 {
1171 int value = actor->GetStat(IE_FACTION);
1172 return parameter==value;
1173 }
1174
ID_Team(const Actor * actor,int parameter)1175 int GameScript::ID_Team(const Actor *actor, int parameter)
1176 {
1177 int value = actor->GetStat(IE_TEAM);
1178 return parameter==value;
1179 }
1180
ID_Gender(const Actor * actor,int parameter)1181 int GameScript::ID_Gender(const Actor *actor, int parameter)
1182 {
1183 int value = actor->GetStat(IE_SEX);
1184 return parameter==value;
1185 }
1186
ID_General(const Actor * actor,int parameter)1187 int GameScript::ID_General(const Actor *actor, int parameter)
1188 {
1189 int value = actor->GetStat(IE_GENERAL);
1190 return parameter==value;
1191 }
1192
ID_Specific(const Actor * actor,int parameter)1193 int GameScript::ID_Specific(const Actor *actor, int parameter)
1194 {
1195 int value = actor->GetStat(IE_SPECIFIC);
1196 return parameter==value;
1197 }
1198
1199 }
1200