GUIScript: Make LoadSymbol return an object.
[gemrb.git] / gemrb / core / Triggers.cpp
blob4bf8d5bbc9b02f6a77d55bdab797cae7a4a4c406
1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003-2005 The GemRB Project
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.
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.
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.
21 #include "GameScript.h"
23 #include "win32def.h"
25 #include "Calendar.h"
26 #include "GSUtils.h"
27 #include "Game.h"
28 #include "GameControl.h"
29 #include "GameData.h"
30 #include "Video.h"
32 //-------------------------------------------------------------
33 // Trigger Functions
34 //-------------------------------------------------------------
35 int GameScript::BreakingPoint(Scriptable* Sender, Trigger* /*parameters*/)
37 int value=GetHappiness(Sender, core->GetGame()->Reputation );
38 return value < -300;
41 int GameScript::Reaction(Scriptable* Sender, Trigger* parameters)
43 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
44 if (!scr || scr->Type != ST_ACTOR) {
45 parameters->Dump();
46 return 0;
48 int value = GetReaction(((Actor*) scr), Sender);
49 return value == parameters->int0Parameter;
52 int GameScript::ReactionGT(Scriptable* Sender, Trigger* parameters)
54 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
55 if (!scr || scr->Type != ST_ACTOR) {
56 parameters->Dump();
57 return 0;
59 int value = GetReaction(((Actor*) scr), Sender);
60 return value > parameters->int0Parameter;
63 int GameScript::ReactionLT(Scriptable* Sender, Trigger* parameters)
65 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
66 if (!scr || scr->Type != ST_ACTOR) {
67 parameters->Dump();
68 return 0;
70 int value = GetReaction(((Actor*) scr), Sender);
71 return value < parameters->int0Parameter;
74 int GameScript::Happiness(Scriptable* Sender, Trigger* parameters)
76 int value=GetHappiness(Sender, core->GetGame()->Reputation );
77 return value == parameters->int0Parameter;
80 int GameScript::HappinessGT(Scriptable* Sender, Trigger* parameters)
82 int value=GetHappiness(Sender, core->GetGame()->Reputation );
83 return value > parameters->int0Parameter;
86 int GameScript::HappinessLT(Scriptable* Sender, Trigger* parameters)
88 int value=GetHappiness(Sender, core->GetGame()->Reputation );
89 return value < parameters->int0Parameter;
92 int GameScript::Reputation(Scriptable* /*Sender*/, Trigger* parameters)
94 return core->GetGame()->Reputation/10 == (ieDword) parameters->int0Parameter;
97 int GameScript::ReputationGT(Scriptable* /*Sender*/, Trigger* parameters)
99 return core->GetGame()->Reputation/10 > (ieDword) parameters->int0Parameter;
102 int GameScript::ReputationLT(Scriptable* /*Sender*/, Trigger* parameters)
104 return core->GetGame()->Reputation/10 < (ieDword) parameters->int0Parameter;
107 int GameScript::Alignment(Scriptable* Sender, Trigger* parameters)
109 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
110 if (!scr || scr->Type != ST_ACTOR) {
111 return 0;
113 Actor* actor = ( Actor* ) scr;
114 return ID_Alignment( actor, parameters->int0Parameter);
117 int GameScript::Allegiance(Scriptable* Sender, Trigger* parameters)
119 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
120 if (!scr || scr->Type != ST_ACTOR) {
121 return 0;
123 Actor* actor = ( Actor* ) scr;
124 return ID_Allegiance( actor, parameters->int0Parameter);
127 //should return *_ALL stuff
128 int GameScript::Class(Scriptable* Sender, Trigger* parameters)
130 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
131 if (!scr || scr->Type != ST_ACTOR) {
132 return 0;
134 Actor* actor = (Actor*)scr;
135 return ID_Class( actor, parameters->int0Parameter);
138 //should not handle >200, but should check on multi-class
139 //this is most likely ClassMask
140 int GameScript::ClassEx(Scriptable* Sender, Trigger* parameters)
142 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
143 if (!scr || scr->Type != ST_ACTOR) {
144 return 0;
146 Actor* actor = (Actor*)scr;
147 return ID_ClassMask( actor, parameters->int0Parameter);
150 int GameScript::Faction(Scriptable* Sender, Trigger* parameters)
152 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
153 if (!scr || scr->Type != ST_ACTOR) {
154 return 0;
156 Actor* actor = (Actor*)scr;
157 return ID_Faction( actor, parameters->int0Parameter);
160 int GameScript::Team(Scriptable* Sender, Trigger* parameters)
162 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
163 if (!scr || scr->Type != ST_ACTOR) {
164 return 0;
166 Actor* actor = (Actor*)scr;
167 return ID_Team( actor, parameters->int0Parameter);
170 int GameScript::SubRace(Scriptable* Sender, Trigger* parameters)
172 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
173 if (!scr || scr->Type != ST_ACTOR) {
174 return 0;
176 Actor* actor = (Actor*)scr;
177 //subrace trigger uses a weird system, cannot use ID_*
178 //return ID_Subrace( actor, parameters->int0Parameter);
179 int value = actor->GetStat(IE_SUBRACE);
180 if (value) {
181 value |= actor->GetStat(IE_RACE)<<16;
183 if (value == parameters->int0Parameter) {
184 return 1;
186 return 0;
189 //if object parameter is given (gemrb) it is used
190 //otherwise it works on the current object (iwd2)
191 int GameScript::IsTeamBitOn(Scriptable* Sender, Trigger* parameters)
193 Scriptable* scr = Sender;
194 if (parameters->objectParameter) {
195 scr = GetActorFromObject( Sender, parameters->objectParameter );
197 if (!scr || scr->Type != ST_ACTOR) {
198 return 0;
200 Actor* actor = (Actor*)scr;
201 if (actor->GetStat(IE_TEAM) & parameters->int0Parameter) {
202 return 1;
204 return 0;
207 int GameScript::NearbyDialog(Scriptable* Sender, Trigger* parameters)
209 Actor *target = Sender->GetCurrentArea()->GetActorByDialog(parameters->string0Parameter);
210 if ( !target ) {
211 return 0;
213 return CanSee( Sender, target, true, GA_NO_DEAD | GA_NO_HIDDEN );
216 //atm this checks for InParty and See, it is unsure what is required
217 int GameScript::IsValidForPartyDialog(Scriptable* Sender, Trigger* parameters)
219 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
220 if (!scr) {
221 scr = Sender;
223 if (scr->Type != ST_ACTOR) {
224 return 0;
226 Actor *target = (Actor *) scr;
227 //inparty returns -1 if not in party
228 if (core->GetGame()->InParty( target )<0) {
229 return 0;
231 //don't accept parties currently in dialog!
232 //this might disturb some modders, but this is the correct behaviour
233 //for example the aaquatah dialog in irenicus dungeon depends on it
234 GameControl *gc = core->GetGameControl();
235 Actor *pc = (Actor *) scr;
236 if (pc->globalID == gc->targetID || pc->globalID==gc->speakerID) {
237 return 0;
240 //don't accept parties with the no interrupt flag
241 //this fixes bug #2573808 on gamescript level
242 //(still someone has to turn the no interrupt flag off)
243 if(!pc->GetDialog(GD_CHECK)) {
244 return 0;
246 return CanSee( Sender, target, false, GA_NO_DEAD );
249 int GameScript::InParty(Scriptable* Sender, Trigger* parameters)
251 Scriptable* scr;
253 if (parameters->objectParameter) {
254 scr = GetActorFromObject( Sender, parameters->objectParameter );
255 } else {
256 scr = Sender;
258 if (!scr || scr->Type != ST_ACTOR) {
259 return 0;
261 Actor *tar = (Actor *) scr;
262 if (core->GetGame()->InParty( tar ) <0) {
263 return 0;
265 //don't allow dead, don't allow maze and similar effects
266 if (tar->ValidTarget(GA_NO_DEAD|GA_NO_HIDDEN)) {
267 return 1;
269 return 0;
272 int GameScript::InPartyAllowDead(Scriptable* Sender, Trigger* parameters)
274 Scriptable* scr;
276 if (parameters->objectParameter) {
277 scr = GetActorFromObject( Sender, parameters->objectParameter );
278 } else {
279 scr = Sender;
281 if (!scr || scr->Type != ST_ACTOR) {
282 return 0;
284 return core->GetGame()->InParty( ( Actor * ) scr ) >= 0 ? 1 : 0;
287 int GameScript::InPartySlot(Scriptable* Sender, Trigger* parameters)
289 Actor *actor = core->GetGame()->GetPC(parameters->int0Parameter, false);
290 return MatchActor(Sender, actor->GetID(), parameters->objectParameter);
293 int GameScript::Exists(Scriptable* Sender, Trigger* parameters)
295 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
296 if (!scr) {
297 return 0;
299 return 1;
302 int GameScript::IsAClown(Scriptable* Sender, Trigger* parameters)
304 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
305 if (!scr || scr->Type!=ST_ACTOR) {
306 return 0;
308 return 1;
311 int GameScript::IsGabber(Scriptable* Sender, Trigger* parameters)
313 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
314 if (!scr || scr->Type!=ST_ACTOR) {
315 return 0;
317 if (((Actor *) scr)->globalID == core->GetGameControl()->speakerID)
318 return 1;
319 return 0;
322 int GameScript::IsActive(Scriptable* Sender, Trigger* parameters)
324 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
325 if (!scr) {
326 return 0;
328 if (scr->GetInternalFlag()&IF_ACTIVE) {
329 return 1;
331 return 0;
334 int GameScript::InTrap(Scriptable* Sender, Trigger* parameters)
336 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
337 if (!scr) {
338 return 0;
340 if (scr->GetInternalFlag()&IF_INTRAP) {
341 return 1;
343 return 0;
346 int GameScript::School(Scriptable* Sender, Trigger* parameters)
348 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
349 if (!scr || scr->Type!=ST_ACTOR) {
350 return 0;
352 Actor* actor = (Actor *) scr;
353 //only the low 2 bytes count
354 //the School values start from 1 to 9 and the first school value is 0x40
355 //so this mild hack will do
356 if ( actor->GetStat(IE_KIT) == (ieDword) (0x20<<parameters->int0Parameter)) {
357 return 1;
359 return 0;
362 int GameScript::Kit(Scriptable* Sender, Trigger* parameters)
364 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
365 if (!scr || scr->Type!=ST_ACTOR) {
366 return 0;
368 Actor* actor = (Actor *) scr;
370 ieDword kit = actor->GetStat(IE_KIT);
371 //TODO: fix baseclass / barbarian confusion
373 //IWD2 style kit matching (also used for mage schools)
374 if (kit == (ieDword) (parameters->int0Parameter)) {
375 return 1;
377 //BG2 style kit matching (not needed anymore?), we do it on load
378 //kit = (kit>>16)|(kit<<16);
379 if ( kit == (ieDword) (parameters->int0Parameter)) {
380 return 1;
382 return 0;
385 int GameScript::General(Scriptable* Sender, Trigger* parameters)
387 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
388 if (!scr) {
389 scr = Sender;
391 if (scr->Type != ST_ACTOR) {
392 return 0;
394 Actor* actor = ( Actor* ) scr;
395 if (actor == NULL) {
396 return 0;
398 return ID_General(actor, parameters->int0Parameter);
401 int GameScript::Specifics(Scriptable* Sender, Trigger* parameters)
403 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
404 if (!scr) {
405 scr = Sender;
407 if (scr->Type != ST_ACTOR) {
408 return 0;
410 Actor* actor = ( Actor* ) scr;
411 if (actor == NULL) {
412 return 0;
414 return ID_Specific(actor, parameters->int0Parameter);
417 int GameScript::BitCheck(Scriptable* Sender, Trigger* parameters)
419 bool valid=true;
421 ieDword value = CheckVariable(Sender, parameters->string0Parameter, &valid );
422 if (valid) {
423 if ( value & parameters->int0Parameter ) return 1;
425 return 0;
428 int GameScript::BitCheckExact(Scriptable* Sender, Trigger* parameters)
430 bool valid=true;
432 ieDword value = CheckVariable(Sender, parameters->string0Parameter, &valid );
433 if (valid) {
434 ieDword tmp = (ieDword) parameters->int0Parameter ;
435 if ((value & tmp) == tmp) return 1;
437 return 0;
440 //BM_OR would make sense only if this trigger changes the value of the variable
441 //should I do that???
442 int GameScript::BitGlobal_Trigger(Scriptable* Sender, Trigger* parameters)
444 bool valid=true;
446 ieDword value = CheckVariable(Sender, parameters->string0Parameter, &valid );
447 if (valid) {
448 HandleBitMod(value, parameters->int0Parameter, parameters->int1Parameter);
449 if (value!=0) return 1;
451 return 0;
454 int GameScript::GlobalOrGlobal_Trigger(Scriptable* Sender, Trigger* parameters)
456 bool valid=true;
458 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, &valid );
459 if (valid) {
460 if ( value1 ) return 1;
461 ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, &valid );
462 if (valid) {
463 if ( value2 ) return 1;
466 return 0;
469 int GameScript::GlobalAndGlobal_Trigger(Scriptable* Sender, Trigger* parameters)
471 bool valid=true;
473 ieDword value1 = CheckVariable( Sender, parameters->string0Parameter, &valid );
474 if (valid && value1) {
475 ieDword value2 = CheckVariable( Sender, parameters->string1Parameter, &valid );
476 if (valid && value2) return 1;
478 return 0;
481 int GameScript::GlobalBAndGlobal_Trigger(Scriptable* Sender, Trigger* parameters)
483 bool valid=true;
485 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, &valid );
486 if (valid) {
487 ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, &valid );
488 if (valid) {
489 if ((value1& value2 ) != 0) return 1;
492 return 0;
495 int GameScript::GlobalBAndGlobalExact(Scriptable* Sender, Trigger* parameters)
497 bool valid=true;
499 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, &valid );
500 if (valid) {
501 ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, &valid );
502 if (valid) {
503 if (( value1& value2 ) == value2) return 1;
506 return 0;
509 int GameScript::GlobalBitGlobal_Trigger(Scriptable* Sender, Trigger* parameters)
511 bool valid=true;
513 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, &valid );
514 if (valid) {
515 ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, &valid );
516 if (valid) {
517 HandleBitMod( value1, value2, parameters->int1Parameter);
518 if (value1!=0) return 1;
521 return 0;
524 //no what exactly this trigger would do, defined in iwd2, but never used
525 //i just assume it sets a global in the trigger block
526 int GameScript::TriggerSetGlobal(Scriptable* Sender, Trigger* parameters)
528 SetVariable( Sender, parameters->string0Parameter, parameters->int0Parameter );
529 return 1;
532 //would this function also alter the variable?
533 int GameScript::Xor(Scriptable* Sender, Trigger* parameters)
535 bool valid=true;
537 ieDword value = CheckVariable(Sender, parameters->string0Parameter, &valid );
538 if (valid) {
539 if (( value ^ parameters->int0Parameter ) != 0) return 1;
541 return 0;
544 //TODO:
545 //no sprite is dead for iwd, they use KILL_<name>_CNT
546 int GameScript::NumDead(Scriptable* Sender, Trigger* parameters)
548 ieDword value;
550 if (core->HasFeature(GF_HAS_KAPUTZ) ) {
551 value = CheckVariable(Sender, parameters->string0Parameter, "KAPUTZ");
552 } else {
553 ieVariable VariableName;
554 snprintf(VariableName, 32, core->GetDeathVarFormat(), parameters->string0Parameter);
555 value = CheckVariable(Sender, VariableName, "GLOBAL" );
557 return ( value == (ieDword) parameters->int0Parameter );
560 int GameScript::NumDeadGT(Scriptable* Sender, Trigger* parameters)
562 ieDword value;
564 if (core->HasFeature(GF_HAS_KAPUTZ) ) {
565 value = CheckVariable(Sender, parameters->string0Parameter, "KAPUTZ");
566 } else {
567 ieVariable VariableName;
568 snprintf(VariableName, 32, core->GetDeathVarFormat(), parameters->string0Parameter);
569 value = CheckVariable(Sender, VariableName, "GLOBAL" );
571 return ( value > (ieDword) parameters->int0Parameter );
574 int GameScript::NumDeadLT(Scriptable* Sender, Trigger* parameters)
576 ieDword value;
578 if (core->HasFeature(GF_HAS_KAPUTZ) ) {
579 value = CheckVariable(Sender, parameters->string0Parameter, "KAPUTZ");
580 } else {
581 ieVariable VariableName;
583 snprintf(VariableName, 32, core->GetDeathVarFormat(), parameters->string0Parameter);
584 value = CheckVariable(Sender, VariableName, "GLOBAL" );
586 return ( value < (ieDword) parameters->int0Parameter );
589 int GameScript::G_Trigger(Scriptable* Sender, Trigger* parameters)
591 ieDwordSigned value = CheckVariable(Sender, parameters->string0Parameter, "GLOBAL" );
592 return ( value == parameters->int0Parameter );
595 int GameScript::Global(Scriptable* Sender, Trigger* parameters)
597 bool valid=true;
599 ieDwordSigned value = CheckVariable(Sender, parameters->string0Parameter, &valid );
600 if (valid) {
601 if ( value == parameters->int0Parameter ) return 1;
603 return 0;
606 int GameScript::GLT_Trigger(Scriptable* Sender, Trigger* parameters)
608 ieDwordSigned value = CheckVariable(Sender, parameters->string0Parameter,"GLOBAL" );
609 return ( value < parameters->int0Parameter );
612 int GameScript::GlobalLT(Scriptable* Sender, Trigger* parameters)
614 bool valid=true;
616 ieDwordSigned value = CheckVariable(Sender, parameters->string0Parameter, &valid );
617 if (valid) {
618 if ( value < parameters->int0Parameter ) return 1;
620 return 0;
623 int GameScript::GGT_Trigger(Scriptable* Sender, Trigger* parameters)
625 ieDwordSigned value = CheckVariable(Sender, parameters->string0Parameter, "GLOBAL" );
626 return ( value > parameters->int0Parameter );
629 int GameScript::GlobalGT(Scriptable* Sender, Trigger* parameters)
631 bool valid=true;
633 ieDwordSigned value = CheckVariable(Sender, parameters->string0Parameter, &valid );
634 if (valid) {
635 if ( value > parameters->int0Parameter ) return 1;
637 return 0;
640 int GameScript::GlobalLTGlobal(Scriptable* Sender, Trigger* parameters)
642 bool valid=true;
644 ieDwordSigned value1 = CheckVariable(Sender, parameters->string0Parameter, &valid );
645 if (valid) {
646 ieDwordSigned value2 = CheckVariable(Sender, parameters->string1Parameter, &valid );
647 if (valid) {
648 if ( value1 < value2 ) return 1;
651 return 0;
654 int GameScript::GlobalGTGlobal(Scriptable* Sender, Trigger* parameters)
656 bool valid=true;
658 ieDwordSigned value1 = CheckVariable(Sender, parameters->string0Parameter, &valid );
659 if (valid) {
660 ieDwordSigned value2 = CheckVariable(Sender, parameters->string1Parameter, &valid );
661 if (valid) {
662 if ( value1 > value2 ) return 1;
665 return 0;
668 int GameScript::GlobalsEqual(Scriptable* Sender, Trigger* parameters)
670 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, "GLOBAL" );
671 ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, "GLOBAL" );
672 return ( value1 == value2 );
675 int GameScript::GlobalsGT(Scriptable* Sender, Trigger* parameters)
677 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, "GLOBAL" );
678 ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, "GLOBAL" );
679 return ( value1 > value2 );
682 int GameScript::GlobalsLT(Scriptable* Sender, Trigger* parameters)
684 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, "GLOBAL" );
685 ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, "GLOBAL" );
686 return ( value1 < value2 );
689 int GameScript::LocalsEqual(Scriptable* Sender, Trigger* parameters)
691 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, "LOCALS" );
692 ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, "LOCALS" );
693 return ( value1 == value2 );
696 int GameScript::LocalsGT(Scriptable* Sender, Trigger* parameters)
698 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, "LOCALS" );
699 ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, "LOCALS" );
700 return ( value1 > value2 );
703 int GameScript::LocalsLT(Scriptable* Sender, Trigger* parameters)
705 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, "LOCALS" );
706 ieDword value2 = CheckVariable(Sender, parameters->string1Parameter, "LOCALS" );
707 return ( value1 < value2 );
710 int GameScript::RealGlobalTimerExact(Scriptable* Sender, Trigger* parameters)
712 bool valid=true;
714 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid );
715 if (valid && value1) {
716 ieDword value2 = core->GetGame()->RealTime;
717 if ( value1 == value2 ) return 1;
719 return 0;
722 int GameScript::RealGlobalTimerExpired(Scriptable* Sender, Trigger* parameters)
724 bool valid=true;
726 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid );
727 if (valid && value1) {
728 if ( value1 < core->GetGame()->RealTime ) return 1;
730 return 0;
733 int GameScript::RealGlobalTimerNotExpired(Scriptable* Sender, Trigger* parameters)
735 bool valid=true;
737 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid );
738 if (valid && value1) {
739 if ( value1 > core->GetGame()->RealTime ) return 1;
741 return 0;
744 int GameScript::GlobalTimerExact(Scriptable* Sender, Trigger* parameters)
746 bool valid=true;
748 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid );
749 if (valid) {
750 if ( value1 == core->GetGame()->GameTime ) return 1;
752 return 0;
755 int GameScript::GlobalTimerExpired(Scriptable* Sender, Trigger* parameters)
757 bool valid=true;
759 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid );
760 if (valid && value1) {
761 if ( value1 < core->GetGame()->GameTime ) return 1;
763 return 0;
766 //globaltimernotexpired returns false if the timer doesn't exist
767 int GameScript::GlobalTimerNotExpired(Scriptable* Sender, Trigger* parameters)
769 bool valid=true;
771 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid );
772 if (valid && value1) {
773 if ( value1 > core->GetGame()->GameTime ) return 1;
775 return 0;
778 //globaltimerstarted returns false if the timer doesn't exist
779 //is it the same as globaltimernotexpired?
780 int GameScript::GlobalTimerStarted(Scriptable* Sender, Trigger* parameters)
782 bool valid=true;
784 ieDword value1 = CheckVariable(Sender, parameters->string0Parameter, parameters->string1Parameter, &valid );
785 if (valid && value1) {
786 if ( value1 > core->GetGame()->GameTime ) return 1;
788 return 0;
791 int GameScript::WasInDialog(Scriptable* Sender, Trigger* /*parameters*/)
793 if (Sender->GetInternalFlag()&IF_WASINDIALOG) {
794 Sender->SetBitTrigger(BT_WASINDIALOG);
795 return 1;
797 return 0;
800 int GameScript::OnCreation(Scriptable* Sender, Trigger* /*parameters*/)
802 if (Sender->GetInternalFlag()&IF_ONCREATION) {
803 Sender->SetBitTrigger(BT_ONCREATION);
804 return 1;
806 return 0;
809 int GameScript::NumItemsParty(Scriptable* /*Sender*/, Trigger* parameters)
811 int cnt = 0;
812 Game *game=core->GetGame();
814 int i = game->GetPartySize(true);
815 while(i--) {
816 Actor *actor = game->GetPC(i, true);
817 cnt+=actor->inventory.CountItems(parameters->string0Parameter,1);
819 return cnt==parameters->int0Parameter;
822 int GameScript::NumItemsPartyGT(Scriptable* /*Sender*/, Trigger* parameters)
824 int cnt = 0;
825 Game *game=core->GetGame();
827 int i = game->GetPartySize(true);
828 while(i--) {
829 Actor *actor = game->GetPC(i, true);
830 cnt+=actor->inventory.CountItems(parameters->string0Parameter,1);
832 return cnt>parameters->int0Parameter;
835 int GameScript::NumItemsPartyLT(Scriptable* /*Sender*/, Trigger* parameters)
837 int cnt = 0;
838 Game *game=core->GetGame();
840 int i = game->GetPartySize(true);
841 while(i--) {
842 Actor *actor = game->GetPC(i, true);
843 cnt+=actor->inventory.CountItems(parameters->string0Parameter,1);
845 return cnt<parameters->int0Parameter;
848 int GameScript::NumItems(Scriptable* Sender, Trigger* parameters)
850 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
851 if ( !tar || tar->Type!=ST_ACTOR) {
852 return 0;
854 Actor *actor = (Actor *) tar;
855 int cnt = actor->inventory.CountItems(parameters->string0Parameter,1);
856 return cnt==parameters->int0Parameter;
859 int GameScript::TotalItemCnt(Scriptable* Sender, Trigger* parameters)
861 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
862 if ( !tar || tar->Type!=ST_ACTOR) {
863 return 0;
865 Actor *actor = (Actor *) tar;
866 int cnt = actor->inventory.CountItems("",1); //shall we count heaps or not?
867 return cnt==parameters->int0Parameter;
870 int GameScript::TotalItemCntExclude(Scriptable* Sender, Trigger* parameters)
872 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
873 if ( !tar || tar->Type!=ST_ACTOR) {
874 return 0;
876 Actor *actor = (Actor *) tar;
877 int cnt = actor->inventory.CountItems("",1)-actor->inventory.CountItems(parameters->string0Parameter,1); //shall we count heaps or not?
878 return cnt==parameters->int0Parameter;
881 int GameScript::NumItemsGT(Scriptable* Sender, Trigger* parameters)
883 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
884 if ( !tar || tar->Type!=ST_ACTOR) {
885 return 0;
887 Actor *actor = (Actor *) tar;
888 int cnt = actor->inventory.CountItems(parameters->string0Parameter,1);
889 return cnt>parameters->int0Parameter;
892 int GameScript::TotalItemCntGT(Scriptable* Sender, Trigger* parameters)
894 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
895 if ( !tar || tar->Type!=ST_ACTOR) {
896 return 0;
898 Actor *actor = (Actor *) tar;
899 int cnt = actor->inventory.CountItems("",1); //shall we count heaps or not?
900 return cnt>parameters->int0Parameter;
903 int GameScript::TotalItemCntExcludeGT(Scriptable* Sender, Trigger* parameters)
905 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
906 if ( !tar || tar->Type!=ST_ACTOR) {
907 return 0;
909 Actor *actor = (Actor *) tar;
910 int cnt = actor->inventory.CountItems("",1)-actor->inventory.CountItems(parameters->string0Parameter,1); //shall we count heaps or not?
911 return cnt>parameters->int0Parameter;
914 int GameScript::NumItemsLT(Scriptable* Sender, Trigger* parameters)
916 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
917 if ( !tar || tar->Type!=ST_ACTOR) {
918 return 0;
920 Actor *actor = (Actor *) tar;
921 int cnt = actor->inventory.CountItems(parameters->string0Parameter,1);
922 return cnt<parameters->int0Parameter;
925 int GameScript::TotalItemCntLT(Scriptable* Sender, Trigger* parameters)
927 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
928 if ( !tar || tar->Type!=ST_ACTOR) {
929 return 0;
931 Actor *actor = (Actor *) tar;
932 int cnt = actor->inventory.CountItems("",1); //shall we count heaps or not?
933 return cnt<parameters->int0Parameter;
936 int GameScript::TotalItemCntExcludeLT(Scriptable* Sender, Trigger* parameters)
938 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
939 if ( !tar || tar->Type!=ST_ACTOR) {
940 return 0;
942 Actor *actor = (Actor *) tar;
943 int cnt = actor->inventory.CountItems("",1)-actor->inventory.CountItems(parameters->string0Parameter,1); //shall we count heaps or not?
944 return cnt<parameters->int0Parameter;
947 //the int0 parameter is an addition, normally it is 0
948 int GameScript::Contains(Scriptable* Sender, Trigger* parameters)
950 //actually this should be a container
951 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
952 if ( !tar || tar->Type!=ST_CONTAINER) {
953 return 0;
955 Container *cnt = (Container *) tar;
956 if (HasItemCore(&cnt->inventory, parameters->string0Parameter, parameters->int0Parameter) ) {
957 return 1;
959 return 0;
962 int GameScript::StoreHasItem(Scriptable* /*Sender*/, Trigger* parameters)
964 return StoreHasItemCore(parameters->string0Parameter, parameters->string1Parameter);
967 //the int0 parameter is an addition, normally it is 0
968 int GameScript::HasItem(Scriptable* Sender, Trigger* parameters)
970 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
971 if ( !scr ) {
972 return 0;
974 Inventory *inventory;
975 switch (scr->Type) {
976 case ST_ACTOR:
977 inventory = &( (Actor *) scr)->inventory;
978 break;
979 case ST_CONTAINER:
980 inventory = &( (Container *) scr)->inventory;
981 break;
982 default:
983 inventory = NULL;
984 break;
986 if (inventory && HasItemCore(inventory, parameters->string0Parameter, parameters->int0Parameter) ) {
987 return 1;
989 return 0;
992 int GameScript::ItemIsIdentified(Scriptable* Sender, Trigger* parameters)
994 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
995 if ( !scr || scr->Type!=ST_ACTOR) {
996 return 0;
998 Actor *actor = (Actor *) scr;
999 if (HasItemCore(&actor->inventory, parameters->string0Parameter, IE_INV_ITEM_IDENTIFIED) ) {
1000 return 1;
1002 return 0;
1005 /** if the string is zero, then it will return true if there is any item in the slot (BG2)*/
1006 /** if the string is non-zero, it will return true, if the given item was in the slot (IWD2)*/
1007 int GameScript::HasItemSlot(Scriptable* Sender, Trigger* parameters)
1009 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1010 if ( !scr || scr->Type!=ST_ACTOR) {
1011 return 0;
1013 Actor *actor = (Actor *) scr;
1014 //this might require a conversion of the slots
1015 if (actor->inventory.HasItemInSlot(parameters->string0Parameter, parameters->int0Parameter) ) {
1016 return 1;
1018 return 0;
1021 //this is a GemRB extension
1022 //HasItemTypeSlot(Object, SLOT, ItemType)
1023 //returns true if the item in SLOT is of ItemType
1024 int GameScript::HasItemTypeSlot(Scriptable* Sender, Trigger* parameters)
1026 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1027 if ( !scr || scr->Type!=ST_ACTOR) {
1028 return 0;
1030 Inventory *inv = &((Actor *) scr)->inventory;
1031 if (parameters->int0Parameter>=inv->GetSlotCount()) {
1032 return 0;
1034 CREItem *slot = inv->GetSlotItem(parameters->int0Parameter);
1035 if (!slot) {
1036 return 0;
1038 Item *itm = gamedata->GetItem(slot->ItemResRef);
1039 int itemtype = itm->ItemType;
1040 gamedata->FreeItem(itm, slot->ItemResRef, 0);
1041 if (itemtype==parameters->int1Parameter) {
1042 return 1;
1044 return 0;
1047 int GameScript::HasItemEquipped(Scriptable * Sender, Trigger* parameters)
1049 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1050 if ( !scr || scr->Type!=ST_ACTOR) {
1051 return 0;
1053 Actor *actor = (Actor *) scr;
1054 if (actor->inventory.HasItem(parameters->string0Parameter, IE_INV_ITEM_EQUIPPED) ) {
1055 return 1;
1057 return 0;
1060 int GameScript::Acquired(Scriptable * Sender, Trigger* parameters)
1062 if ( Sender->Type!=ST_ACTOR) {
1063 return 0;
1065 Actor *actor = (Actor *) Sender;
1066 if (actor->inventory.HasItem(parameters->string0Parameter, IE_INV_ITEM_ACQUIRED) ) {
1067 return 1;
1069 return 0;
1072 /** this trigger accepts a numeric parameter, this number could be: */
1073 /** 0 - normal, 1 - equipped, 2 - identified, 3 - equipped&identified */
1074 /** this is a GemRB extension */
1075 int GameScript::PartyHasItem(Scriptable * /*Sender*/, Trigger* parameters)
1077 Game *game=core->GetGame();
1079 int i = game->GetPartySize(true);
1080 while(i--) {
1081 Actor *actor = game->GetPC(i, true);
1082 if (HasItemCore(&actor->inventory, parameters->string0Parameter, parameters->int0Parameter) ) {
1083 return 1;
1086 return 0;
1089 int GameScript::PartyHasItemIdentified(Scriptable * /*Sender*/, Trigger* parameters)
1091 Game *game=core->GetGame();
1093 int i = game->GetPartySize(true);
1094 while(i--) {
1095 Actor *actor = game->GetPC(i, true);
1096 if (HasItemCore(&actor->inventory, parameters->string0Parameter, IE_INV_ITEM_IDENTIFIED) ) {
1097 return 1;
1100 return 0;
1103 int GameScript::InventoryFull( Scriptable* Sender, Trigger* parameters)
1105 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
1106 if (!tar || tar->Type!=ST_ACTOR) {
1107 return 0;
1109 Actor *actor = (Actor *) tar;
1110 if (actor->inventory.FindCandidateSlot( SLOT_INVENTORY, 0 )==-1) {
1111 return 1;
1113 return 0;
1116 int GameScript::HasInnateAbility(Scriptable *Sender, Trigger *parameters)
1118 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
1119 if (!tar || tar->Type!=ST_ACTOR) {
1120 return 0;
1122 Actor *actor = (Actor *) tar;
1123 if (parameters->string0Parameter[0]) {
1124 return actor->spellbook.HaveSpell(parameters->string0Parameter, 0);
1126 return actor->spellbook.HaveSpell(parameters->int0Parameter, 0);
1129 int GameScript::HaveSpell(Scriptable *Sender, Trigger *parameters)
1131 if (Sender->Type!=ST_ACTOR) {
1132 return 0;
1134 Actor *actor = (Actor *) Sender;
1135 if (parameters->string0Parameter[0]) {
1136 return actor->spellbook.HaveSpell(parameters->string0Parameter, 0);
1138 return actor->spellbook.HaveSpell(parameters->int0Parameter, 0);
1141 int GameScript::HaveAnySpells(Scriptable* Sender, Trigger* /*parameters*/)
1143 if (Sender->Type!=ST_ACTOR) {
1144 return 0;
1146 Actor *actor = (Actor *) Sender;
1147 return actor->spellbook.HaveSpell("", 0);
1150 int GameScript::HaveSpellParty(Scriptable* /*Sender*/, Trigger *parameters)
1152 Game *game=core->GetGame();
1154 int i = game->GetPartySize(true);
1156 if (parameters->string0Parameter[0]) {
1157 while(i--) {
1158 Actor *actor = game->GetPC(i, true);
1159 if (actor->spellbook.HaveSpell(parameters->string0Parameter, 0) ) {
1160 return 1;
1163 } else {
1164 while(i--) {
1165 Actor *actor = game->GetPC(i, true);
1166 if (actor->spellbook.HaveSpell(parameters->int0Parameter, 0) ) {
1167 return 1;
1171 return 0;
1174 int GameScript::KnowSpell(Scriptable *Sender, Trigger *parameters)
1176 if (Sender->Type!=ST_ACTOR) {
1177 return 0;
1179 Actor *actor = (Actor *) Sender;
1180 if (parameters->string0Parameter[0]) {
1181 return actor->spellbook.KnowSpell(parameters->string0Parameter);
1183 return actor->spellbook.KnowSpell(parameters->int0Parameter);
1186 int GameScript::True(Scriptable * /* Sender*/, Trigger * /*parameters*/)
1188 return 1;
1191 //in fact this could be used only on Sender, but we want to enhance these
1192 //triggers and actions to accept an object argument whenever possible.
1193 //0 defaults to Myself (Sender)
1194 int GameScript::NumTimesTalkedTo(Scriptable* Sender, Trigger* parameters)
1196 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1197 if (!scr) {
1198 scr = Sender;
1200 if (scr->Type != ST_ACTOR) {
1201 return 0;
1203 Actor* actor = ( Actor* ) scr;
1204 return actor->TalkCount == (ieDword) parameters->int0Parameter ? 1 : 0;
1207 int GameScript::NumTimesTalkedToGT(Scriptable* Sender, Trigger* parameters)
1209 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1210 if (!scr) {
1211 scr = Sender;
1213 if (scr->Type != ST_ACTOR) {
1214 return 0;
1216 Actor* actor = ( Actor* ) scr;
1217 return actor->TalkCount > (ieDword) parameters->int0Parameter ? 1 : 0;
1220 int GameScript::NumTimesTalkedToLT(Scriptable* Sender, Trigger* parameters)
1222 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1223 if (!scr) {
1224 scr = Sender;
1226 if (scr->Type != ST_ACTOR) {
1227 return 0;
1229 Actor* actor = ( Actor* ) scr;
1230 return actor->TalkCount < (ieDword) parameters->int0Parameter ? 1 : 0;
1233 int GameScript::NumTimesInteracted(Scriptable* Sender, Trigger* parameters)
1235 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1236 if (!scr) {
1237 scr = Sender;
1239 if (scr->Type != ST_ACTOR) {
1240 return 0;
1242 Actor* actor = ( Actor* ) scr;
1243 return actor->InteractCount == (ieDword) parameters->int1Parameter ? 1 : 0;
1246 int GameScript::NumTimesInteractedGT(Scriptable* Sender, Trigger* parameters)
1248 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1249 if (!scr) {
1250 scr = Sender;
1252 if (scr->Type != ST_ACTOR) {
1253 return 0;
1255 Actor* actor = ( Actor* ) scr;
1256 return actor->InteractCount > (ieDword) parameters->int1Parameter ? 1 : 0;
1259 int GameScript::NumTimesInteractedLT(Scriptable* Sender, Trigger* parameters)
1261 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1262 if (!scr) {
1263 scr = Sender;
1265 if (scr->Type != ST_ACTOR) {
1266 return 0;
1268 Actor* actor = ( Actor* ) scr;
1269 return actor->InteractCount < (ieDword) parameters->int1Parameter ? 1 : 0;
1272 int GameScript::NumTimesInteractedObject(Scriptable* Sender, Trigger* parameters)
1274 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1275 if (!scr) {
1276 scr = Sender;
1278 if (scr->Type != ST_ACTOR) {
1279 return 0;
1281 Actor* actor = ( Actor* ) scr;
1282 return actor->InteractCount == (ieDword) parameters->int0Parameter ? 1 : 0;
1285 int GameScript::NumTimesInteractedObjectGT(Scriptable* Sender, Trigger* parameters)
1287 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1288 if (!scr) {
1289 scr = Sender;
1291 if (scr->Type != ST_ACTOR) {
1292 return 0;
1294 Actor* actor = ( Actor* ) scr;
1295 return actor->InteractCount > (ieDword) parameters->int0Parameter ? 1 : 0;
1298 int GameScript::NumTimesInteractedObjectLT(Scriptable* Sender, Trigger* parameters)
1300 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1301 if (!scr) {
1302 scr = Sender;
1304 if (scr->Type != ST_ACTOR) {
1305 return 0;
1307 Actor* actor = ( Actor* ) scr;
1308 return actor->InteractCount < (ieDword) parameters->int0Parameter ? 1 : 0;
1311 int GameScript::ObjectActionListEmpty(Scriptable* Sender, Trigger* parameters)
1313 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1314 if (!scr) {
1315 return 0;
1318 // added CurrentAction as part of blocking action fixes
1319 if (scr->GetCurrentAction() || scr->GetNextAction()) {
1320 return 0;
1322 return 1;
1325 int GameScript::ActionListEmpty(Scriptable* Sender, Trigger* /*parameters*/)
1327 // added CurrentAction as part of blocking action fixes
1328 if (Sender->GetCurrentAction() || Sender->GetNextAction()) {
1329 return 0;
1331 return 1;
1334 int GameScript::False(Scriptable* /*Sender*/, Trigger* /*parameters*/)
1336 return 0;
1339 /* i guess this is a range of circle edges (instead of centers) */
1340 int GameScript::PersonalSpaceDistance(Scriptable* Sender, Trigger* parameters)
1342 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1343 if (!scr) {
1344 return 0;
1346 int range = parameters->int0Parameter;
1348 int distance = PersonalDistance(Sender, scr);
1349 if (distance <= ( range * 10 )) {
1350 return 1;
1352 return 0;
1355 int GameScript::Range(Scriptable* Sender, Trigger* parameters)
1357 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1358 if (!scr) {
1359 return 0;
1361 int distance = Distance(Sender, scr);
1362 return DiffCore(distance, parameters->int0Parameter*10, parameters->int1Parameter);
1365 //PST
1366 int GameScript::AtLocation( Scriptable* Sender, Trigger* parameters)
1368 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
1369 if (!tar) {
1370 return 0;
1372 if ( (tar->Pos.x==parameters->pointParameter.x) &&
1373 (tar->Pos.y==parameters->pointParameter.y) ) {
1374 return 1;
1376 return 0;
1379 //in pst this is a point
1380 //in iwd2 this is not a point
1381 int GameScript::NearLocation(Scriptable* Sender, Trigger* parameters)
1383 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1384 if (!scr) {
1385 return 0;
1387 if (parameters->pointParameter.isnull()) {
1388 Point p((short) parameters->int0Parameter, (short) parameters->int1Parameter);
1389 int distance = PersonalDistance(p, scr);
1390 if (distance <= ( parameters->int2Parameter * 10 )) {
1391 return 1;
1393 return 0;
1395 // should this be PersonalDistance?
1396 int distance = Distance(parameters->pointParameter, scr);
1397 if (distance <= ( parameters->int0Parameter * 10 )) {
1398 return 1;
1400 return 0;
1403 int GameScript::NearSavedLocation(Scriptable* Sender, Trigger* parameters)
1405 if (Sender->Type!=ST_ACTOR) {
1406 return 0;
1408 if (core->HasFeature(GF_HAS_KAPUTZ)) {
1409 // we don't understand how this works in pst yet
1410 return 1;
1412 Actor *actor = (Actor *) Sender;
1413 Point p( (short) actor->GetStat(IE_SAVEDXPOS), (short) actor->GetStat(IE_SAVEDYPOS) );
1414 // should this be PersonalDistance?
1415 int distance = Distance(p, Sender);
1416 if (distance <= ( parameters->int0Parameter * 10 )) {
1417 return 1;
1419 return 0;
1422 int GameScript::Or(Scriptable* /*Sender*/, Trigger* parameters)
1424 return parameters->int0Parameter;
1427 int GameScript::TriggerTrigger(Scriptable* Sender, Trigger* parameters)
1429 if(Sender->TriggerID==(ieDword) parameters->int0Parameter) {
1430 Sender->AddTrigger (&Sender->TriggerID);
1431 return 1;
1433 return 0;
1436 int GameScript::WalkedToTrigger(Scriptable* Sender, Trigger* parameters)
1438 Actor *target = Sender->GetCurrentArea()->GetActorByGlobalID(Sender->LastTrigger);
1439 if (!target) {
1440 return 0;
1442 if (PersonalDistance(target, Sender) > 3*MAX_OPERATING_DISTANCE ) {
1443 return 0;
1445 //now objects suicide themselves if they are empty objects
1446 //so checking an empty object is easier
1447 if (parameters->objectParameter == NULL) {
1448 Sender->AddTrigger (&Sender->LastTrigger);
1449 return 1;
1451 if (MatchActor(Sender, Sender->LastTrigger, parameters->objectParameter)) {
1452 Sender->AddTrigger (&Sender->LastTrigger);
1453 return 1;
1455 return 0;
1458 int GameScript::Clicked(Scriptable* Sender, Trigger* parameters)
1460 //now objects suicide themselves if they are empty objects
1461 //so checking an empty object is easier
1462 if (parameters->objectParameter == NULL) {
1463 if (Sender->LastTrigger) {
1464 Sender->AddTrigger (&Sender->LastTrigger);
1465 return 1;
1467 return 0;
1469 if (MatchActor(Sender, Sender->LastTrigger, parameters->objectParameter)) {
1470 Sender->AddTrigger (&Sender->LastTrigger);
1471 return 1;
1473 return 0;
1476 int GameScript::Disarmed(Scriptable* Sender, Trigger* parameters)
1478 switch(Sender->Type) {
1479 case ST_DOOR: case ST_CONTAINER: case ST_PROXIMITY:
1480 break;
1481 default:
1482 return 0;
1484 if (parameters->objectParameter == NULL) {
1485 if (Sender->LastDisarmed) {
1486 Sender->AddTrigger (&Sender->LastDisarmed);
1487 return 1;
1489 return 0;
1491 if (MatchActor(Sender, Sender->LastDisarmed, parameters->objectParameter)) {
1492 Sender->AddTrigger (&Sender->LastDisarmed);
1493 return 1;
1495 return 0;
1498 //stealing from a store failed, owner triggered
1499 int GameScript::StealFailed(Scriptable* Sender, Trigger* parameters)
1501 switch(Sender->Type) {
1502 case ST_ACTOR:
1503 break;
1504 default:
1505 return 0;
1507 // maybe check if Sender is a shopkeeper???
1509 if (parameters->objectParameter == NULL) {
1510 if (Sender->LastDisarmFailed) {
1511 Sender->AddTrigger (&Sender->LastDisarmFailed);
1512 return 1;
1514 return 0;
1516 if (MatchActor(Sender, Sender->LastDisarmFailed, parameters->objectParameter)) {
1517 Sender->AddTrigger (&Sender->LastDisarmFailed);
1518 return 1;
1520 return 0;
1523 int GameScript::PickpocketFailed(Scriptable* Sender, Trigger* parameters)
1525 switch(Sender->Type) {
1526 case ST_ACTOR:
1527 break;
1528 default:
1529 return 0;
1531 if (parameters->objectParameter == NULL) {
1532 if (Sender->LastOpenFailed) {
1533 Sender->AddTrigger (&Sender->LastOpenFailed);
1534 return 1;
1536 return 0;
1538 if (MatchActor(Sender, Sender->LastOpenFailed, parameters->objectParameter)) {
1539 Sender->AddTrigger (&Sender->LastOpenFailed);
1540 return 1;
1542 return 0;
1545 int GameScript::PickLockFailed(Scriptable* Sender, Trigger* parameters)
1547 switch(Sender->Type) {
1548 case ST_DOOR: case ST_CONTAINER:
1549 break;
1550 default:
1551 return 0;
1553 if (parameters->objectParameter == NULL) {
1554 if (Sender->LastPickLockFailed) {
1555 Sender->AddTrigger (&Sender->LastPickLockFailed);
1556 return 1;
1558 return 0;
1560 if (MatchActor(Sender, Sender->LastPickLockFailed, parameters->objectParameter)) {
1561 Sender->AddTrigger (&Sender->LastPickLockFailed);
1562 return 1;
1564 return 0;
1567 int GameScript::OpenFailed(Scriptable* Sender, Trigger* parameters)
1569 switch(Sender->Type) {
1570 case ST_DOOR: case ST_CONTAINER:
1571 break;
1572 default:
1573 return 0;
1575 if (parameters->objectParameter == NULL) {
1576 if (Sender->LastOpenFailed) {
1577 Sender->AddTrigger (&Sender->LastOpenFailed);
1578 return 1;
1580 return 0;
1582 if (MatchActor(Sender, Sender->LastOpenFailed, parameters->objectParameter
1583 )) {
1584 Sender->AddTrigger (&Sender->LastOpenFailed);
1585 return 1;
1587 return 0;
1590 int GameScript::DisarmFailed(Scriptable* Sender, Trigger* parameters)
1592 switch(Sender->Type) {
1593 case ST_DOOR: case ST_CONTAINER: case ST_PROXIMITY:
1594 break;
1595 default:
1596 return 0;
1598 if (parameters->objectParameter == NULL) {
1599 if (Sender->LastDisarmFailed) {
1600 Sender->AddTrigger (&Sender->LastDisarmFailed);
1601 return 1;
1603 return 0;
1605 if (MatchActor(Sender, Sender->LastDisarmFailed, parameters->objectParameter)) {
1606 Sender->AddTrigger (&Sender->LastDisarmFailed);
1607 return 1;
1609 return 0;
1612 //opened for doors/containers (using lastEntered)
1613 int GameScript::Opened(Scriptable* Sender, Trigger* parameters)
1615 Door *door;
1617 switch (Sender->Type) {
1618 case ST_DOOR:
1619 door = (Door *) Sender;
1620 if (!door->IsOpen()) {
1621 return 0;
1623 break;
1624 case ST_CONTAINER:
1625 break;
1626 default:
1627 return 0;
1630 if (parameters->objectParameter == NULL) {
1631 if (Sender->LastEntered) {
1632 Sender->AddTrigger (&Sender->LastEntered);
1633 return 1;
1635 return 0;
1637 if (MatchActor(Sender, Sender->LastEntered, parameters->objectParameter)) {
1638 Sender->AddTrigger (&Sender->LastEntered);
1639 return 1;
1641 return 0;
1644 //closed for doors (using lastTrigger)
1645 int GameScript::Closed(Scriptable* Sender, Trigger* parameters)
1647 if (Sender->Type != ST_DOOR) {
1648 return 0;
1650 Door *door = (Door *) Sender;
1651 if (door->IsOpen()) {
1652 return 0;
1655 if (parameters->objectParameter == NULL) {
1656 if (Sender->LastTrigger) {
1657 Sender->AddTrigger (&Sender->LastTrigger);
1658 return 1;
1660 return 0;
1662 if (MatchActor(Sender, Sender->LastTrigger, parameters->objectParameter)) {
1663 Sender->AddTrigger (&Sender->LastTrigger);
1664 return 1;
1666 return 0;
1669 //unlocked for doors/containers (using lastUnlocked)
1670 int GameScript::Unlocked(Scriptable* Sender, Trigger* parameters)
1672 Door *door;
1674 switch (Sender->Type) {
1675 case ST_DOOR:
1676 door = (Door *) Sender;
1677 if ((door->Flags&DOOR_LOCKED) ) {
1678 return 0;
1680 break;
1681 case ST_CONTAINER:
1682 break;
1683 default:
1684 return 0;
1687 if (parameters->objectParameter == NULL) {
1688 if (Sender->LastUnlocked) {
1689 Sender->AddTrigger (&Sender->LastUnlocked);
1690 return 1;
1692 return 0;
1694 if (MatchActor(Sender, Sender->LastUnlocked, parameters->objectParameter)) {
1695 Sender->AddTrigger (&Sender->LastUnlocked);
1696 return 1;
1698 return 0;
1701 int GameScript::Entered(Scriptable* Sender, Trigger* parameters)
1703 if (Sender->Type != ST_PROXIMITY) {
1704 return 0;
1706 InfoPoint *ip = (InfoPoint *) Sender;
1707 if (!ip->Trapped) {
1708 return 0;
1711 if (parameters->objectParameter == NULL) {
1712 if (Sender->LastEntered) {
1713 Sender->AddTrigger (&Sender->LastEntered);
1714 return 1;
1716 return 0;
1718 if (MatchActor(Sender, Sender->LastEntered, parameters->objectParameter)) {
1719 Sender->AddTrigger (&Sender->LastEntered);
1720 return 1;
1722 return 0;
1725 int GameScript::HarmlessEntered(Scriptable* Sender, Trigger* parameters)
1727 if (Sender->Type != ST_PROXIMITY) {
1728 return 0;
1730 if (parameters->objectParameter == NULL) {
1731 if (Sender->LastEntered) {
1732 Sender->AddTrigger (&Sender->LastEntered);
1733 return 1;
1735 return 0;
1737 if (MatchActor(Sender, Sender->LastEntered, parameters->objectParameter)) {
1738 Sender->AddTrigger (&Sender->LastEntered);
1739 return 1;
1741 return 0;
1744 int GameScript::IsOverMe(Scriptable* Sender, Trigger* parameters)
1746 if (Sender->Type != ST_PROXIMITY) {
1747 return 0;
1749 Highlightable *trap = (Highlightable *)Sender;
1751 Targets *tgts = GetAllObjects(Sender->GetCurrentArea(), Sender, parameters->objectParameter, GA_NO_DEAD);
1752 int ret = 0;
1753 if (tgts) {
1754 targetlist::iterator m;
1755 const targettype *tt = tgts->GetFirstTarget(m, ST_ACTOR);
1756 while (tt) {
1757 Actor *actor = (Actor *) tt->actor;
1758 if (trap->IsOver(actor->Pos)) {
1759 ret = 1;
1760 break;
1762 tt = tgts->GetNextTarget(m, ST_ACTOR);
1765 delete tgts;
1766 return ret;
1769 //this function is different in every engines, if you use a string0parameter
1770 //then it will be considered as a variable check
1771 //you can also use an object parameter (like in iwd)
1772 int GameScript::Dead(Scriptable* Sender, Trigger* parameters)
1774 if (parameters->string0Parameter[0]) {
1775 ieDword value;
1776 ieVariable Variable;
1778 if (core->HasFeature( GF_HAS_KAPUTZ )) {
1779 value = CheckVariable( Sender, parameters->string0Parameter, "KAPUTZ");
1780 } else {
1781 snprintf( Variable, 32, core->GetDeathVarFormat(), parameters->string0Parameter );
1783 value = CheckVariable( Sender, Variable, "GLOBAL" );
1784 if (value>0) {
1785 return 1;
1787 return 0;
1789 Scriptable* target = GetActorFromObject( Sender, parameters->objectParameter );
1790 if (!target) {
1791 return 1;
1793 if (target->Type != ST_ACTOR) {
1794 return 1;
1796 Actor* actor = ( Actor* ) target;
1797 if (actor->GetStat( IE_STATE_ID ) & STATE_DEAD) {
1798 return 1;
1800 return 0;
1803 int GameScript::CreatureHidden(Scriptable* Sender, Trigger* /*parameters*/)
1805 if (Sender->Type!=ST_ACTOR) {
1806 return 0;
1808 Actor *act=(Actor *) Sender;
1810 //this stuff is not completely clear, but HoW has a flag for this
1811 //and GemRB uses the avatarremoval stat for it.
1812 //HideCreature also sets this stat, so...
1813 if (act->GetStat(IE_AVATARREMOVAL)) {
1814 return 1;
1817 if (act->GetInternalFlag()&IF_VISIBLE) {
1818 return 0;
1820 return 1;
1822 int GameScript::BecameVisible(Scriptable* Sender, Trigger* /*parameters*/)
1824 if (Sender->Type!=ST_ACTOR) {
1825 return 0;
1827 Actor *act=(Actor *) Sender;
1828 if (act->GetInternalFlag()&IF_BECAMEVISIBLE) {
1829 //set trigger to erase
1830 act->SetBitTrigger(BT_BECAMEVISIBLE);
1831 return 1;
1833 return 0;
1836 int GameScript::Die(Scriptable* Sender, Trigger* /*parameters*/)
1838 if (Sender->Type!=ST_ACTOR) {
1839 return 0;
1841 Actor *act=(Actor *) Sender;
1842 if (act->GetInternalFlag()&IF_JUSTDIED) {
1843 //set trigger to erase
1844 act->SetBitTrigger(BT_DIE);
1845 return 1;
1847 return 0;
1850 int GameScript::Died(Scriptable* Sender, Trigger* parameters)
1852 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
1853 if (!tar || tar->Type!=ST_ACTOR) {
1854 return 0;
1856 Actor *act=(Actor *) tar;
1857 if (act->GetInternalFlag()&IF_JUSTDIED) {
1858 //set trigger to erase
1859 act->SetBitTrigger(BT_DIE);
1860 return 1;
1862 return 0;
1865 int GameScript::PartyMemberDied(Scriptable* /*Sender*/, Trigger* /*parameters*/)
1867 Game *game = core->GetGame();
1868 int i = game->PartyMemberDied();
1869 if (i==-1) {
1870 return 0;
1872 //set trigger to erase
1873 game->GetPC(i,false)->SetBitTrigger(BT_DIE);
1874 return 1;
1877 int GameScript::NamelessBitTheDust(Scriptable* /*Sender*/, Trigger* /*parameters*/)
1879 Actor* actor = core->GetGame()->GetPC(0, false);
1880 if (actor->GetInternalFlag()&IF_JUSTDIED) {
1881 //set trigger to clear
1882 actor->SetBitTrigger(BT_DIE);
1883 return 1;
1885 return 0;
1888 int GameScript::Race(Scriptable* Sender, Trigger* parameters)
1890 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1891 if (!scr) {
1892 return 0;
1894 if (scr->Type != ST_ACTOR) {
1895 return 0;
1897 Actor* actor = ( Actor* ) scr;
1898 return ID_Race(actor, parameters->int0Parameter);
1901 int GameScript::Gender(Scriptable* Sender, Trigger* parameters)
1903 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1904 if (!scr) {
1905 return 0;
1907 if (scr->Type != ST_ACTOR) {
1908 return 0;
1910 Actor* actor = ( Actor* ) scr;
1911 return ID_Gender(actor, parameters->int0Parameter);
1914 int GameScript::HP(Scriptable* Sender, Trigger* parameters)
1916 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1917 if (!scr) {
1918 return 0;
1920 if (scr->Type != ST_ACTOR) {
1921 return 0;
1923 Actor* actor = ( Actor* ) scr;
1924 if ((signed) actor->GetBase( IE_HITPOINTS ) == parameters->int0Parameter) {
1925 return 1;
1927 return 0;
1930 int GameScript::HPGT(Scriptable* Sender, Trigger* parameters)
1932 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1933 if (!scr) {
1934 return 0;
1936 if (scr->Type != ST_ACTOR) {
1937 return 0;
1939 Actor* actor = ( Actor* ) scr;
1940 if ( (signed) actor->GetBase( IE_HITPOINTS ) > parameters->int0Parameter) {
1941 return 1;
1943 return 0;
1946 int GameScript::HPLT(Scriptable* Sender, Trigger* parameters)
1948 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
1949 if (!scr) {
1950 return 0;
1952 if (scr->Type != ST_ACTOR) {
1953 return 0;
1955 Actor* actor = ( Actor* ) scr;
1956 if ( (signed) actor->GetBase( IE_HITPOINTS ) < parameters->int0Parameter) {
1957 return 1;
1959 return 0;
1962 //these triggers work on the current damage (not the last damage)
1963 /* they are identical to HPLost
1964 int GameScript::DamageTaken(Scriptable* Sender, Trigger* parameters)
1966 if (Sender->Type!=ST_ACTOR) {
1967 return 0;
1969 Actor* actor = ( Actor* ) Sender;
1970 int damage = actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
1971 if (damage==(int) parameters->int0Parameter) {
1972 return 1;
1974 return 0;
1977 int GameScript::DamageTakenGT(Scriptable* Sender, Trigger* parameters)
1979 if (Sender->Type!=ST_ACTOR) {
1980 return 0;
1982 Actor* actor = ( Actor* ) Sender;
1983 int damage = actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
1984 if (damage>(int) parameters->int0Parameter) {
1985 return 1;
1987 return 0;
1990 int GameScript::DamageTakenLT(Scriptable* Sender, Trigger* parameters)
1992 if (Sender->Type!=ST_ACTOR) {
1993 return 0;
1995 Actor* actor = ( Actor* ) Sender;
1996 int damage = actor->GetStat(IE_MAXHITPOINTS)-actor->GetBase(IE_HITPOINTS);
1997 if (damage<(int) parameters->int0Parameter) {
1998 return 1;
2000 return 0;
2004 int GameScript::HPLost(Scriptable* Sender, Trigger* parameters)
2006 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
2007 if (!scr) {
2008 return 0;
2010 if (scr->Type != ST_ACTOR) {
2011 return 0;
2013 Actor* actor = ( Actor* ) scr;
2014 //max-current
2015 if ( (signed) actor->GetStat(IE_MAXHITPOINTS)-(signed) actor->GetBase( IE_HITPOINTS ) == (signed) parameters->int0Parameter) {
2016 return 1;
2018 return 0;
2021 int GameScript::HPLostGT(Scriptable* Sender, Trigger* parameters)
2023 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
2024 if (!scr) {
2025 return 0;
2027 if (scr->Type != ST_ACTOR) {
2028 return 0;
2030 Actor* actor = ( Actor* ) scr;
2031 //max-current
2032 if ( (signed) actor->GetStat(IE_MAXHITPOINTS)-(signed) actor->GetBase( IE_HITPOINTS ) > (signed) parameters->int0Parameter) {
2033 return 1;
2035 return 0;
2038 int GameScript::HPLostLT(Scriptable* Sender, Trigger* parameters)
2040 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
2041 if (!scr) {
2042 return 0;
2044 if (scr->Type != ST_ACTOR) {
2045 return 0;
2047 Actor* actor = ( Actor* ) scr;
2048 //max-current
2049 if ( (signed) actor->GetStat(IE_MAXHITPOINTS)-(signed) actor->GetBase( IE_HITPOINTS ) < (signed) parameters->int0Parameter) {
2050 return 1;
2052 return 0;
2055 int GameScript::HPPercent(Scriptable* Sender, Trigger* parameters)
2057 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
2058 if (!scr) {
2059 return 0;
2061 if (GetHPPercent( scr ) == parameters->int0Parameter) {
2062 return 1;
2064 return 0;
2067 int GameScript::HPPercentGT(Scriptable* Sender, Trigger* parameters)
2069 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
2070 if (!scr) {
2071 return 0;
2073 if (GetHPPercent( scr ) > parameters->int0Parameter) {
2074 return 1;
2076 return 0;
2079 int GameScript::HPPercentLT(Scriptable* Sender, Trigger* parameters)
2081 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
2082 if (!scr) {
2083 return 0;
2085 if (GetHPPercent( scr ) < parameters->int0Parameter) {
2086 return 1;
2088 return 0;
2091 int GameScript::XP(Scriptable* Sender, Trigger* parameters)
2093 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
2094 if (!scr) {
2095 return 0;
2097 if (scr->Type != ST_ACTOR) {
2098 return 0;
2100 Actor* actor = ( Actor* ) scr;
2101 if (actor->GetStat( IE_XP ) == (unsigned) parameters->int0Parameter) {
2102 return 1;
2104 return 0;
2107 int GameScript::XPGT(Scriptable* Sender, Trigger* parameters)
2109 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
2110 if (!scr) {
2111 return 0;
2113 if (scr->Type != ST_ACTOR) {
2114 return 0;
2116 Actor* actor = ( Actor* ) scr;
2117 if (actor->GetStat( IE_XP ) > (unsigned) parameters->int0Parameter) {
2118 return 1;
2120 return 0;
2123 int GameScript::XPLT(Scriptable* Sender, Trigger* parameters)
2125 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
2126 if (!scr) {
2127 return 0;
2129 if (scr->Type != ST_ACTOR) {
2130 return 0;
2132 Actor* actor = ( Actor* ) scr;
2133 if (actor->GetStat( IE_XP ) < (unsigned) parameters->int0Parameter) {
2134 return 1;
2136 return 0;
2139 int GameScript::CheckSkill(Scriptable* Sender, Trigger* parameters)
2141 if (parameters->int1Parameter>=SkillCount) {
2142 return 0;
2144 Scriptable* target = GetActorFromObject( Sender, parameters->objectParameter );
2145 if (!target) {
2146 return 0;
2148 if (target->Type != ST_ACTOR) {
2149 return 0;
2151 Actor* actor = ( Actor* ) target;
2152 if ((signed) actor->GetStat( SkillStats[parameters->int1Parameter] ) == parameters->int0Parameter) {
2153 return 1;
2155 return 0;
2157 int GameScript::CheckStat(Scriptable* Sender, Trigger* parameters)
2159 Scriptable* target = GetActorFromObject( Sender, parameters->objectParameter );
2160 if (!target) {
2161 return 0;
2163 if (target->Type != ST_ACTOR) {
2164 return 0;
2166 Actor* actor = ( Actor* ) target;
2167 if ((signed) actor->GetStat( parameters->int1Parameter ) == parameters->int0Parameter) {
2168 return 1;
2170 return 0;
2173 int GameScript::CheckSkillGT(Scriptable* Sender, Trigger* parameters)
2175 if (parameters->int1Parameter>=SkillCount) {
2176 return 0;
2178 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2179 if (!tar || tar->Type != ST_ACTOR) {
2180 return 0;
2182 Actor* actor = ( Actor* ) tar;
2183 if ((signed) actor->GetStat( SkillStats[parameters->int1Parameter] ) > parameters->int0Parameter) {
2184 return 1;
2186 return 0;
2189 int GameScript::CheckStatGT(Scriptable* Sender, Trigger* parameters)
2191 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2192 if (!tar || tar->Type != ST_ACTOR) {
2193 return 0;
2195 Actor* actor = ( Actor* ) tar;
2196 if ((signed) actor->GetStat( parameters->int1Parameter ) > parameters->int0Parameter) {
2197 return 1;
2199 return 0;
2202 int GameScript::CheckSkillLT(Scriptable* Sender, Trigger* parameters)
2204 if (parameters->int1Parameter>=SkillCount) {
2205 return 0;
2207 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2208 if (!tar || tar->Type != ST_ACTOR) {
2209 return 0;
2211 Actor* actor = ( Actor* ) tar;
2212 if ((signed) actor->GetStat( SkillStats[parameters->int1Parameter] ) < parameters->int0Parameter) {
2213 return 1;
2215 return 0;
2218 int GameScript::CheckStatLT(Scriptable* Sender, Trigger* parameters)
2220 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2221 if (!tar || tar->Type != ST_ACTOR) {
2222 return 0;
2224 Actor* actor = ( Actor* ) tar;
2225 if ((signed) actor->GetStat( parameters->int1Parameter ) < parameters->int0Parameter) {
2226 return 1;
2228 return 0;
2231 /* i believe this trigger is the same as 'MarkObject' action
2232 except that if it cannot set the marked object, it returns false */
2233 int GameScript::SetLastMarkedObject(Scriptable* Sender, Trigger* parameters)
2235 if (Sender->Type != ST_ACTOR) {
2236 return 0;
2238 Actor *scr = (Actor *) Sender;
2240 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2241 if (!tar || tar->Type != ST_ACTOR) {
2242 return 0;
2244 Actor* actor = ( Actor* ) tar;
2245 scr->LastMarked = actor->GetID();
2246 return 1;
2249 int GameScript::See(Scriptable* Sender, Trigger* parameters)
2251 int see = SeeCore(Sender, parameters, 0);
2252 //don't mark LastSeen for clear!!!
2253 if (Sender->Type==ST_ACTOR && see) {
2254 Actor *act = (Actor *) Sender;
2255 //save lastseen as lastmarked
2256 act->LastMarked = act->LastSeen;
2257 //Sender->AddTrigger (&act->LastSeen);
2259 return see;
2262 //unsure if this should be different from see, we'll see :)
2263 int GameScript::Detect(Scriptable* Sender, Trigger* parameters)
2265 parameters->int0Parameter=1; //seedead
2266 int see = SeeCore(Sender, parameters, 0);
2267 if (!see) {
2268 return 0;
2270 return 1;
2273 int GameScript::LOS(Scriptable* Sender, Trigger* parameters)
2275 int see=SeeCore(Sender, parameters, 1);
2276 if (!see) {
2277 return 0;
2279 return Range(Sender, parameters); //same as range
2282 int GameScript::NumCreatures(Scriptable* Sender, Trigger* parameters)
2284 int value = GetObjectCount(Sender, parameters->objectParameter);
2285 return value == parameters->int0Parameter;
2288 int GameScript::NumCreaturesAtMyLevel(Scriptable* Sender, Trigger* parameters)
2290 if (Sender->Type != ST_ACTOR) {
2291 return 0;
2293 int level = ((Actor *) Sender)->GetXPLevel(true);
2294 int value;
2296 if (parameters->int0Parameter) {
2297 value = GetObjectLevelCount(Sender, parameters->objectParameter);
2298 } else {
2299 value = GetObjectCount(Sender, parameters->objectParameter);
2301 return value == level;
2304 int GameScript::NumCreaturesLT(Scriptable* Sender, Trigger* parameters)
2306 int value = GetObjectCount(Sender, parameters->objectParameter);
2307 return value < parameters->int0Parameter;
2310 int GameScript::NumCreaturesLTMyLevel(Scriptable* Sender, Trigger* parameters)
2312 if (Sender->Type != ST_ACTOR) {
2313 return 0;
2315 int level = ((Actor *) Sender)->GetXPLevel(true);
2316 int value;
2318 if (parameters->int0Parameter) {
2319 value = GetObjectLevelCount(Sender, parameters->objectParameter);
2320 } else {
2321 value = GetObjectCount(Sender, parameters->objectParameter);
2323 return value < level;
2326 int GameScript::NumCreaturesGT(Scriptable* Sender, Trigger* parameters)
2328 int value = GetObjectCount(Sender, parameters->objectParameter);
2329 return value > parameters->int0Parameter;
2332 int GameScript::NumCreaturesGTMyLevel(Scriptable* Sender, Trigger* parameters)
2334 if (Sender->Type != ST_ACTOR) {
2335 return 0;
2337 int level = ((Actor *) Sender)->GetXPLevel(true);
2338 int value;
2340 if (parameters->int0Parameter) {
2341 value = GetObjectLevelCount(Sender, parameters->objectParameter);
2342 } else {
2343 value = GetObjectCount(Sender, parameters->objectParameter);
2345 return value > level;
2348 int GameScript::NumCreatureVsParty(Scriptable* Sender, Trigger* parameters)
2350 //creating object on the spot
2351 if (!parameters->objectParameter) {
2352 parameters->objectParameter = new Object();
2354 parameters->objectParameter->objectFields[0]=EA_EVILCUTOFF;
2355 int value = GetObjectCount(Sender, parameters->objectParameter);
2356 return value == parameters->int0Parameter;
2359 int GameScript::NumCreatureVsPartyGT(Scriptable* Sender, Trigger* parameters)
2361 if (!parameters->objectParameter) {
2362 parameters->objectParameter = new Object();
2364 parameters->objectParameter->objectFields[0]=EA_EVILCUTOFF;
2365 int value = GetObjectCount(Sender, parameters->objectParameter);
2366 return value > parameters->int0Parameter;
2369 int GameScript::NumCreatureVsPartyLT(Scriptable* Sender, Trigger* parameters)
2371 if (!parameters->objectParameter) {
2372 parameters->objectParameter = new Object();
2374 parameters->objectParameter->objectFields[0]=EA_EVILCUTOFF;
2375 int value = GetObjectCount(Sender, parameters->objectParameter);
2376 return value < parameters->int0Parameter;
2379 int GameScript::Morale(Scriptable* Sender, Trigger* parameters)
2381 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2382 if (!tar || tar->Type != ST_ACTOR) {
2383 return 0;
2385 Actor* actor = ( Actor* ) tar;
2386 return (signed) actor->GetStat(IE_MORALEBREAK) == parameters->int0Parameter;
2389 int GameScript::MoraleGT(Scriptable* Sender, Trigger* parameters)
2391 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2392 if (!tar || tar->Type != ST_ACTOR) {
2393 return 0;
2395 Actor* actor = ( Actor* ) tar;
2396 return (signed) actor->GetStat(IE_MORALEBREAK) > parameters->int0Parameter;
2399 int GameScript::MoraleLT(Scriptable* Sender, Trigger* parameters)
2401 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2402 if (!tar || tar->Type != ST_ACTOR) {
2403 return 0;
2405 Actor* actor = ( Actor* ) tar;
2406 return (signed) actor->GetStat(IE_MORALEBREAK) < parameters->int0Parameter;
2409 int GameScript::CheckSpellState(Scriptable* Sender, Trigger* parameters)
2411 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2412 if (!tar || tar->Type != ST_ACTOR) {
2413 return 0;
2415 Actor* actor = ( Actor* ) tar;
2416 if (parameters->int0Parameter>255) {
2417 return 0;
2419 unsigned int position = parameters->int0Parameter>>5;
2420 unsigned int bit = 1<<(parameters->int0Parameter&31);
2421 if (actor->GetStat(IE_SPLSTATE_ID1+position) & bit) {
2422 return 1;
2424 return 0;
2427 int GameScript::StateCheck(Scriptable* Sender, Trigger* parameters)
2429 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2430 if (!tar || tar->Type != ST_ACTOR) {
2431 return 0;
2433 Actor* actor = ( Actor* ) tar;
2434 if (actor->GetStat(IE_STATE_ID) & parameters->int0Parameter) {
2435 return 1;
2437 return 0;
2440 int GameScript::ExtendedStateCheck(Scriptable* Sender, Trigger* parameters)
2442 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2443 if (!tar || tar->Type != ST_ACTOR) {
2444 return 0;
2446 Actor* actor = ( Actor* ) tar;
2447 if (actor->GetStat(IE_EXTSTATE_ID) & parameters->int0Parameter) {
2448 return 1;
2450 return 0;
2453 int GameScript::NotStateCheck(Scriptable* Sender, Trigger* parameters)
2455 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2456 if (!tar || tar->Type != ST_ACTOR) {
2457 return 0;
2459 Actor* actor = ( Actor* ) tar;
2460 if (actor->GetStat(IE_STATE_ID) & ~parameters->int0Parameter) {
2461 return 1;
2463 return 0;
2466 int GameScript::RandomNum(Scriptable* /*Sender*/, Trigger* parameters)
2468 if (parameters->int0Parameter<0) {
2469 return 0;
2471 if (parameters->int1Parameter<0) {
2472 return 0;
2474 return parameters->int1Parameter-1 == RandomNumValue%parameters->int0Parameter;
2477 int GameScript::RandomNumGT(Scriptable* /*Sender*/, Trigger* parameters)
2479 if (parameters->int0Parameter<0) {
2480 return 0;
2482 if (parameters->int1Parameter<0) {
2483 return 0;
2485 return parameters->int1Parameter-1 < RandomNumValue%parameters->int0Parameter;
2488 int GameScript::RandomNumLT(Scriptable* /*Sender*/, Trigger* parameters)
2490 if (parameters->int0Parameter<0) {
2491 return 0;
2493 if (parameters->int1Parameter<0) {
2494 return 0;
2496 return parameters->int1Parameter-1 > RandomNumValue%parameters->int0Parameter;
2499 int GameScript::OpenState(Scriptable* Sender, Trigger* parameters)
2501 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2502 if (!tar) {
2503 if (InDebug&ID_TRIGGERS) {
2504 printMessage("GameScript"," ",LIGHT_RED);
2505 printf("Couldn't find door/container:%s\n", parameters->objectParameter? parameters->objectParameter->objectName:"<NULL>");
2506 printf("Sender: %s\n", Sender->GetScriptName() );
2508 return 0;
2510 switch(tar->Type) {
2511 case ST_DOOR:
2513 Door *door =(Door *) tar;
2514 return !door->IsOpen() == !parameters->int0Parameter;
2516 case ST_CONTAINER:
2518 Container *cont = (Container *) tar;
2519 return !(cont->Flags&CONT_LOCKED) == !parameters->int0Parameter;
2521 default:; //to remove a warning
2523 printMessage("GameScript"," ",LIGHT_RED);
2524 printf("Not a door/container:%s\n", tar->GetScriptName());
2525 return 0;
2528 int GameScript::IsLocked(Scriptable * Sender, Trigger *parameters)
2530 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2531 if (!tar) {
2532 printMessage("GameScript"," ",LIGHT_RED);
2533 printf("Couldn't find door/container:%s\n", parameters->objectParameter? parameters->objectParameter->objectName:"<NULL>");
2534 printf("Sender: %s\n", Sender->GetScriptName() );
2535 return 0;
2537 switch(tar->Type) {
2538 case ST_DOOR:
2540 Door *door =(Door *) tar;
2541 return !!(door->Flags&DOOR_LOCKED);
2543 case ST_CONTAINER:
2545 Container *cont = (Container *) tar;
2546 return !!(cont->Flags&CONT_LOCKED);
2548 default:; //to remove a warning
2550 printMessage("GameScript"," ",LIGHT_RED);
2551 printf("Not a door/container:%s\n", tar->GetScriptName());
2552 return 0;
2555 int GameScript::Level(Scriptable* Sender, Trigger* parameters)
2557 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2558 if (!tar) {
2559 return 0;
2561 if (tar->Type != ST_ACTOR) {
2562 return 0;
2564 Actor* actor = ( Actor* ) tar;
2565 return actor->GetStat(IE_LEVEL) == (unsigned) parameters->int0Parameter;
2568 //this is just a hack, actually multiclass should be available
2569 int GameScript::ClassLevel(Scriptable* Sender, Trigger* parameters)
2571 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2572 if (!tar) {
2573 return 0;
2575 if (tar->Type != ST_ACTOR) {
2576 return 0;
2578 Actor* actor = ( Actor* ) tar;
2580 if (!ID_ClassMask( actor, parameters->int0Parameter) )
2581 return 0;
2582 return actor->GetStat(IE_LEVEL) == (unsigned) parameters->int1Parameter;
2585 int GameScript::LevelGT(Scriptable* Sender, Trigger* parameters)
2587 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2588 if (!tar) {
2589 return 0;
2591 if (tar->Type != ST_ACTOR) {
2592 return 0;
2594 Actor* actor = ( Actor* ) tar;
2595 return actor->GetStat(IE_LEVEL) > (unsigned) parameters->int0Parameter;
2598 //this is just a hack, actually multiclass should be available
2599 int GameScript::ClassLevelGT(Scriptable* Sender, Trigger* parameters)
2601 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2602 if (!tar) {
2603 return 0;
2605 if (tar->Type != ST_ACTOR) {
2606 return 0;
2608 Actor* actor = ( Actor* ) tar;
2609 if (!ID_ClassMask( actor, parameters->int0Parameter) )
2610 return 0;
2611 return actor->GetStat(IE_LEVEL) > (unsigned) parameters->int1Parameter;
2614 int GameScript::LevelLT(Scriptable* Sender, Trigger* parameters)
2616 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2617 if (!tar) {
2618 return 0;
2620 if (tar->Type != ST_ACTOR) {
2621 return 0;
2623 Actor* actor = ( Actor* ) tar;
2624 return actor->GetStat(IE_LEVEL) < (unsigned) parameters->int0Parameter;
2627 int GameScript::ClassLevelLT(Scriptable* Sender, Trigger* parameters)
2629 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2630 if (!tar) {
2631 return 0;
2633 if (tar->Type != ST_ACTOR) {
2634 return 0;
2636 Actor* actor = ( Actor* ) tar;
2637 if (!ID_ClassMask( actor, parameters->int0Parameter) )
2638 return 0;
2639 return actor->GetStat(IE_LEVEL) < (unsigned) parameters->int1Parameter;
2642 int GameScript::UnselectableVariable(Scriptable* Sender, Trigger* parameters)
2644 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2645 if (!tar) {
2646 return 0;
2648 return tar->UnselectableTimer == (unsigned) parameters->int0Parameter;
2651 int GameScript::UnselectableVariableGT(Scriptable* Sender, Trigger* parameters)
2653 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2654 if (!tar) {
2655 return 0;
2657 return tar->UnselectableTimer > (unsigned) parameters->int0Parameter;
2660 int GameScript::UnselectableVariableLT(Scriptable* Sender, Trigger* parameters)
2662 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2663 if (!tar) {
2664 return 0;
2666 return tar->UnselectableTimer < (unsigned) parameters->int0Parameter;
2669 int GameScript::AreaCheck(Scriptable* Sender, Trigger* parameters)
2671 if (!strnicmp(Sender->GetCurrentArea()->GetScriptName(), parameters->string0Parameter, 8)) {
2672 return 1;
2674 return 0;
2677 int GameScript::AreaCheckObject(Scriptable* Sender, Trigger* parameters)
2679 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2681 if (!tar) {
2682 return 0;
2684 if (!strnicmp(tar->GetCurrentArea()->GetScriptName(), parameters->string0Parameter, 8)) {
2685 return 1;
2687 return 0;
2690 //lame iwd2 uses a numeric area identifier, this reduces its usability
2691 int GameScript::CurrentAreaIs(Scriptable* Sender, Trigger* parameters)
2693 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2695 if (!tar) {
2696 return 0;
2698 ieResRef arearesref;
2699 snprintf(arearesref, 8, "AR%04d", parameters->int0Parameter);
2700 if (!strnicmp(tar->GetCurrentArea()->GetScriptName(), arearesref, 8)) {
2701 return 1;
2703 return 0;
2706 //lame bg2 uses a constant areaname prefix, this reduces its usability
2707 //but in the spirit of flexibility, gemrb extension allows arbitrary prefixes
2708 int GameScript::AreaStartsWith(Scriptable* Sender, Trigger* parameters)
2710 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2712 if (!tar) {
2713 return 0;
2715 ieResRef arearesref;
2716 if (parameters->string0Parameter[0]) {
2717 strnlwrcpy(arearesref, parameters->string0Parameter, 8);
2718 } else {
2719 strnlwrcpy(arearesref, "AR30", 8); //InWatchersKeep
2721 int i = strlen(arearesref);
2722 if (!strnicmp(tar->GetCurrentArea()->GetScriptName(), arearesref, i)) {
2723 return 1;
2725 return 0;
2728 int GameScript::EntirePartyOnMap(Scriptable* Sender, Trigger* /*parameters*/)
2730 Map *map = Sender->GetCurrentArea();
2731 Game *game=core->GetGame();
2732 int i=game->GetPartySize(true);
2733 while (i--) {
2734 Actor *actor=game->GetPC(i,true);
2735 if (actor->GetCurrentArea()!=map) {
2736 return 0;
2739 return 1;
2742 int GameScript::AnyPCOnMap(Scriptable* Sender, Trigger* /*parameters*/)
2744 Map *map = Sender->GetCurrentArea();
2745 Game *game=core->GetGame();
2746 int i=game->GetPartySize(true);
2747 while (i--) {
2748 Actor *actor=game->GetPC(i,true);
2749 if (actor->GetCurrentArea()==map) {
2750 return 1;
2753 return 0;
2756 int GameScript::InActiveArea(Scriptable* Sender, Trigger* parameters)
2758 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2759 if (!tar) {
2760 return 0;
2762 if (core->GetGame()->GetCurrentArea() == tar->GetCurrentArea()) {
2763 return 1;
2765 return 0;
2768 int GameScript::InMyArea(Scriptable* Sender, Trigger* parameters)
2770 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2771 if (!tar) {
2772 return 0;
2774 if (Sender->GetCurrentArea() == tar->GetCurrentArea()) {
2775 return 1;
2777 return 0;
2780 int GameScript::AreaType(Scriptable* Sender, Trigger* parameters)
2782 Map *map=Sender->GetCurrentArea();
2783 return (map->AreaType&parameters->int0Parameter)>0;
2786 int GameScript::IsExtendedNight( Scriptable* Sender, Trigger* /*parameters*/)
2788 Map *map=Sender->GetCurrentArea();
2789 if (map->AreaType&AT_EXTENDED_NIGHT) {
2790 return 1;
2792 return 0;
2795 int GameScript::AreaFlag(Scriptable* Sender, Trigger* parameters)
2797 Map *map=Sender->GetCurrentArea();
2798 return (map->AreaFlags&parameters->int0Parameter)>0;
2801 int GameScript::AreaRestDisabled(Scriptable* Sender, Trigger* /*parameters*/)
2803 Map *map=Sender->GetCurrentArea();
2804 if (map->AreaFlags&2) {
2805 return 1;
2807 return 0;
2810 //new optional parameter: size of actor (to reach target)
2811 int GameScript::TargetUnreachable(Scriptable* Sender, Trigger* parameters)
2813 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2814 if (!tar || tar->Type != ST_ACTOR) {
2815 return 1; //well, if it doesn't exist it is unreachable
2817 Map *map=Sender->GetCurrentArea();
2818 if (!map) {
2819 return 1;
2821 unsigned int size = parameters->int0Parameter;
2823 if (!size) {
2824 if (Sender->Type==ST_ACTOR) {
2825 size = ((Movable *) Sender)->size;
2827 else {
2828 size = 1;
2831 return map->TargetUnreachable( Sender->Pos, tar->Pos, size);
2834 int GameScript::PartyCountEQ(Scriptable* /*Sender*/, Trigger* parameters)
2836 return core->GetGame()->GetPartySize(0)==parameters->int0Parameter;
2839 int GameScript::PartyCountLT(Scriptable* /*Sender*/, Trigger* parameters)
2841 return core->GetGame()->GetPartySize(0)<parameters->int0Parameter;
2844 int GameScript::PartyCountGT(Scriptable* /*Sender*/, Trigger* parameters)
2846 return core->GetGame()->GetPartySize(0)>parameters->int0Parameter;
2849 int GameScript::PartyCountAliveEQ(Scriptable* /*Sender*/, Trigger* parameters)
2851 return core->GetGame()->GetPartySize(1)==parameters->int0Parameter;
2854 int GameScript::PartyCountAliveLT(Scriptable* /*Sender*/, Trigger* parameters)
2856 return core->GetGame()->GetPartySize(1)<parameters->int0Parameter;
2859 int GameScript::PartyCountAliveGT(Scriptable* /*Sender*/, Trigger* parameters)
2861 return core->GetGame()->GetPartySize(1)>parameters->int0Parameter;
2864 int GameScript::LevelParty(Scriptable* /*Sender*/, Trigger* parameters)
2866 return core->GetGame()->GetPartyLevel(1)==parameters->int0Parameter;
2869 int GameScript::LevelPartyLT(Scriptable* /*Sender*/, Trigger* parameters)
2871 return core->GetGame()->GetPartyLevel(1)<parameters->int0Parameter;
2874 int GameScript::LevelPartyGT(Scriptable* /*Sender*/, Trigger* parameters)
2876 return core->GetGame()->GetPartyLevel(1)>parameters->int0Parameter;
2879 int GameScript::PartyGold(Scriptable* /*Sender*/, Trigger* parameters)
2881 return core->GetGame()->PartyGold == (ieDword) parameters->int0Parameter;
2884 int GameScript::PartyGoldGT(Scriptable* /*Sender*/, Trigger* parameters)
2886 return core->GetGame()->PartyGold > (ieDword) parameters->int0Parameter;
2889 int GameScript::PartyGoldLT(Scriptable* /*Sender*/, Trigger* parameters)
2891 return core->GetGame()->PartyGold < (ieDword) parameters->int0Parameter;
2894 int GameScript::OwnsFloaterMessage(Scriptable* Sender, Trigger* parameters)
2896 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2897 if (!tar) {
2898 return 0;
2900 return tar->textDisplaying;
2903 int GameScript::InCutSceneMode(Scriptable* /*Sender*/, Trigger* /*parameters*/)
2905 return core->InCutSceneMode();
2908 int GameScript::Proficiency(Scriptable* Sender, Trigger* parameters)
2910 unsigned int idx = parameters->int0Parameter;
2911 if (idx>31) {
2912 return 0;
2914 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2915 if (!tar) {
2916 return 0;
2918 if (tar->Type != ST_ACTOR) {
2919 return 0;
2921 Actor* actor = ( Actor* ) tar;
2922 return (signed) actor->GetStat(IE_PROFICIENCYBASTARDSWORD+idx) == parameters->int1Parameter;
2925 int GameScript::ProficiencyGT(Scriptable* Sender, Trigger* parameters)
2927 unsigned int idx = parameters->int0Parameter;
2928 if (idx>31) {
2929 return 0;
2931 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2932 if (!tar) {
2933 return 0;
2935 if (tar->Type != ST_ACTOR) {
2936 return 0;
2938 Actor* actor = ( Actor* ) tar;
2939 return (signed) actor->GetStat(IE_PROFICIENCYBASTARDSWORD+idx) > parameters->int1Parameter;
2942 int GameScript::ProficiencyLT(Scriptable* Sender, Trigger* parameters)
2944 unsigned int idx = parameters->int0Parameter;
2945 if (idx>31) {
2946 return 0;
2948 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2949 if (!tar) {
2950 return 0;
2952 if (tar->Type != ST_ACTOR) {
2953 return 0;
2955 Actor* actor = ( Actor* ) tar;
2956 return (signed) actor->GetStat(IE_PROFICIENCYBASTARDSWORD+idx) < parameters->int1Parameter;
2959 //this is a PST specific stat, shows how many free proficiency slots we got
2960 //we use an unused stat for it
2961 int GameScript::ExtraProficiency(Scriptable* Sender, Trigger* parameters)
2963 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2964 if (!tar) {
2965 return 0;
2967 if (tar->Type != ST_ACTOR) {
2968 return 0;
2970 Actor* actor = ( Actor* ) tar;
2971 return (signed) actor->GetStat(IE_FREESLOTS) == parameters->int0Parameter;
2974 int GameScript::ExtraProficiencyGT(Scriptable* Sender, Trigger* parameters)
2976 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2977 if (!tar) {
2978 return 0;
2980 if (tar->Type != ST_ACTOR) {
2981 return 0;
2983 Actor* actor = ( Actor* ) tar;
2984 return (signed) actor->GetStat(IE_FREESLOTS) > parameters->int0Parameter;
2987 int GameScript::ExtraProficiencyLT(Scriptable* Sender, Trigger* parameters)
2989 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
2990 if (!tar) {
2991 return 0;
2993 if (tar->Type != ST_ACTOR) {
2994 return 0;
2996 Actor* actor = ( Actor* ) tar;
2997 return (signed) actor->GetStat(IE_FREESLOTS) < parameters->int0Parameter;
3000 int GameScript::Internal(Scriptable* Sender, Trigger* parameters)
3002 unsigned int idx = parameters->int0Parameter;
3003 if (idx>15) {
3004 return 0;
3006 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3007 if (!tar) {
3008 return 0;
3010 if (tar->Type != ST_ACTOR) {
3011 return 0;
3013 Actor* actor = ( Actor* ) tar;
3014 return (signed) actor->GetStat(IE_INTERNAL_0+idx) == parameters->int1Parameter;
3017 int GameScript::InternalGT(Scriptable* Sender, Trigger* parameters)
3019 unsigned int idx = parameters->int0Parameter;
3020 if (idx>15) {
3021 return 0;
3023 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3024 if (!tar) {
3025 return 0;
3027 if (tar->Type != ST_ACTOR) {
3028 return 0;
3030 Actor* actor = ( Actor* ) tar;
3031 return (signed) actor->GetStat(IE_INTERNAL_0+idx) > parameters->int1Parameter;
3034 int GameScript::InternalLT(Scriptable* Sender, Trigger* parameters)
3036 unsigned int idx = parameters->int0Parameter;
3037 if (idx>15) {
3038 return 0;
3040 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3041 if (!tar) {
3042 return 0;
3044 if (tar->Type != ST_ACTOR) {
3045 return 0;
3047 Actor* actor = ( Actor* ) tar;
3048 return (signed) actor->GetStat(IE_INTERNAL_0+idx) < parameters->int1Parameter;
3051 //we check if target is currently in dialog or not
3052 int GameScript::NullDialog(Scriptable* Sender, Trigger* parameters)
3054 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3055 if (!tar) {
3056 return 0;
3058 if (tar->Type != ST_ACTOR) {
3059 return 0;
3061 Actor *actor = (Actor *) tar;
3062 GameControl *gc = core->GetGameControl();
3063 if ( (actor->globalID != gc->targetID) && (actor->globalID != gc->speakerID) ) {
3064 return 1;
3066 return 0;
3069 //this one checks scriptname (deathvar), i hope it is right
3070 //IsScriptName depends on this too
3071 //Name is another (similar function)
3072 int GameScript::CalledByName(Scriptable* Sender, Trigger* parameters)
3074 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3075 if (!tar) {
3076 return 0;
3078 if (tar->Type != ST_ACTOR) {
3079 return 0;
3081 Actor *actor = (Actor *) tar;
3082 if (stricmp(actor->GetScriptName(), parameters->string0Parameter) ) {
3083 return 0;
3085 return 1;
3088 //This is checking on the character's name as it was typed in
3089 int GameScript::CharName(Scriptable* Sender, Trigger* parameters)
3091 Scriptable* scr = GetActorFromObject( Sender, parameters->objectParameter );
3092 if (!scr || scr->Type!=ST_ACTOR) {
3093 return 0;
3095 Actor* actor = (Actor *) scr;
3096 if (!strnicmp(actor->ShortName, parameters->string0Parameter, 32) ) {
3097 return 1;
3099 return 0;
3102 int GameScript::AnimationID(Scriptable* Sender, Trigger* parameters)
3104 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3105 if (!tar) {
3106 return 0;
3108 if (tar->Type != ST_ACTOR) {
3109 return 0;
3111 Actor *actor = (Actor *) tar;
3112 if ((ieWord) actor->GetStat(IE_ANIMATION_ID) == (ieWord) parameters->int0Parameter) {
3113 return 1;
3115 return 0;
3118 int GameScript::AnimState(Scriptable* Sender, Trigger* parameters)
3120 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3121 if (!tar) {
3122 return 0;
3124 if (tar->Type != ST_ACTOR) {
3125 return 0;
3127 Actor *actor = (Actor *) tar;
3128 return actor->GetStance() == parameters->int0Parameter;
3131 //this trigger uses hours
3132 int GameScript::Time(Scriptable* /*Sender*/, Trigger* parameters)
3134 return (core->GetGame()->GameTime/AI_UPDATE_TIME)%7200/300 == (ieDword) parameters->int0Parameter;
3137 //this trigger uses hours
3138 int GameScript::TimeGT(Scriptable* /*Sender*/, Trigger* parameters)
3140 return (core->GetGame()->GameTime/AI_UPDATE_TIME)%7200/300 > (ieDword) parameters->int0Parameter;
3143 //this trigger uses hours
3144 int GameScript::TimeLT(Scriptable* /*Sender*/, Trigger* parameters)
3146 return (core->GetGame()->GameTime/AI_UPDATE_TIME)%7200/300 < (ieDword) parameters->int0Parameter;
3149 int GameScript::HotKey(Scriptable* Sender, Trigger* parameters)
3151 if (Sender->Type != ST_ACTOR) {
3152 return 0;
3154 Actor *scr = (Actor *) Sender;
3155 // FIXME: this is never going to work on 64 bit archs ...
3156 int ret = (unsigned long) scr->HotKey == (unsigned long) parameters->int0Parameter;
3157 //probably we need to implement a trigger mechanism, clear
3158 //the hotkey only when the triggerblock was evaluated as true
3159 if (ret) {
3160 Sender->AddTrigger (&scr->HotKey);
3162 return ret;
3165 int GameScript::CombatCounter(Scriptable* /*Sender*/, Trigger* parameters)
3167 return core->GetGame()->CombatCounter == (ieDword) parameters->int0Parameter;
3170 int GameScript::CombatCounterGT(Scriptable* /*Sender*/, Trigger* parameters)
3172 return core->GetGame()->CombatCounter > (ieDword) parameters->int0Parameter;
3175 int GameScript::CombatCounterLT(Scriptable* /*Sender*/, Trigger* parameters)
3177 return core->GetGame()->CombatCounter < (ieDword) parameters->int0Parameter;
3180 int GameScript::TrapTriggered(Scriptable* Sender, Trigger* parameters)
3182 if (Sender->Type != ST_TRIGGER) {
3183 return 0;
3185 /* matchactor would do this, hmm
3186 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3187 if (!tar || tar->Type != ST_ACTOR) {
3188 return 0;
3191 if (MatchActor(Sender, Sender->LastTrigger, parameters->objectParameter)) {
3192 Sender->AddTrigger (&Sender->LastTrigger);
3193 return 1;
3195 return 0;
3198 int GameScript::InteractingWith(Scriptable* Sender, Trigger* parameters)
3200 if (Sender->Type!=ST_ACTOR) {
3201 return 0;
3203 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3204 if (!tar || tar->Type != ST_ACTOR) {
3205 return 0;
3207 GameControl *gc = core->GetGameControl();
3208 Actor *pc = (Actor *) Sender;
3209 if (pc->globalID != gc->targetID && pc->globalID != gc->speakerID) {
3210 return 0;
3212 pc = (Actor *) tar;
3213 if (pc->globalID != gc->targetID && pc->globalID != gc->speakerID) {
3214 return 0;
3216 return 1;
3219 int GameScript::LastPersonTalkedTo(Scriptable* Sender, Trigger* parameters)
3221 if (Sender->Type!=ST_ACTOR) {
3222 return 0;
3224 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3225 if (!tar || tar->Type != ST_ACTOR) {
3226 return 0;
3228 Actor *scr = (Actor *) Sender;
3229 if (MatchActor(Sender, scr->LastTalkedTo, parameters->objectParameter)) {
3230 return 1;
3232 return 0;
3235 int GameScript::IsRotation(Scriptable* Sender, Trigger* parameters)
3237 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3238 if (!tar || tar->Type != ST_ACTOR) {
3239 return 0;
3241 Actor* actor = ( Actor* ) tar;
3242 if ( actor->GetOrientation() == parameters->int0Parameter ) {
3243 return 1;
3245 return 0;
3248 //GemRB currently stores the saved location in a local variable, but it is
3249 //actually stored in the .gam structure (only for PCs)
3250 int GameScript::IsFacingSavedRotation(Scriptable* Sender, Trigger* parameters)
3252 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3253 if (!tar || tar->Type!=ST_ACTOR) {
3254 return 0;
3256 Actor* actor = ( Actor* ) tar;
3257 if (actor->GetOrientation() == actor->GetStat(IE_SAVEDFACE) ) {
3258 return 1;
3260 return 0;
3263 int GameScript::IsFacingObject(Scriptable* Sender, Trigger* parameters)
3265 if (Sender->Type != ST_ACTOR) {
3266 return 0;
3268 Scriptable* target = GetActorFromObject( Sender, parameters->objectParameter );
3269 if (!target) {
3270 return 0;
3272 Actor* actor = ( Actor* ) Sender;
3273 if (actor->GetOrientation()==GetOrient( target->Pos, actor->Pos ) ) {
3274 return 1;
3276 return 0;
3279 int GameScript::AttackedBy(Scriptable* Sender, Trigger* parameters)
3281 if (Sender->Type!=ST_ACTOR) {
3282 return 0;
3284 Actor *scr = (Actor *) Sender;
3285 Targets *tgts = GetAllObjects(Sender->GetCurrentArea(), Sender, parameters->objectParameter, GA_NO_DEAD);
3286 int ret = 0;
3287 int AStyle = parameters->int0Parameter;
3288 //iterate through targets to get the actor
3289 if (tgts) {
3290 targetlist::iterator m;
3291 const targettype *tt = tgts->GetFirstTarget(m, ST_ACTOR);
3292 while (tt) {
3293 Actor *actor = (Actor *) tt->actor;
3294 //if (actor->LastTarget == scr->GetID()) {
3295 if (scr->LastAttacker == actor->GetID()) {
3296 if (!AStyle || (AStyle==actor->GetAttackStyle()) ) {
3297 scr->AddTrigger(&scr->LastAttacker);
3298 ret = 1;
3299 break;
3302 tt = tgts->GetNextTarget(m, ST_ACTOR);
3305 delete tgts;
3306 return ret;
3309 int GameScript::TookDamage(Scriptable* Sender, Trigger* /*parameters*/)
3311 if (Sender->Type!=ST_ACTOR) {
3312 return 0;
3314 Actor* actor = ( Actor* ) Sender;
3315 //zero damage doesn't count?
3316 if (actor->LastHitter && actor->LastDamage) {
3317 Sender->AddTrigger(&actor->LastHitter);
3318 return 1;
3320 return 0;
3323 int GameScript::HitBy(Scriptable* Sender, Trigger* parameters)
3325 if (Sender->Type!=ST_ACTOR) {
3326 return 0;
3328 Actor* actor = ( Actor* ) Sender;
3329 if (parameters->int0Parameter) {
3330 if (!(parameters->int0Parameter&actor->LastDamageType) ) {
3331 return 0;
3334 if (MatchActor(Sender, actor->LastHitter, parameters->objectParameter)) {
3335 Sender->AddTrigger(&actor->LastHitter);
3336 return 1;
3338 return 0;
3341 int GameScript::Heard(Scriptable* Sender, Trigger* parameters)
3343 if (Sender->Type!=ST_ACTOR) {
3344 return 0;
3346 Actor* actor = ( Actor* ) Sender;
3347 if (parameters->int0Parameter) {
3348 if (parameters->int0Parameter!=actor->LastShout) {
3349 return 0;
3352 if (MatchActor(Sender, actor->LastHeard, parameters->objectParameter)) {
3353 Sender->AddTrigger(&actor->LastHeard);
3354 return 1;
3356 return 0;
3359 int GameScript::LastMarkedObject_Trigger(Scriptable* Sender, Trigger* parameters)
3361 if (Sender->Type!=ST_ACTOR) {
3362 return 0;
3364 Actor* actor = ( Actor* ) Sender;
3365 if (MatchActor(Sender, actor->LastMarked, parameters->objectParameter)) {
3366 //don't mark this object for clear
3367 //Sender->AddTrigger(&actor->LastSeen);
3368 return 1;
3370 return 0;
3373 int GameScript::HelpEX(Scriptable* Sender, Trigger* parameters)
3375 if (Sender->Type!=ST_ACTOR) {
3376 return 0;
3378 int stat;
3379 switch (parameters->int0Parameter) {
3380 case 1: stat = IE_EA; break;
3381 case 2: stat = IE_GENERAL; break;
3382 case 3: stat = IE_RACE; break;
3383 case 4: stat = IE_CLASS; break;
3384 case 5: stat = IE_SPECIFIC; break;
3385 case 6: stat = IE_SEX; break;
3386 case 7: stat = IE_ALIGNMENT; break;
3387 default: return 0;
3389 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3390 if (!tar || tar->Type!=ST_ACTOR) {
3391 //a non actor checking for help?
3392 return 0;
3394 Actor* actor = ( Actor* ) tar;
3395 Actor* help = Sender->GetCurrentArea()->GetActorByGlobalID(actor->LastHelp);
3396 if (!help) {
3397 //no help required
3398 return 0;
3400 if (actor->GetStat(stat)==help->GetStat(stat) ) {
3401 Sender->AddTrigger(&actor->LastHelp);
3402 return 1;
3404 return 0;
3407 int GameScript::Help_Trigger(Scriptable* Sender, Trigger* parameters)
3409 if (Sender->Type!=ST_ACTOR) {
3410 return 0;
3412 Actor* actor = ( Actor* ) Sender;
3413 if (MatchActor(Sender, actor->LastHelp, parameters->objectParameter)) {
3414 Sender->AddTrigger(&actor->LastHelp);
3415 return 1;
3417 return 0;
3420 int GameScript::ReceivedOrder(Scriptable* Sender, Trigger* parameters)
3422 if (MatchActor(Sender, Sender->LastOrderer, parameters->objectParameter) &&
3423 parameters->int0Parameter==Sender->LastOrder) {
3424 Sender->AddTrigger(&Sender->LastOrderer);
3425 return 1;
3427 return 0;
3430 int GameScript::FallenPaladin(Scriptable* Sender, Trigger* /*parameters*/)
3432 if (Sender->Type!=ST_ACTOR) {
3433 return 0;
3435 Actor* act = ( Actor* ) Sender;
3436 return (act->GetStat(IE_MC_FLAGS) & MC_FALLEN_PALADIN)!=0;
3439 int GameScript::FallenRanger(Scriptable* Sender, Trigger* /*parameters*/)
3441 if (Sender->Type!=ST_ACTOR) {
3442 return 0;
3444 Actor* act = ( Actor* ) Sender;
3445 return (act->GetStat(IE_MC_FLAGS) & MC_FALLEN_RANGER)!=0;
3448 int GameScript::NightmareModeOn(Scriptable* /*Sender*/, Trigger* /*parameters*/)
3450 ieDword diff;
3452 core->GetDictionary()->Lookup("Nightmare Mode", diff);
3453 if (diff) {
3454 return 1;
3456 return 0;
3459 int GameScript::Difficulty(Scriptable* /*Sender*/, Trigger* parameters)
3461 ieDword diff;
3463 core->GetDictionary()->Lookup("Difficulty Level", diff);
3464 int mode = parameters->int1Parameter;
3465 //hack for compatibility
3466 if (!mode) {
3467 mode = EQUALS;
3469 return DiffCore(diff, (ieDword) parameters->int0Parameter, mode);
3472 int GameScript::DifficultyGT(Scriptable* /*Sender*/, Trigger* parameters)
3474 ieDword diff;
3476 core->GetDictionary()->Lookup("Difficulty Level", diff);
3477 return diff>(ieDword) parameters->int0Parameter;
3480 int GameScript::DifficultyLT(Scriptable* /*Sender*/, Trigger* parameters)
3482 ieDword diff;
3484 core->GetDictionary()->Lookup("Difficulty Level", diff);
3485 return diff<(ieDword) parameters->int0Parameter;
3488 int GameScript::Vacant(Scriptable* Sender, Trigger* /*parameters*/)
3490 if (Sender->Type!=ST_AREA) {
3491 return 0;
3493 Map *map = (Map *) Sender;
3494 if ( map->CanFree() ) {
3495 return 1;
3497 return 0;
3500 //this trigger always checks the right hand weapon?
3501 int GameScript::InWeaponRange(Scriptable* Sender, Trigger* parameters)
3503 if (Sender->Type!=ST_ACTOR) {
3504 return 0;
3506 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3507 if (!tar) {
3508 return 0;
3510 Actor *actor = (Actor *) Sender;
3511 WeaponInfo wi;
3512 unsigned int wrange = 0;
3513 ITMExtHeader *header = actor->GetWeapon(wi, false);
3514 if (header) {
3515 wrange = wi.range;
3517 header = actor->GetWeapon(wi, true);
3518 if (header && (wi.range>wrange)) {
3519 wrange = wi.range;
3521 if ( PersonalDistance( Sender, tar ) <= wrange * 10 ) {
3522 return 1;
3524 return 0;
3527 //this implementation returns only true if there is a bow wielded
3528 //but there is no ammo for it
3529 //if the implementation should sign 'no ranged attack possible'
3530 //then change some return values
3531 //in bg2/iwd2 it doesn't accept an object (the object parameter is gemrb ext.)
3532 int GameScript::OutOfAmmo(Scriptable* Sender, Trigger* parameters)
3534 Scriptable* scr = Sender;
3535 if (parameters->objectParameter) {
3536 scr = GetActorFromObject( Sender, parameters->objectParameter );
3538 if ( !scr || scr->Type!=ST_ACTOR) {
3539 return 0;
3541 Actor *actor = (Actor *) scr;
3542 WeaponInfo wi;
3543 ITMExtHeader *header = actor->GetWeapon(wi, false);
3544 //no bow wielded?
3545 if (!header || header->AttackType!=ITEM_AT_BOW) {
3546 return 0;
3548 //we either have a projectile (negative) or an empty bow (positive)
3549 //so we should find a negative slot, positive slot means: OutOfAmmo
3550 if (actor->inventory.GetEquipped()<0) {
3551 return 0;
3553 //out of ammo
3554 return 1;
3557 //returns true if a weapon is equipped (with more than 0 range)
3558 //if a bow is equipped without projectile, it is useless!
3559 //please notice how similar is this to OutOfAmmo
3560 int GameScript::HaveUsableWeaponEquipped(Scriptable* Sender, Trigger* /*parameters*/)
3562 if (Sender->Type!=ST_ACTOR) {
3563 return 0;
3565 Actor *actor = (Actor *) Sender;
3566 WeaponInfo wi;
3567 ITMExtHeader *header = actor->GetWeapon(wi, false);
3569 //bows are not usable (because if they are loaded, the equipped
3570 //weapon is the projectile)
3571 if (!header || header->AttackType==ITEM_AT_BOW) {
3572 return 0;
3574 //only fist we have, it is not qualified as weapon?
3575 if (actor->inventory.GetEquippedSlot() == actor->inventory.GetFistSlot()) {
3576 return 0;
3578 return 1;
3581 int GameScript::HasWeaponEquipped(Scriptable* Sender, Trigger* parameters)
3583 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3584 if (!tar || tar->Type!=ST_ACTOR) {
3585 return 0;
3587 Actor* actor = ( Actor* ) tar;
3588 if (actor->inventory.GetEquippedSlot() == IW_NO_EQUIPPED) {
3589 return 0;
3591 return 1;
3594 int GameScript::PCInStore( Scriptable* /*Sender*/, Trigger* /*parameters*/)
3596 if (core->GetCurrentStore()) {
3597 return 1;
3599 return 0;
3602 //this checks if the launch point is onscreen, a more elaborate check
3603 //would see if any piece of the Scriptable is onscreen, what is the original
3604 //behaviour?
3605 int GameScript::OnScreen( Scriptable* Sender, Trigger* /*parameters*/)
3607 Region vp = core->GetVideoDriver()->GetViewport();
3608 if (vp.PointInside(Sender->Pos) ) {
3609 return 1;
3611 return 0;
3614 int GameScript::IsPlayerNumber( Scriptable* Sender, Trigger* parameters)
3616 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3617 if (!tar || tar->Type!=ST_ACTOR) {
3618 return 0;
3620 Actor* actor = ( Actor* ) tar;
3621 if (actor->InParty == parameters->int0Parameter) {
3622 return 1;
3624 return 0;
3627 int GameScript::PCCanSeePoint( Scriptable* /*Sender*/, Trigger* parameters)
3629 Map* map = core->GetGame()->GetCurrentArea();
3630 if (map->IsVisible(parameters->pointParameter, false) ) {
3631 return 1;
3633 return 0;
3636 //i'm clueless about this trigger
3637 int GameScript::StuffGlobalRandom( Scriptable* Sender, Trigger* parameters)
3639 unsigned int max=parameters->int0Parameter+1;
3640 ieDword Value;
3641 if (max) {
3642 Value = RandomNumValue%max;
3643 } else {
3644 Value = RandomNumValue;
3646 SetVariable( Sender, parameters->string0Parameter, Value );
3647 if (Value) {
3648 return 1;
3650 return 0;
3653 int GameScript::IsCreatureAreaFlag( Scriptable* Sender, Trigger* parameters)
3655 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3656 if (!tar || tar->Type!=ST_ACTOR) {
3657 return 0;
3659 Actor* actor = ( Actor* ) tar;
3660 if (actor->GetStat(IE_MC_FLAGS) & parameters->int0Parameter) {
3661 return 1;
3663 return 0;
3666 // 0 - ability, 1 - number, 2 - mode
3667 int GameScript::ChargeCount( Scriptable* Sender, Trigger* parameters)
3669 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3670 if (!tar || tar->Type!=ST_ACTOR) {
3671 return 0;
3673 Actor* actor = ( Actor* ) tar;
3674 int Slot = actor->inventory.FindItem(parameters->string0Parameter,0);
3675 if (Slot<0) {
3676 return 0;
3678 CREItem *item = actor->inventory.GetSlotItem (Slot);
3679 if (!item) {//bah
3680 return 0;
3682 if (parameters->int0Parameter>2) {
3683 return 0;
3685 int charge = item->Usages[parameters->int0Parameter];
3686 switch (parameters->int2Parameter) {
3687 case DM_EQUAL:
3688 if (charge == parameters->int1Parameter)
3689 return 1;
3690 break;
3691 case DM_LESS:
3692 if (charge < parameters->int1Parameter)
3693 return 1;
3694 break;
3695 case DM_GREATER:
3696 if (charge > parameters->int1Parameter)
3697 return 1;
3698 break;
3699 default:
3700 return 0;
3702 return 0;
3705 // no idea if it checks only alive partymembers
3706 int GameScript::CheckPartyLevel( Scriptable* /*Sender*/, Trigger* parameters)
3708 if (core->GetGame()->GetPartyLevel(false)<parameters->int0Parameter) {
3709 return 0;
3711 return 1;
3714 // no idea if it checks only alive partymembers
3715 int GameScript::CheckPartyAverageLevel( Scriptable* /*Sender*/, Trigger* parameters)
3717 int level = core->GetGame()->GetPartyLevel(false);
3718 switch (parameters->int1Parameter) {
3719 case DM_EQUAL:
3720 if (level ==parameters->int0Parameter) {
3721 return 1;
3723 break;
3724 case DM_LESS:
3725 if (level < parameters->int0Parameter) {
3726 return 1;
3728 break;
3729 case DM_GREATER:
3730 if (level > parameters->int0Parameter) {
3731 return 1;
3733 break;
3734 default:
3735 return 0;
3737 return 1;
3740 int GameScript::CheckDoorFlags( Scriptable* Sender, Trigger* parameters)
3742 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3743 if (!tar || tar->Type!=ST_DOOR) {
3744 return 0;
3746 Door* door = ( Door* ) tar;
3747 if (door->Flags&parameters->int0Parameter) {
3748 return 1;
3750 return 0;
3753 // works only on animations?
3754 // Be careful when converting to GetActorFromObject, it won't return animations (those are not scriptable)
3755 int GameScript::Frame( Scriptable* Sender, Trigger* parameters)
3757 //to avoid a crash
3758 if (!parameters->objectParameter) {
3759 return 0;
3761 AreaAnimation* anim = Sender->GetCurrentArea()->GetAnimation(parameters->objectParameter->objectName);
3762 if (!anim) {
3763 return 0;
3765 int frame = anim->frame;
3766 if ((frame>=parameters->int0Parameter) &&
3767 (frame<=parameters->int1Parameter) ) {
3768 return 1;
3770 return 0;
3773 //Modalstate in IWD2 allows specifying an object
3774 int GameScript::ModalState( Scriptable* Sender, Trigger* parameters)
3776 Scriptable *scr;
3778 if (parameters->objectParameter) {
3779 scr = GetActorFromObject( Sender, parameters->objectParameter );
3780 } else {
3781 scr = Sender;
3783 if (scr->Type!=ST_ACTOR) {
3784 return 0;
3786 Actor *actor = (Actor *) scr;
3788 if (actor->ModalState==(ieDword) parameters->int0Parameter) {
3789 return 1;
3791 return 0;
3794 /* a special redundant trigger for iwd2 - could do something extra */
3795 int GameScript::IsCreatureHiddenInShadows( Scriptable* Sender, Trigger* /*parameters*/)
3797 if (Sender->Type!=ST_ACTOR) {
3798 return 0;
3800 Actor *actor = (Actor *) Sender;
3802 if (actor->ModalState==MS_STEALTH) {
3803 return 1;
3805 return 0;
3808 int GameScript::IsWeather( Scriptable* /*Sender*/, Trigger* parameters)
3810 Game *game = core->GetGame();
3811 ieDword weather = game->WeatherBits & parameters->int0Parameter;
3812 if (weather == (ieDword) parameters->int1Parameter) {
3813 return 1;
3815 return 0;
3818 int GameScript::Delay( Scriptable* Sender, Trigger* parameters)
3820 ieDword delay = (ieDword) parameters->int0Parameter;
3821 if (delay<=1) {
3822 return 1;
3824 ieDword time1=Sender->lastDelay/1000/delay;
3825 ieDword time2=Sender->lastRunTime/1000/delay;
3827 if (time1!=time2) {
3828 return 1;
3830 return 0;
3833 int GameScript::TimeOfDay(Scriptable* /*Sender*/, Trigger* parameters)
3835 ieDword timeofday = (core->GetGame()->GameTime/AI_UPDATE_TIME)%7200/1800;
3837 if (timeofday==(ieDword) parameters->int0Parameter) {
3838 return 1;
3840 return 0;
3843 //this is a PST action, it's using delta, not diffmode
3844 int GameScript::RandomStatCheck(Scriptable* Sender, Trigger* parameters)
3846 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3847 if (!tar || tar->Type!=ST_ACTOR) {
3848 return 0;
3850 Actor* actor = ( Actor* ) tar;
3852 ieDword stat = actor->GetStat(parameters->int0Parameter);
3853 ieDword value = Bones(parameters->int2Parameter);
3854 switch(parameters->int1Parameter) {
3855 case DM_SET:
3856 if (stat==value)
3857 return 1;
3858 break;
3859 case DM_LOWER:
3860 if (stat<value)
3861 return 1;
3862 break;
3863 case DM_RAISE:
3864 if (stat>value)
3865 return 1;
3866 break;
3868 return 0;
3871 int GameScript::PartyRested(Scriptable* Sender, Trigger* /*parameters*/)
3873 if (Sender->GetInternalFlag()&IF_PARTYRESTED) {
3874 Sender->SetBitTrigger(BT_PARTYRESTED);
3875 return 1;
3877 return 0;
3880 int GameScript::IsWeaponRanged(Scriptable* Sender, Trigger* parameters)
3882 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3883 if (!tar || tar->Type!=ST_ACTOR) {
3884 return 0;
3886 Actor* actor = ( Actor* ) tar;
3887 if (actor->inventory.GetEquipped()<0) {
3888 return 1;
3890 return 0;
3893 //HoW applies sequence on area animations
3894 int GameScript::Sequence(Scriptable* Sender, Trigger* parameters)
3896 //to avoid a crash, check if object is NULL
3897 if (parameters->objectParameter) {
3898 AreaAnimation *anim = Sender->GetCurrentArea()->GetAnimation(parameters->objectParameter->objectName);
3899 if (anim) {
3900 //this is the cycle count for the area animation
3901 //very much like stance for avatar anims
3902 if (anim->sequence==parameters->int0Parameter) {
3903 return 1;
3905 return 0;
3909 Scriptable *tar = GetActorFromObject( Sender, parameters->objectParameter );
3910 if (!tar || tar->Type != ST_ACTOR) {
3911 return 0;
3913 Actor* actor = ( Actor* ) tar;
3914 if (actor->GetStance()==parameters->int0Parameter) {
3915 return 1;
3917 return 0;
3920 int GameScript::TimerExpired(Scriptable* Sender, Trigger* parameters)
3922 if (Sender->TimerExpired(parameters->int0Parameter) ) {
3923 return 1;
3925 return 0;
3928 int GameScript::TimerActive(Scriptable* Sender, Trigger* parameters)
3930 if (Sender->TimerActive(parameters->int0Parameter) ) {
3931 return 1;
3933 return 0;
3936 int GameScript::ActuallyInCombat(Scriptable* /*Sender*/, Trigger* /*parameters*/)
3938 Game *game=core->GetGame();
3939 if (game->AnyPCInCombat()) return 1;
3940 return 0;
3943 int GameScript::InMyGroup(Scriptable* Sender, Trigger* parameters)
3945 if (Sender->Type!=ST_ACTOR) {
3946 return 0;
3949 Scriptable* tar = GetActorFromObject( Sender, parameters->objectParameter );
3950 if (!tar || tar->Type!=ST_ACTOR) {
3951 return 0;
3953 /* IESDP SUCKS
3954 if (GetGroup( (Actor *) tar)==GetGroup( (Actor *) Sender) ) {
3955 return 1;
3958 if ( ((Actor *) tar)->GetStat(IE_SPECIFIC)==((Actor *) tar)->GetStat(IE_SPECIFIC) ) {
3959 return 1;
3961 return 0;
3964 int GameScript::AnyPCSeesEnemy(Scriptable* /*Sender*/, Trigger* /*parameters*/)
3966 Game *game = core->GetGame();
3967 unsigned int i = (unsigned int) game->GetLoadedMapCount();
3968 while(i--) {
3969 Map *map = game->GetMap(i);
3970 if (map->AnyPCSeesEnemy()) {
3971 return 1;
3974 return 0;
3977 int GameScript::Unusable(Scriptable* Sender, Trigger* parameters)
3979 if (Sender->Type!=ST_ACTOR) {
3980 return 0;
3982 Actor *actor = (Actor *) Sender;
3984 Item *item = gamedata->GetItem(parameters->string0Parameter);
3985 int ret;
3986 if (actor->Unusable(item)) {
3987 ret = 0;
3988 } else {
3989 ret = 1;
3991 gamedata->FreeItem(item, parameters->string0Parameter, true);
3992 return ret;
3995 int GameScript::HasBounceEffects(Scriptable* Sender, Trigger* parameters)
3997 Scriptable *tar = GetActorFromObject( Sender, parameters->objectParameter );
3998 if (!tar || tar->Type != ST_ACTOR) {
3999 return 0;
4001 Actor* actor = ( Actor* ) tar;
4002 if (actor->GetStat(IE_BOUNCE)) return 1;
4003 return 0;
4006 int GameScript::HasImmunityEffects(Scriptable* Sender, Trigger* parameters)
4008 Scriptable *tar = GetActorFromObject( Sender, parameters->objectParameter );
4009 if (!tar || tar->Type != ST_ACTOR) {
4010 return 0;
4012 Actor* actor = ( Actor* ) tar;
4013 if (actor->GetStat(IE_IMMUNITY)) return 1;
4014 return 0;
4017 // this is a GemRB specific trigger, to transfer some system variables
4018 // to a global (game variable), it will always return true, and the
4019 // variable could be checked in a subsequent trigger (like triggersetglobal)
4021 #define SYSV_SCREENFLAGS 0
4022 #define SYSV_CONTROLSTATUS 1
4023 #define SYSV_REPUTATION 2
4024 #define SYSV_PARTYGOLD 3
4026 int GameScript::SystemVariable_Trigger(Scriptable* Sender, Trigger* parameters)
4028 ieDword value;
4030 switch (parameters->int0Parameter) {
4031 case SYSV_SCREENFLAGS:
4032 value = core->GetGameControl()->GetScreenFlags();
4033 break;
4034 case SYSV_CONTROLSTATUS:
4035 value = core->GetGame()->ControlStatus;
4036 break;
4037 case SYSV_REPUTATION:
4038 value = core->GetGame()->Reputation;
4039 break;
4040 case SYSV_PARTYGOLD:
4041 value = core->GetGame()->PartyGold;
4042 break;
4043 default:
4044 return 0;
4047 SetVariable(Sender, parameters->string0Parameter, value);
4048 return 1;
4051 int GameScript::SpellCast(Scriptable* Sender, Trigger* parameters)
4053 if(parameters->int0Parameter) {
4054 unsigned int param = 2000+parameters->int0Parameter%1000;
4055 if (param!=Sender->LastSpellSeen) {
4056 return 0;
4059 if(MatchActor(Sender, Sender->LastCasterSeen, parameters->objectParameter)) {
4060 Sender->AddTrigger(&Sender->LastCasterSeen);
4061 return 1;
4063 return 0;
4066 int GameScript::SpellCastPriest(Scriptable* Sender, Trigger* parameters)
4068 if(parameters->int0Parameter) {
4069 unsigned int param = 1000+parameters->int0Parameter%1000;
4070 if (param!=Sender->LastSpellSeen) {
4071 return 0;
4074 if(MatchActor(Sender, Sender->LastCasterSeen, parameters->objectParameter)) {
4075 Sender->AddTrigger(&Sender->LastCasterSeen);
4076 return 1;
4078 return 0;
4081 int GameScript::SpellCastInnate(Scriptable* Sender, Trigger* parameters)
4083 if(parameters->int0Parameter) {
4084 unsigned int param = 3000+parameters->int0Parameter%1000;
4085 if (param!=Sender->LastSpellSeen) {
4086 return 0;
4089 if(MatchActor(Sender, Sender->LastCasterSeen, parameters->objectParameter)) {
4090 Sender->AddTrigger(&Sender->LastCasterSeen);
4091 return 1;
4093 return 0;
4096 int GameScript::SpellCastOnMe(Scriptable* Sender, Trigger* parameters)
4098 if(parameters->int0Parameter) {
4099 if ((ieDword) parameters->int0Parameter!=Sender->LastSpellOnMe) {
4100 return 0;
4103 if(MatchActor(Sender, Sender->LastCasterOnMe, parameters->objectParameter)) {
4104 Sender->AddTrigger(&Sender->LastCasterOnMe);
4105 return 1;
4107 return 0;
4110 int GameScript::CalendarDay(Scriptable* /*Sender*/, Trigger* parameters)
4112 int day = core->GetCalendar()->GetCalendarDay(core->GetGame()->GameTime/AI_UPDATE_TIME/7200);
4113 if(day == parameters->int0Parameter) {
4114 return 1;
4116 return 0;
4119 int GameScript::CalendarDayGT(Scriptable* /*Sender*/, Trigger* parameters)
4121 int day = core->GetCalendar()->GetCalendarDay(core->GetGame()->GameTime/AI_UPDATE_TIME/7200);
4122 if(day > parameters->int0Parameter) {
4123 return 1;
4125 return 0;
4128 int GameScript::CalendarDayLT(Scriptable* /*Sender*/, Trigger* parameters)
4130 int day = core->GetCalendar()->GetCalendarDay(core->GetGame()->GameTime/AI_UPDATE_TIME/7200);
4131 if(day < parameters->int0Parameter) {
4132 return 1;
4134 return 0;