1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003-2007 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.
22 #include "GameScript.h"
26 #include "ScriptEngine.h"
30 #include "SaveGameIterator.h"
33 #include "GameControl.h"
35 #include "DataFileMgr.h"
36 #include "AmbientMgr.h"
39 //------------------------------------------------------------
41 //-------------------------------------------------------------
43 void GameScript::SetExtendedNight(Scriptable
* Sender
, Action
* parameters
)
45 Map
*map
=Sender
->GetCurrentArea();
46 //sets the 'can rest other' bit
47 if (parameters
->int0Parameter
) {
48 map
->AreaType
|=AT_EXTENDED_NIGHT
;
50 map
->AreaType
&=~AT_EXTENDED_NIGHT
;
54 void GameScript::SetAreaRestFlag(Scriptable
* Sender
, Action
* parameters
)
56 Map
*map
=Sender
->GetCurrentArea();
57 //sets the 'can rest other' bit
58 if (parameters
->int0Parameter
) {
59 map
->AreaType
|=AT_CAN_REST
;
61 map
->AreaType
&=~AT_CAN_REST
;
65 void GameScript::AddAreaFlag(Scriptable
* Sender
, Action
* parameters
)
67 Map
*map
=Sender
->GetCurrentArea();
68 map
->AreaFlags
|=parameters
->int0Parameter
;
71 void GameScript::RemoveAreaFlag(Scriptable
* Sender
, Action
* parameters
)
73 Map
*map
=Sender
->GetCurrentArea();
74 map
->AreaFlags
&=~parameters
->int0Parameter
;
77 void GameScript::SetAreaFlags(Scriptable
* Sender
, Action
* parameters
)
79 Map
*map
=Sender
->GetCurrentArea();
80 ieDword value
= map
->AreaFlags
;
81 HandleBitMod( value
, parameters
->int0Parameter
, parameters
->int1Parameter
);
85 void GameScript::AddAreaType(Scriptable
* Sender
, Action
* parameters
)
87 Map
*map
=Sender
->GetCurrentArea();
88 map
->AreaType
|=parameters
->int0Parameter
;
91 void GameScript::RemoveAreaType(Scriptable
* Sender
, Action
* parameters
)
93 Map
*map
=Sender
->GetCurrentArea();
94 map
->AreaType
&=~parameters
->int0Parameter
;
97 void GameScript::NoActionAtAll(Scriptable
* /*Sender*/, Action
* /*parameters*/)
102 // this action stops modal actions, so...
103 void GameScript::NoAction(Scriptable
* Sender
, Action
* /*parameters*/)
105 if (Sender
->Type
!=ST_ACTOR
) {
108 Actor
*actor
= (Actor
*) Sender
;
109 actor
->SetModal( MS_NONE
);
112 void GameScript::SG(Scriptable
* Sender
, Action
* parameters
)
114 SetVariable( Sender
, parameters
->string0Parameter
, "GLOBAL", parameters
->int0Parameter
);
117 void GameScript::SetGlobal(Scriptable
* Sender
, Action
* parameters
)
119 SetVariable( Sender
, parameters
->string0Parameter
, parameters
->int0Parameter
);
122 void GameScript::SetGlobalRandom(Scriptable
* Sender
, Action
* parameters
)
124 int max
=parameters
->int1Parameter
-parameters
->int0Parameter
+1;
126 SetVariable( Sender
, parameters
->string0Parameter
, RandomNumValue
%max
+parameters
->int0Parameter
);
128 SetVariable( Sender
, parameters
->string0Parameter
, 0);
132 void GameScript::StartTimer(Scriptable
* Sender
, Action
* parameters
)
134 Sender
->StartTimer(parameters
->int0Parameter
, parameters
->int1Parameter
);
137 void GameScript::StartRandomTimer(Scriptable
* Sender
, Action
* parameters
)
139 ieDword value
= core
->Roll(1, parameters
->int2Parameter
-parameters
->int1Parameter
, parameters
->int2Parameter
-1);
140 Sender
->StartTimer(parameters
->int0Parameter
, value
);
143 void GameScript::SetGlobalTimer(Scriptable
* Sender
, Action
* parameters
)
147 mytime
=core
->GetGame()->GameTime
; //gametime (should increase it)
148 SetVariable( Sender
, parameters
->string0Parameter
,
149 parameters
->int0Parameter
*AI_UPDATE_TIME
+ mytime
);
152 void GameScript::SetGlobalTimerRandom(Scriptable
* Sender
, Action
* parameters
)
156 int random
=parameters
->int1Parameter
-parameters
->int0Parameter
+1;
158 random
= RandomNumValue
% random
+ parameters
->int0Parameter
;
162 mytime
=core
->GetGame()->GameTime
; //gametime (should increase it)
163 SetVariable( Sender
, parameters
->string0Parameter
, random
*AI_UPDATE_TIME
+ mytime
);
166 void GameScript::SetGlobalTimerOnce(Scriptable
* Sender
, Action
* parameters
)
168 ieDword mytime
= CheckVariable( Sender
, parameters
->string0Parameter
);
172 mytime
=core
->GetGame()->GameTime
; //gametime (should increase it)
173 SetVariable( Sender
, parameters
->string0Parameter
,
174 parameters
->int0Parameter
*AI_UPDATE_TIME
+ mytime
);
177 void GameScript::RealSetGlobalTimer(Scriptable
* Sender
, Action
* parameters
)
179 ieDword mytime
=core
->GetGame()->RealTime
;
181 SetVariable( Sender
, parameters
->string0Parameter
,
182 parameters
->int0Parameter
+ mytime
);
185 void GameScript::ChangeAllegiance(Scriptable
* Sender
, Action
* parameters
)
187 Scriptable
*scr
= Sender
;
188 if (parameters
->objects
[1]) {
189 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
191 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
194 Actor
* actor
= ( Actor
* ) scr
;
195 actor
->SetBase( IE_EA
, parameters
->int0Parameter
);
198 void GameScript::ChangeGeneral(Scriptable
* Sender
, Action
* parameters
)
200 Scriptable
*scr
= Sender
;
201 if (parameters
->objects
[1]) {
202 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
204 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
207 Actor
* actor
= ( Actor
* ) scr
;
208 actor
->SetBase( IE_GENERAL
, parameters
->int0Parameter
);
211 void GameScript::ChangeRace(Scriptable
* Sender
, Action
* parameters
)
213 Scriptable
*scr
= Sender
;
214 if (parameters
->objects
[1]) {
215 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
217 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
220 Actor
* actor
= ( Actor
* ) scr
;
221 actor
->SetBase( IE_RACE
, parameters
->int0Parameter
);
224 void GameScript::ChangeClass(Scriptable
* Sender
, Action
* parameters
)
226 Scriptable
*scr
= Sender
;
227 if (parameters
->objects
[1]) {
228 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
230 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
233 Actor
* actor
= ( Actor
* ) scr
;
234 actor
->SetBase( IE_CLASS
, parameters
->int0Parameter
);
237 void GameScript::SetNamelessClass(Scriptable
* /*Sender*/, Action
* parameters
)
239 //same as Protagonist
240 Actor
* actor
= core
->GetGame()->GetPC(0, false);
241 actor
->SetBase( IE_CLASS
, parameters
->int0Parameter
);
244 void GameScript::SetNamelessDisguise(Scriptable
* Sender
, Action
* parameters
)
246 SetVariable(Sender
, "APPEARANCE", "GLOBAL", parameters
->int0Parameter
);
247 core
->SetEventFlag(EF_UPDATEANIM
);
250 void GameScript::ChangeSpecifics(Scriptable
* Sender
, Action
* parameters
)
252 Scriptable
*scr
= Sender
;
253 if (parameters
->objects
[1]) {
254 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
256 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
259 Actor
* actor
= ( Actor
* ) scr
;
260 actor
->SetBase( IE_SPECIFIC
, parameters
->int0Parameter
);
263 void GameScript::PermanentStatChange(Scriptable
* Sender
, Action
* parameters
)
265 Scriptable
*scr
= Sender
;
266 if (parameters
->objects
[1]) {
267 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
269 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
272 Actor
* actor
= ( Actor
* ) scr
;
274 switch (parameters
->int1Parameter
) {
276 value
= actor
->GetBase(parameters
->int0Parameter
);
277 value
-= parameters
->int2Parameter
;
280 value
= actor
->GetBase(parameters
->int0Parameter
);
281 value
+= parameters
->int2Parameter
;
284 default: //no idea what happens
285 value
= parameters
->int2Parameter
;
288 actor
->SetBase( parameters
->int0Parameter
, value
);
291 void GameScript::ChangeStat(Scriptable
* Sender
, Action
* parameters
)
293 Scriptable
*scr
= Sender
;
294 if (parameters
->objects
[1]) {
295 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
297 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
300 Actor
* actor
= ( Actor
* ) scr
;
301 ieDword value
= parameters
->int1Parameter
;
302 if (parameters
->int2Parameter
==1) {
303 value
+=actor
->GetBase(parameters
->int0Parameter
);
305 actor
->SetBase( parameters
->int0Parameter
, value
);
308 void GameScript::ChangeStatGlobal(Scriptable
* Sender
, Action
* parameters
)
310 Scriptable
*scr
= Sender
;
311 if (parameters
->objects
[1]) {
312 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
314 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
317 ieDword value
= (ieDword
) CheckVariable( Sender
, parameters
->string0Parameter
, parameters
->string1Parameter
);
318 Actor
* actor
= ( Actor
* ) scr
;
319 if (parameters
->int1Parameter
==1) {
320 value
+=actor
->GetBase(parameters
->int0Parameter
);
322 actor
->SetBase( parameters
->int0Parameter
, value
);
325 void GameScript::ChangeGender(Scriptable
* Sender
, Action
* parameters
)
327 Scriptable
*scr
= Sender
;
328 if (parameters
->objects
[1]) {
329 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
331 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
334 Actor
* actor
= ( Actor
* ) scr
;
335 actor
->SetBase( IE_SEX
, parameters
->int0Parameter
);
338 void GameScript::ChangeAlignment(Scriptable
* Sender
, Action
* parameters
)
340 Scriptable
*scr
= Sender
;
341 if (parameters
->objects
[1]) {
342 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
344 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
347 Actor
* actor
= ( Actor
* ) scr
;
348 actor
->SetBase( IE_ALIGNMENT
, parameters
->int0Parameter
);
351 void GameScript::SetFaction(Scriptable
* Sender
, Action
* parameters
)
353 Scriptable
*scr
= Sender
;
354 if (parameters
->objects
[1]) {
355 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
357 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
360 Actor
* actor
= ( Actor
* ) scr
;
361 actor
->SetBase( IE_FACTION
, parameters
->int0Parameter
);
364 void GameScript::SetHP(Scriptable
* Sender
, Action
* parameters
)
366 Scriptable
*scr
= Sender
;
367 if (parameters
->objects
[1]) {
368 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
370 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
373 Actor
* actor
= ( Actor
* ) scr
;
374 actor
->SetBase( IE_HITPOINTS
, parameters
->int0Parameter
);
377 void GameScript::SetHPPercent(Scriptable
* Sender
, Action
* parameters
)
379 Scriptable
*scr
= Sender
;
380 if (parameters
->objects
[1]) {
381 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
383 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
386 Actor
* actor
= ( Actor
* ) scr
;
387 actor
->NewBase( IE_HITPOINTS
, parameters
->int0Parameter
, MOD_PERCENT
);
390 void GameScript::AddHP(Scriptable
* Sender
, Action
* parameters
)
392 Scriptable
*scr
= Sender
;
393 if (parameters
->objects
[1]) {
394 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
396 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
399 Actor
* actor
= ( Actor
* ) scr
;
400 actor
->NewBase(IE_HITPOINTS
, parameters
->int0Parameter
, MOD_ADDITIVE
);
403 //this works on an object (pst)
404 //but can also work on actor itself (gemrb)
405 void GameScript::SetTeam(Scriptable
* Sender
, Action
* parameters
)
407 Scriptable
*scr
= Sender
;
408 if (parameters
->objects
[1]) {
409 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
411 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
414 Actor
* actor
= ( Actor
* ) scr
;
415 actor
->SetBase( IE_TEAM
, parameters
->int0Parameter
);
418 //this works on an object (gemrb)
419 //or on Myself if object isn't given (iwd2)
420 void GameScript::SetTeamBit(Scriptable
* Sender
, Action
* parameters
)
422 Scriptable
*scr
= Sender
;
423 if (parameters
->objects
[1]) {
424 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
426 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
429 Actor
* actor
= ( Actor
* ) scr
;
430 if (parameters
->int1Parameter
) {
431 actor
->SetBase( IE_TEAM
, actor
->GetStat(IE_TEAM
) | parameters
->int0Parameter
);
433 actor
->SetBase( IE_TEAM
, actor
->GetStat(IE_TEAM
) & ~parameters
->int0Parameter
);
437 void GameScript::TriggerActivation(Scriptable
* Sender
, Action
* parameters
)
441 if (!parameters
->objects
[1]) {
444 ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
446 if (!ip
|| (ip
->Type
!=ST_TRIGGER
&& ip
->Type
!=ST_TRAVEL
&& ip
->Type
!=ST_PROXIMITY
)) {
447 printf("Script error: No Trigger Named \"%s\"\n", parameters
->objects
[1]->objectName
);
450 InfoPoint
*trigger
= (InfoPoint
*) ip
;
451 if ( parameters
->int0Parameter
!= 0 ) {
452 trigger
->Flags
&= ~TRAP_DEACTIVATED
;
454 trigger
->Flags
|= TRAP_DEACTIVATED
;
458 void GameScript::FadeToColor(Scriptable
* Sender
, Action
* parameters
)
460 core
->timer
->SetFadeToColor( parameters
->pointParameter
.x
);
461 // Sender->SetWait( parameters->pointParameter.x );
462 Sender
->ReleaseCurrentAction(); // todo, blocking?
465 void GameScript::FadeFromColor(Scriptable
* Sender
, Action
* parameters
)
467 core
->timer
->SetFadeFromColor( parameters
->pointParameter
.x
);
468 // Sender->SetWait( parameters->pointParameter.x );
469 Sender
->ReleaseCurrentAction(); // todo, blocking?
472 void GameScript::FadeToAndFromColor(Scriptable
* Sender
, Action
* parameters
)
474 core
->timer
->SetFadeToColor( parameters
->pointParameter
.x
);
475 core
->timer
->SetFadeFromColor( parameters
->pointParameter
.x
);
476 // Sender->SetWait( parameters->pointParameter.x<<1 ); //multiply by 2
477 Sender
->ReleaseCurrentAction(); // todo, blocking?
480 void GameScript::JumpToPoint(Scriptable
* Sender
, Action
* parameters
)
482 if (Sender
->Type
!= ST_ACTOR
) {
485 Actor
* ab
= ( Actor
* ) Sender
;
486 ab
->SetPosition( parameters
->pointParameter
, true );
489 void GameScript::JumpToPointInstant(Scriptable
* Sender
, Action
* parameters
)
491 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
492 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
495 Actor
* ab
= ( Actor
* ) tar
;
496 ab
->SetPosition( parameters
->pointParameter
, true );
499 /** instant jump to location saved in stats */
500 /** default subject is the current actor */
501 void GameScript::JumpToSavedLocation(Scriptable
* Sender
, Action
* parameters
)
503 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
507 if (tar
->Type
!= ST_ACTOR
) {
510 Actor
*actor
= (Actor
*) tar
;
511 Point
p((short) actor
->GetStat(IE_SAVEDXPOS
), (short) actor
->GetStat(IE_SAVEDYPOS
) );
512 actor
->SetPosition(p
, true );
513 actor
->SetOrientation( actor
->GetStat(IE_SAVEDFACE
), false );
516 void GameScript::JumpToObject(Scriptable
* Sender
, Action
* parameters
)
518 if (Sender
->Type
!= ST_ACTOR
) {
521 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
526 const Map
*map
= tar
->GetCurrentArea();
529 if (parameters
->string0Parameter
[0]) {
530 CreateVisualEffectCore(Sender
, Sender
->Pos
, parameters
->string0Parameter
, 0);
532 MoveBetweenAreasCore( (Actor
*) Sender
, map
->GetScriptName(), tar
->Pos
, -1, true);
536 void GameScript::TeleportParty(Scriptable
* /*Sender*/, Action
* parameters
)
538 Game
*game
= core
->GetGame();
539 int i
= game
->GetPartySize(false);
541 Actor
*tar
= game
->GetPC(i
, false);
542 MoveBetweenAreasCore( tar
, parameters
->string1Parameter
,
543 parameters
->pointParameter
, -1, true);
547 //this is unfinished, maybe the original moves actors too?
549 void GameScript::MoveToExpansion(Scriptable
* Sender
, Action
* /*parameters*/)
551 Game
*game
= core
->GetGame();
553 game
->SetExpansion(1);
554 core
->GetDictionary()->SetAt( "PlayMode", 2 );
555 //TODO: set the new world map
557 int i
= game
->GetPartySize(false);
559 Actor
*actor
= game
->GetPC(i
, false);
560 game
->InitActorPos(actor
);
563 SaveGameIterator
*sg
= core
->GetSaveGameIterator();
567 core
->SetEventFlag(EF_MASTERSCRIPT
);
568 Sender
->ReleaseCurrentAction();
571 //add some animation effects too?
572 void GameScript::ExitPocketPlane(Scriptable
* /*Sender*/, Action
* /*parameters*/)
574 Game
*game
= core
->GetGame();
575 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
576 Actor
* act
= game
->GetPC( i
, false );
578 if (game
->GetPlaneLocationCount() <= (unsigned int)i
) {
579 // what are we meant to do here?
580 printf("argh, couldn't restore party member %d!", i
+ 1);
583 GAMLocationEntry
*gle
= game
->GetPlaneLocationEntry(i
);
584 MoveBetweenAreasCore(act
, gle
->AreaResRef
, gle
->Pos
, -1, true);
588 // presumably this is correct
589 game
->ClearPlaneLocations();
592 //moves pcs and npcs from an area to another area
593 void GameScript::MoveGlobalsTo(Scriptable
* /*Sender*/, Action
* parameters
)
595 Game
*game
= core
->GetGame();
596 int i
= game
->GetPartySize(false);
598 Actor
*tar
= game
->GetPC(i
, false);
599 //if the actor isn't in the area, we don't care
600 if (strnicmp(tar
->Area
, parameters
->string0Parameter
,8) ) {
603 MoveBetweenAreasCore( tar
, parameters
->string1Parameter
,
604 parameters
->pointParameter
, -1, true);
606 i
= game
->GetNPCCount();
608 Actor
*tar
= game
->GetNPC(i
);
609 //if the actor isn't in the area, we don't care
610 if (strnicmp(tar
->Area
, parameters
->string0Parameter
,8) ) {
613 MoveBetweenAreasCore( tar
, parameters
->string1Parameter
,
614 parameters
->pointParameter
, -1, true);
618 void GameScript::MoveGlobal(Scriptable
* Sender
, Action
* parameters
)
620 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
621 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
625 MoveBetweenAreasCore( (Actor
*) tar
, parameters
->string0Parameter
,
626 parameters
->pointParameter
, -1, true);
629 //we also allow moving to door, container
630 void GameScript::MoveGlobalObject(Scriptable
* Sender
, Action
* parameters
)
632 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
633 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
636 Scriptable
* to
= GetActorFromObject( Sender
, parameters
->objects
[2] );
640 const Map
*map
= to
->GetCurrentArea();
643 MoveBetweenAreasCore( (Actor
*) tar
, map
->GetScriptName(),
648 void GameScript::MoveGlobalObjectOffScreen(Scriptable
* Sender
, Action
* parameters
)
650 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
651 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
654 Scriptable
* to
= GetActorFromObject( Sender
, parameters
->objects
[2] );
658 MoveBetweenAreasCore( (Actor
*) tar
, parameters
->string0Parameter
,
662 //don't use offset from Sender
663 void GameScript::CreateCreature(Scriptable
* Sender
, Action
* parameters
)
665 CreateCreatureCore( Sender
, parameters
, CC_CHECK_IMPASSABLE
|CC_CHECK_OVERLAP
|CC_SCRIPTNAME
);
668 //another highly redundant action
669 void GameScript::CreateCreatureDoor(Scriptable
* Sender
, Action
* parameters
)
671 //we hack this to death
672 strcpy(parameters
->string1Parameter
, "SPDIMNDR");
673 CreateCreatureCore( Sender
, parameters
, CC_CHECK_IMPASSABLE
|CC_CHECK_OVERLAP
| CC_PLAY_ANIM
);
676 //another highly redundant action
677 void GameScript::CreateCreatureObjectDoor(Scriptable
* Sender
, Action
* parameters
)
679 //we hack this to death
680 strcpy(parameters
->string1Parameter
, "SPDIMNDR");
681 CreateCreatureCore( Sender
, parameters
, CC_OFFSET
| CC_CHECK_IMPASSABLE
|CC_CHECK_OVERLAP
| CC_PLAY_ANIM
);
684 //don't use offset from Sender
685 void GameScript::CreateCreatureImpassable(Scriptable
* Sender
, Action
* parameters
)
687 CreateCreatureCore( Sender
, parameters
, CC_CHECK_OVERLAP
);
690 void GameScript::CreateCreatureImpassableAllowOverlap(Scriptable
* Sender
, Action
* parameters
)
692 CreateCreatureCore( Sender
, parameters
, 0 );
695 //use offset from Sender
696 void GameScript::CreateCreatureAtFeet(Scriptable
* Sender
, Action
* parameters
)
698 CreateCreatureCore( Sender
, parameters
, CC_OFFSET
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
);
701 void GameScript::CreateCreatureOffScreen(Scriptable
* Sender
, Action
* parameters
)
703 CreateCreatureCore( Sender
, parameters
, CC_OFFSCREEN
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
);
706 //creates copy at actor, plays animation
707 void GameScript::CreateCreatureObjectCopy(Scriptable
* Sender
, Action
* parameters
)
709 CreateCreatureCore( Sender
, parameters
, CC_OBJECT
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
| CC_COPY
| CC_PLAY_ANIM
);
712 //creates copy at absolute point
713 void GameScript::CreateCreatureCopyPoint(Scriptable
* Sender
, Action
* parameters
)
715 CreateCreatureCore( Sender
, parameters
, CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
| CC_COPY
| CC_PLAY_ANIM
);
718 //this is the same, object + offset
719 //using this for simple createcreatureobject, (0 offsets)
720 //createcreatureobjecteffect may have animation
721 void GameScript::CreateCreatureObjectOffset(Scriptable
* Sender
, Action
* parameters
)
723 CreateCreatureCore( Sender
, parameters
, CC_OBJECT
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
| CC_PLAY_ANIM
);
726 void GameScript::CreateCreatureObjectOffScreen(Scriptable
* Sender
, Action
* parameters
)
728 CreateCreatureCore( Sender
, parameters
, CC_OFFSCREEN
| CC_OBJECT
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
);
731 //I think this simply removes the cursor and hides the gui without disabling scripts
732 //See Interface::SetCutSceneMode
733 void GameScript::SetCursorState(Scriptable
* /*Sender*/, Action
* parameters
)
735 int active
= parameters
->int0Parameter
;
737 Game
*game
= core
->GetGame();
739 game
->ControlStatus
|= CS_HIDEGUI
;
741 game
->ControlStatus
&= ~CS_HIDEGUI
;
743 core
->SetEventFlag(EF_CONTROL
);
744 core
->GetVideoDriver()->SetMouseEnabled(!active
);
747 void GameScript::StartCutSceneMode(Scriptable
* /*Sender*/, Action
* /*parameters*/)
749 core
->SetCutSceneMode( true );
752 void GameScript::EndCutSceneMode(Scriptable
* /*Sender*/, Action
* /*parameters*/)
754 core
->SetCutSceneMode( false );
757 void GameScript::StartCutScene(Scriptable
* Sender
, Action
* parameters
)
759 GameScript
* gs
= new GameScript( parameters
->string0Parameter
, ST_GLOBAL
);
761 gs
->EvaluateAllBlocks();
763 Sender
->ClearCutsceneID();
766 void GameScript::CutSceneID(Scriptable
* Sender
, Action
* parameters
)
768 Sender
->SetCutsceneID( GetActorFromObject( Sender
, parameters
->objects
[1] ) );
769 if (InDebug
&ID_CUTSCENE
) {
770 if (!Sender
->GetCutsceneID()) {
771 printMessage("GameScript","Failed to set CutSceneID!\n",YELLOW
);
772 parameters
->objects
[1]->Dump();
777 void GameScript::Enemy(Scriptable
* Sender
, Action
* /*parameters*/)
779 if (Sender
->Type
!= ST_ACTOR
) {
782 Actor
* actor
= ( Actor
* ) Sender
;
783 actor
->SetBase( IE_EA
, EA_ENEMY
);
786 void GameScript::Ally(Scriptable
* Sender
, Action
* /*parameters*/)
788 if (Sender
->Type
!= ST_ACTOR
) {
791 Actor
* actor
= ( Actor
* ) Sender
;
792 actor
->SetBase( IE_EA
, EA_ALLY
);
795 /** GemRB extension: you can replace baldur.bcs */
796 void GameScript::ChangeAIScript(Scriptable
* Sender
, Action
* parameters
)
798 if (parameters
->int0Parameter
>7) {
801 if (Sender
->Type
!=ST_ACTOR
&& parameters
->int0Parameter
) {
804 Sender
->SetScript( parameters
->string0Parameter
, parameters
->int0Parameter
, false );
807 void GameScript::ForceAIScript(Scriptable
* Sender
, Action
* parameters
)
809 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
810 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
813 Actor
* actor
= ( Actor
* ) tar
;
814 //changeaiscript clears the queue, i believe
815 // actor->ClearActions();
816 actor
->SetScript( parameters
->string0Parameter
, parameters
->int0Parameter
, false );
819 void GameScript::SetPlayerSound(Scriptable
* Sender
, Action
* parameters
)
821 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
822 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
825 Actor
* actor
= ( Actor
* ) tar
;
826 actor
->StrRefs
[parameters
->int0Parameter
]=parameters
->int1Parameter
;
829 //this one works only on real actors, they got constants
830 void GameScript::VerbalConstantHead(Scriptable
* Sender
, Action
* parameters
)
832 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
833 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
836 DisplayStringCore( tar
, parameters
->int0Parameter
, DS_HEAD
|DS_CONSOLE
|DS_CONST
);
839 void GameScript::VerbalConstant(Scriptable
* Sender
, Action
* parameters
)
841 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
842 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
845 DisplayStringCore( tar
, parameters
->int0Parameter
, DS_CONSOLE
|DS_CONST
);
849 void GameScript::SaveLocation(Scriptable
* Sender
, Action
* parameters
)
851 ieDword value
= parameters
->pointParameter
.asDword();
852 if (!parameters
->string0Parameter
[0]) {
853 strcpy(parameters
->string0Parameter
,"LOCALSsavedlocation");
855 printf("SaveLocation: %s\n",parameters
->string0Parameter
);
856 SetVariable(Sender
, parameters
->string0Parameter
, value
);
859 //PST:has parameters, IWD2: no params
860 void GameScript::SetSavedLocation(Scriptable
* Sender
, Action
* parameters
)
862 if (Sender
->Type
!=ST_ACTOR
) {
865 Actor
*actor
= (Actor
*) Sender
;
867 if (parameters
->pointParameter
.isnull()) {
868 actor
->SetBase(IE_SAVEDXPOS
, actor
->Pos
.x
);
869 actor
->SetBase(IE_SAVEDYPOS
, actor
->Pos
.y
);
870 actor
->SetBase(IE_SAVEDFACE
, actor
->GetOrientation());
874 actor
->SetBase(IE_SAVEDXPOS
, parameters
->pointParameter
.x
);
875 actor
->SetBase(IE_SAVEDYPOS
, parameters
->pointParameter
.y
);
876 actor
->SetBase(IE_SAVEDFACE
, parameters
->int0Parameter
);
878 //IWD2, sets the homepoint int0,int1,int2
879 void GameScript::SetSavedLocationPoint(Scriptable
* Sender
, Action
* parameters
)
881 if (Sender
->Type
!=ST_ACTOR
) {
884 Actor
*actor
= (Actor
*) Sender
;
885 actor
->SetBase(IE_SAVEDXPOS
, parameters
->int0Parameter
);
886 actor
->SetBase(IE_SAVEDYPOS
, parameters
->int1Parameter
);
887 actor
->SetBase(IE_SAVEDFACE
, parameters
->int2Parameter
);
889 //IWD2, sets the homepoint P
890 void GameScript::SetStartPos(Scriptable
* Sender
, Action
* parameters
)
892 if (Sender
->Type
!=ST_ACTOR
) {
895 Actor
*actor
= (Actor
*) Sender
;
896 actor
->SetBase(IE_SAVEDXPOS
, parameters
->pointParameter
.x
);
897 actor
->SetBase(IE_SAVEDYPOS
, parameters
->pointParameter
.y
);
898 actor
->SetBase(IE_SAVEDFACE
, parameters
->int0Parameter
);
901 void GameScript::SaveObjectLocation(Scriptable
* Sender
, Action
* parameters
)
903 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
907 ieDword value
= tar
->Pos
.asDword();
908 if (!parameters
->string0Parameter
[0]) {
909 strcpy(parameters
->string0Parameter
,"LOCALSsavedlocation");
911 printf("SaveLocation: %s\n",parameters
->string0Parameter
);
912 SetVariable(Sender
, parameters
->string0Parameter
, value
);
915 /** you may omit the string0Parameter, in this case this will be a */
916 /** CreateCreatureAtSavedLocation */
917 void GameScript::CreateCreatureAtLocation(Scriptable
* Sender
, Action
* parameters
)
919 if (!parameters
->string0Parameter
[0]) {
920 strcpy(parameters
->string0Parameter
,"LOCALSsavedlocation");
922 ieDword value
= CheckVariable(Sender
, parameters
->string0Parameter
);
923 parameters
->pointParameter
.y
= (ieWord
) (value
& 0xffff);
924 parameters
->pointParameter
.x
= (ieWord
) (value
>> 16);
925 CreateCreatureCore(Sender
, parameters
, CC_CHECK_IMPASSABLE
|CC_STRING1
);
928 void GameScript::WaitRandom(Scriptable
* Sender
, Action
* parameters
)
930 if (!Sender
->CurrentActionState
) {
931 int width
= parameters
->int1Parameter
-parameters
->int0Parameter
;
933 width
= parameters
->int0Parameter
;
935 width
= rand() % width
+ parameters
->int0Parameter
;
937 Sender
->CurrentActionState
= width
* AI_UPDATE_TIME
;
939 Sender
->CurrentActionState
--;
942 if (!Sender
->CurrentActionState
) {
943 Sender
->ReleaseCurrentAction();
946 assert(Sender
->CurrentActionState
>= 0);
949 void GameScript::Wait(Scriptable
* Sender
, Action
* parameters
)
951 if (!Sender
->CurrentActionState
) {
952 Sender
->CurrentActionState
= parameters
->int0Parameter
* AI_UPDATE_TIME
;
954 Sender
->CurrentActionState
--;
957 if (!Sender
->CurrentActionState
) {
958 Sender
->ReleaseCurrentAction();
961 assert(Sender
->CurrentActionState
>= 0);
964 void GameScript::SmallWait(Scriptable
* Sender
, Action
* parameters
)
966 if (!Sender
->CurrentActionState
) {
967 Sender
->CurrentActionState
= parameters
->int0Parameter
;
969 Sender
->CurrentActionState
--;
972 if (!Sender
->CurrentActionState
) {
973 Sender
->ReleaseCurrentAction();
976 assert(Sender
->CurrentActionState
>= 0);
979 void GameScript::SmallWaitRandom(Scriptable
* Sender
, Action
* parameters
)
981 if (!Sender
->CurrentActionState
) {
982 int random
= parameters
->int1Parameter
- parameters
->int0Parameter
;
986 Sender
->CurrentActionState
= rand() % random
+ parameters
->int0Parameter
;
988 Sender
->CurrentActionState
--;
991 if (!Sender
->CurrentActionState
) {
992 Sender
->ReleaseCurrentAction();
995 assert(Sender
->CurrentActionState
>= 0);
998 void GameScript::MoveViewPoint(Scriptable
* Sender
, Action
* parameters
)
1000 core
->timer
->SetMoveViewPort( parameters
->pointParameter
.x
, parameters
->pointParameter
.y
, parameters
->int0Parameter
<<1, true );
1001 Sender
->SetWait(1); // todo, blocking?
1002 Sender
->ReleaseCurrentAction(); // todo, blocking?
1005 void GameScript::MoveViewObject(Scriptable
* Sender
, Action
* parameters
)
1007 Scriptable
* scr
= GetActorFromObject( Sender
, parameters
->objects
[1]);
1011 core
->timer
->SetMoveViewPort( scr
->Pos
.x
, scr
->Pos
.y
, parameters
->int0Parameter
<<1, true );
1012 Sender
->SetWait(1); // todo, blocking?
1013 Sender
->ReleaseCurrentAction(); // todo, blocking?
1016 void GameScript::AddWayPoint(Scriptable
* Sender
, Action
* parameters
)
1018 if (Sender
->Type
!= ST_ACTOR
) {
1021 Actor
* actor
= ( Actor
* ) Sender
;
1022 actor
->AddWayPoint( parameters
->pointParameter
);
1023 // this is marked as AF_BLOCKING (and indeed AddWayPoint causes moves),
1024 // but this probably needs more thought
1025 Sender
->ReleaseCurrentAction();
1028 void GameScript::MoveToPointNoRecticle(Scriptable
* Sender
, Action
* parameters
)
1030 if (Sender
->Type
!= ST_ACTOR
) {
1031 Sender
->ReleaseCurrentAction();
1034 Actor
*actor
= ( Actor
* ) Sender
;
1035 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1036 actor
->WalkTo( parameters
->pointParameter
, IF_NORECTICLE
, 0 );
1038 if (!actor
->InMove()) {
1039 // we should probably instead keep retrying until we reach dest
1040 Sender
->ReleaseCurrentAction();
1044 void GameScript::MoveToPointNoInterrupt(Scriptable
* Sender
, Action
* parameters
)
1046 if (Sender
->Type
!= ST_ACTOR
) {
1047 Sender
->ReleaseCurrentAction();
1050 Actor
* actor
= ( Actor
* ) Sender
;
1051 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1052 actor
->WalkTo( parameters
->pointParameter
, IF_NOINT
, 0 );
1054 // should we always force IF_NOINT here?
1055 if (!actor
->InMove()) {
1056 // we should probably instead keep retrying until we reach dest
1058 Sender
->ReleaseCurrentAction();
1062 void GameScript::RunToPointNoRecticle(Scriptable
* Sender
, Action
* parameters
)
1064 if (Sender
->Type
!= ST_ACTOR
) {
1065 Sender
->ReleaseCurrentAction();
1068 Actor
* actor
= ( Actor
* ) Sender
;
1069 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1070 actor
->WalkTo( parameters
->pointParameter
, IF_NORECTICLE
|IF_RUNNING
, 0 );
1072 if (!actor
->InMove()) {
1073 // we should probably instead keep retrying until we reach dest
1074 Sender
->ReleaseCurrentAction();
1078 void GameScript::RunToPoint(Scriptable
* Sender
, Action
* parameters
)
1080 if (Sender
->Type
!= ST_ACTOR
) {
1081 Sender
->ReleaseCurrentAction();
1084 Actor
* actor
= ( Actor
* ) Sender
;
1085 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1086 actor
->WalkTo( parameters
->pointParameter
, IF_RUNNING
, 0 );
1088 if (!actor
->InMove()) {
1089 // we should probably instead keep retrying until we reach dest
1090 Sender
->ReleaseCurrentAction();
1094 //movetopoint until timer is down or target reached
1095 void GameScript::TimedMoveToPoint(Scriptable
* Sender
, Action
* parameters
)
1097 if (Sender
->Type
!= ST_ACTOR
) {
1098 Sender
->ReleaseCurrentAction();
1101 if (parameters
->int0Parameter
<=0) {
1102 Sender
->ReleaseCurrentAction();
1105 Actor
*actor
= (Actor
*) Sender
;
1107 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1108 actor
->WalkTo( parameters
->pointParameter
, parameters
->int1Parameter
,0 );
1111 //hopefully this hack will prevent lockups
1112 if (!actor
->InMove()) {
1113 // we should probably instead keep retrying until we reach dest
1114 Sender
->ReleaseCurrentAction();
1118 //repeat movement...
1119 if (parameters
->int0Parameter
>0) {
1120 Action
*newaction
= ParamCopyNoOverride(parameters
);
1121 newaction
->int0Parameter
--;
1122 actor
->AddActionInFront(newaction
);
1126 Sender
->ReleaseCurrentAction();
1129 void GameScript::MoveToPoint(Scriptable
* Sender
, Action
* parameters
)
1131 if (Sender
->Type
!= ST_ACTOR
) {
1132 Sender
->ReleaseCurrentAction();
1135 Actor
* actor
= ( Actor
* ) Sender
;
1136 //WalkTo could release the current action, so we need this
1137 ieDword tmp
= (ieDword
) parameters
->int0Parameter
;
1138 //InMove can clear destination, so we need to save it
1139 Point dest
= actor
->Destination
;
1141 // try the actual move, if we are not already moving there
1142 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1143 actor
->WalkTo( parameters
->pointParameter
, 0, tmp
);
1144 dest
= actor
->Destination
;
1147 // give up if we can't move there (no path was found)
1148 if (!actor
->InMove()) {
1149 // we should probably instead keep retrying until we reach dest
1150 Sender
->ReleaseCurrentAction();
1154 if (!actor
->InMove()) {
1155 //can't reach target, movement failed
1156 //we have to use tmp-1 because the distance required might be 0,
1157 //so in GoNearAndRetry we add 1 to distance
1158 if (Distance(dest
,actor
)>tmp
-1) {
1159 //to prevent deadlocks, we free the action
1160 //which caused MoveToPoint in the first place
1161 Sender
->PopNextAction();
1167 //bg2, jumps to saved location in variable
1168 void GameScript::MoveToSavedLocation(Scriptable
* Sender
, Action
* parameters
)
1170 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1174 if (tar
->Type
!= ST_ACTOR
) {
1175 Sender
->ReleaseCurrentAction();
1180 Actor
* actor
= ( Actor
* ) tar
;
1181 ieDword value
= (ieDword
) CheckVariable( Sender
, parameters
->string0Parameter
);
1183 actor
->SetPosition(p
, true );
1184 Sender
->ReleaseCurrentAction();
1186 /** iwd2 returntosavedlocation (with stats) */
1187 /** pst returntosavedplace */
1188 /** use Sender as default subject */
1189 void GameScript::ReturnToSavedLocation(Scriptable
* Sender
, Action
* parameters
)
1191 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
1195 if (tar
->Type
!= ST_ACTOR
) {
1196 Sender
->ReleaseCurrentAction();
1200 Actor
* actor
= ( Actor
* ) tar
;
1201 Point
p((short) actor
->GetBase(IE_SAVEDXPOS
),(short) actor
->GetBase(IE_SAVEDYPOS
) );
1203 Sender
->ReleaseCurrentAction();
1206 if (!actor
->InMove() || actor
->Destination
!= p
) {
1207 actor
->WalkTo( p
, 0, 0 );
1209 if (!actor
->InMove()) {
1210 // we should probably instead keep retrying until we reach dest
1211 Sender
->ReleaseCurrentAction();
1216 void GameScript::RunToSavedLocation(Scriptable
* Sender
, Action
* parameters
)
1218 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
1222 if (tar
->Type
!= ST_ACTOR
) {
1223 Sender
->ReleaseCurrentAction();
1227 Actor
* actor
= ( Actor
* ) tar
;
1228 Point
p((short) actor
->GetBase(IE_SAVEDXPOS
),(short) actor
->GetBase(IE_SAVEDYPOS
) );
1230 Sender
->ReleaseCurrentAction();
1233 if (!actor
->InMove() || actor
->Destination
!= p
) {
1234 actor
->WalkTo( p
, IF_RUNNING
, 0 );
1236 if (!actor
->InMove()) {
1237 // we should probably instead keep retrying until we reach dest
1238 Sender
->ReleaseCurrentAction();
1243 void GameScript::ReturnToSavedLocationDelete(Scriptable
* Sender
, Action
* parameters
)
1245 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
1249 if (tar
->Type
!= ST_ACTOR
) {
1250 Sender
->ReleaseCurrentAction();
1254 Actor
* actor
= ( Actor
* ) tar
;
1255 Point
p((short) actor
->GetBase(IE_SAVEDXPOS
),(short) actor
->GetBase(IE_SAVEDYPOS
) );
1256 actor
->SetBase(IE_SAVEDXPOS
,0);
1257 actor
->SetBase(IE_SAVEDYPOS
,0);
1259 Sender
->ReleaseCurrentAction();
1262 if (!actor
->InMove() || actor
->Destination
!= p
) {
1263 actor
->WalkTo( p
, 0, 0 );
1266 if (!actor
->InMove()) {
1267 // we should probably instead keep retrying until we reach dest
1268 Sender
->ReleaseCurrentAction();
1272 void GameScript::MoveToObjectNoInterrupt(Scriptable
* Sender
, Action
* parameters
)
1274 MoveToObjectCore(Sender
, parameters
, IF_NOINT
, false);
1277 void GameScript::RunToObject(Scriptable
* Sender
, Action
* parameters
)
1279 MoveToObjectCore(Sender
, parameters
, IF_RUNNING
, false);
1282 void GameScript::MoveToObject(Scriptable
* Sender
, Action
* parameters
)
1284 MoveToObjectCore(Sender
, parameters
, 0, false);
1287 void GameScript::MoveToObjectUntilSee(Scriptable
* Sender
, Action
* parameters
)
1289 MoveToObjectCore(Sender
, parameters
, 0, true);
1292 void GameScript::MoveToObjectFollow(Scriptable
* Sender
, Action
* parameters
)
1294 if (Sender
->Type
!= ST_ACTOR
) {
1295 Sender
->ReleaseCurrentAction();
1298 Scriptable
* target
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
1300 Sender
->ReleaseCurrentAction();
1303 Actor
* actor
= ( Actor
* ) Sender
;
1304 //follow leader from a distance of 5
1305 //could also follow the leader with a point offset
1306 if (target
->Type
==ST_ACTOR
) {
1307 actor
->SetLeader( (Actor
*) target
, 5);
1309 MoveNearerTo(Sender
, target
, MAX_OPERATING_DISTANCE
);
1312 void GameScript::StorePartyLocation(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1314 Game
*game
= core
->GetGame();
1315 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
1316 Actor
* act
= game
->GetPC( i
, false );
1317 GAMLocationEntry
*gle
= game
->GetSavedLocationEntry(i
);
1319 gle
->Pos
= act
->Pos
;
1320 memcpy(gle
->AreaResRef
, act
->Area
, 9);
1325 void GameScript::RestorePartyLocation(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1327 Game
*game
= core
->GetGame();
1328 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
1329 Actor
* act
= game
->GetPC( i
, false );
1331 if (game
->GetSavedLocationCount() <= (unsigned int)i
) {
1332 // what are we meant to do here?
1333 printf("argh, couldn't restore party member %d!", i
+ 1);
1336 GAMLocationEntry
*gle
= game
->GetSavedLocationEntry(i
);
1337 MoveBetweenAreasCore(act
, gle
->AreaResRef
, gle
->Pos
, -1, true);
1341 // presumably this is correct
1342 game
->ClearSavedLocations();
1345 void GameScript::MoveToCenterOfScreen(Scriptable
* Sender
, Action
* /*parameters*/)
1347 if (Sender
->Type
!= ST_ACTOR
) {
1348 Sender
->ReleaseCurrentAction();
1351 Region vp
= core
->GetVideoDriver()->GetViewport();
1352 Actor
* actor
= ( Actor
* ) Sender
;
1353 Point
p((short) (vp
.x
+vp
.w
/2), (short) (vp
.y
+vp
.h
/2) );
1354 if (!actor
->InMove() || actor
->Destination
!= p
) {
1355 actor
->WalkTo( p
, IF_NOINT
, 0 );
1357 if (!actor
->InMove()) {
1358 // we should probably instead keep retrying until we reach dest
1359 Sender
->ReleaseCurrentAction();
1363 void GameScript::MoveToOffset(Scriptable
* Sender
, Action
* parameters
)
1365 if (Sender
->Type
!= ST_ACTOR
) {
1366 Sender
->ReleaseCurrentAction();
1369 Actor
* actor
= ( Actor
* ) Sender
;
1370 Point
p(Sender
->Pos
.x
+parameters
->pointParameter
.x
, Sender
->Pos
.y
+parameters
->pointParameter
.y
);
1371 if (!actor
->InMove() || actor
->Destination
!= p
) {
1372 actor
->WalkTo( p
, 0, 0 );
1374 if (!actor
->InMove()) {
1375 // we should probably instead keep retrying until we reach dest
1376 Sender
->ReleaseCurrentAction();
1380 void GameScript::RunAwayFrom(Scriptable
* Sender
, Action
* parameters
)
1382 if (Sender
->Type
!= ST_ACTOR
) {
1383 Sender
->ReleaseCurrentAction();
1386 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
1387 Sender
->ReleaseCurrentAction();
1390 Actor
* actor
= ( Actor
* ) Sender
;
1391 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
1393 Sender
->ReleaseCurrentAction();
1396 //TODO: actor could use travel areas
1397 // we should be using int0Parameter for the timing here, not distance
1398 if (!actor
->InMove()) {
1399 // we should make sure our existing walk is a 'run away', or fix moving/path code
1400 actor
->RunAwayFrom( tar
->Pos
, parameters
->int0Parameter
, false);
1403 //repeat movement...
1404 if (parameters
->int0Parameter
>0) {
1405 Action
*newaction
= ParamCopyNoOverride(parameters
);
1406 newaction
->int0Parameter
--;
1407 actor
->AddActionInFront(newaction
);
1411 Sender
->ReleaseCurrentAction();
1414 void GameScript::RunAwayFromNoLeaveArea(Scriptable
* Sender
, Action
* parameters
)
1416 if (Sender
->Type
!= ST_ACTOR
) {
1417 Sender
->ReleaseCurrentAction();
1420 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
1421 Sender
->ReleaseCurrentAction();
1424 Actor
* actor
= ( Actor
* ) Sender
;
1425 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
1427 Sender
->ReleaseCurrentAction();
1430 // we should be using int0Parameter for the timing here, not distance
1431 if (!actor
->InMove()) {
1432 // we should make sure our existing walk is a 'run away', or fix moving/path code
1433 actor
->RunAwayFrom( tar
->Pos
, parameters
->int0Parameter
, false);
1436 //repeat movement...
1437 if (parameters
->int0Parameter
>0) {
1438 Action
*newaction
= ParamCopyNoOverride(parameters
);
1439 newaction
->int0Parameter
--;
1440 actor
->AddActionInFront(newaction
);
1444 Sender
->ReleaseCurrentAction();
1447 void GameScript::RunAwayFromNoInterrupt(Scriptable
* Sender
, Action
* parameters
)
1449 if (Sender
->Type
!= ST_ACTOR
) {
1450 Sender
->ReleaseCurrentAction();
1453 //i believe being dead still interrupts this action
1454 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
1455 Sender
->ReleaseCurrentAction();
1458 Actor
* actor
= ( Actor
* ) Sender
;
1459 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
1461 Sender
->ReleaseCurrentAction();
1464 //actor->InternalFlags|=IF_NOINT;
1465 actor
->NoInterrupt();
1466 // we should be using int0Parameter for the timing here, not distance
1467 if (!actor
->InMove()) {
1468 // we should make sure our existing walk is a 'run away', or fix moving/path code
1469 actor
->RunAwayFrom( tar
->Pos
, parameters
->int0Parameter
, false);
1472 //repeat movement...
1473 if (parameters
->int0Parameter
>0) {
1474 Action
*newaction
= ParamCopyNoOverride(parameters
);
1475 newaction
->int0Parameter
--;
1476 actor
->AddActionInFront(newaction
);
1482 Sender
->ReleaseCurrentAction();
1485 void GameScript::RunAwayFromPoint(Scriptable
* Sender
, Action
* parameters
)
1487 if (Sender
->Type
!= ST_ACTOR
) {
1488 Sender
->ReleaseCurrentAction();
1491 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
1492 Sender
->ReleaseCurrentAction();
1495 Actor
* actor
= ( Actor
* ) Sender
;
1496 // we should be using int0Parameter for the timing here, not distance?
1497 if (!actor
->InMove()) {
1498 // we should make sure our existing walk is a 'run away', or fix moving/path code
1499 actor
->RunAwayFrom( parameters
->pointParameter
, parameters
->int0Parameter
, false);
1502 //repeat movement...
1503 if (parameters
->int0Parameter
>0) {
1504 Action
*newaction
= ParamCopyNoOverride(parameters
);
1505 newaction
->int0Parameter
--;
1506 actor
->AddActionInFront(newaction
);
1510 Sender
->ReleaseCurrentAction();
1513 void GameScript::DisplayStringNoName(Scriptable
* Sender
, Action
* parameters
)
1515 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1]);
1519 if (Sender
->Type
==ST_ACTOR
) {
1520 DisplayStringCore( target
, parameters
->int0Parameter
, DS_CONSOLE
|DS_NONAME
);
1522 DisplayStringCore( target
, parameters
->int0Parameter
, DS_AREA
|DS_NONAME
);
1526 void GameScript::DisplayStringNoNameHead(Scriptable
* Sender
, Action
* parameters
)
1528 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1533 DisplayStringCore( target
, parameters
->int0Parameter
, DS_HEAD
|DS_CONSOLE
|DS_NONAME
);
1536 //display message over current script owner
1537 void GameScript::DisplayMessage(Scriptable
* Sender
, Action
* parameters
)
1539 DisplayStringCore(Sender
, parameters
->int0Parameter
, DS_CONSOLE
);
1542 //float message over target
1543 void GameScript::DisplayStringHead(Scriptable
* Sender
, Action
* parameters
)
1545 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1548 printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
1551 DisplayStringCore(target
, parameters
->int0Parameter
, DS_CONSOLE
|DS_HEAD
|DS_SPEECH
);
1554 void GameScript::KillFloatMessage(Scriptable
* Sender
, Action
* parameters
)
1556 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1560 target
->DisplayHeadText(NULL
);
1563 void GameScript::DisplayStringHeadOwner(Scriptable
* /*Sender*/, Action
* parameters
)
1565 Game
*game
=core
->GetGame();
1567 int i
= game
->GetPartySize(true);
1569 Actor
*actor
= game
->GetPC(i
, true);
1570 if (actor
->inventory
.HasItem(parameters
->string0Parameter
,parameters
->int0Parameter
) ) {
1571 DisplayStringCore(actor
, parameters
->int0Parameter
, DS_CONSOLE
|DS_HEAD
);
1576 void GameScript::FloatMessageFixed(Scriptable
* Sender
, Action
* parameters
)
1578 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1581 printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
1584 DisplayStringCore(target
, parameters
->int0Parameter
, DS_CONSOLE
|DS_HEAD
);
1587 void GameScript::FloatMessageFixedRnd(Scriptable
* Sender
, Action
* parameters
)
1589 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1592 printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
1595 SrcVector
*rndstr
=LoadSrc(parameters
->string0Parameter
);
1597 printMessage("GameScript","Cannot display resource!",LIGHT_RED
);
1600 DisplayStringCore(target
, rndstr
->at(rand()%rndstr
->size()), DS_CONSOLE
|DS_HEAD
);
1601 FreeSrc(rndstr
, parameters
->string0Parameter
);
1604 void GameScript::FloatMessageRnd(Scriptable
* Sender
, Action
* parameters
)
1606 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1609 printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
1612 SrcVector
*rndstr
=LoadSrc(parameters
->string0Parameter
);
1614 printMessage("GameScript","Cannot display resource!",LIGHT_RED
);
1617 DisplayStringCore(target
, rndstr
->at(rand()%rndstr
->size()), DS_CONSOLE
|DS_HEAD
);
1618 FreeSrc(rndstr
, parameters
->string0Parameter
);
1621 //apparently this should not display over head (for actors)
1622 void GameScript::DisplayString(Scriptable
* Sender
, Action
* parameters
)
1624 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1]);
1628 if (Sender
->Type
==ST_ACTOR
) {
1629 DisplayStringCore( target
, parameters
->int0Parameter
, DS_CONSOLE
);
1631 DisplayStringCore( target
, parameters
->int0Parameter
, DS_AREA
);
1635 //DisplayStringHead, but wait for previous talk to succeed
1636 void GameScript::DisplayStringWait(Scriptable
* Sender
, Action
* parameters
)
1638 if (core
->GetAudioDrv()->IsSpeaking()) {
1639 //Sender->AddActionInFront( Sender->CurrentAction );
1642 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1]);
1646 DisplayStringCore( target
, parameters
->int0Parameter
, DS_CONSOLE
|DS_WAIT
|DS_SPEECH
|DS_HEAD
);
1647 Sender
->ReleaseCurrentAction();
1650 void GameScript::ForceFacing(Scriptable
* Sender
, Action
* parameters
)
1652 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1653 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
1654 Sender
->ReleaseCurrentAction();
1657 Actor
*actor
= (Actor
*) tar
;
1658 actor
->SetOrientation(parameters
->int0Parameter
, false);
1661 /* A -1 means random facing? */
1662 void GameScript::Face(Scriptable
* Sender
, Action
* parameters
)
1664 if (Sender
->Type
!= ST_ACTOR
) {
1665 Sender
->ReleaseCurrentAction();
1668 Actor
* actor
= ( Actor
* ) Sender
;
1669 if (parameters
->int0Parameter
==-1) {
1670 actor
->SetOrientation(core
->Roll(1,MAX_ORIENT
,-1), false);
1672 actor
->SetOrientation(parameters
->int0Parameter
, false);
1674 actor
->SetWait( 1 );
1675 Sender
->ReleaseCurrentAction(); // todo, blocking?
1678 void GameScript::FaceObject(Scriptable
* Sender
, Action
* parameters
)
1680 if (Sender
->Type
!= ST_ACTOR
) {
1681 Sender
->ReleaseCurrentAction();
1684 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1686 Sender
->ReleaseCurrentAction();
1689 Actor
* actor
= ( Actor
* ) Sender
;
1690 actor
->SetOrientation( GetOrient( target
->Pos
, actor
->Pos
), false);
1691 actor
->SetWait( 1 );
1692 Sender
->ReleaseCurrentAction(); // todo, blocking?
1695 void GameScript::FaceSavedLocation(Scriptable
* Sender
, Action
* parameters
)
1697 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1698 if (!target
|| target
->Type
!=ST_ACTOR
) {
1699 Sender
->ReleaseCurrentAction();
1702 Actor
* actor
= ( Actor
* ) target
;
1704 if (!parameters
->string0Parameter
[0]) {
1705 strcpy(parameters
->string0Parameter
,"LOCALSsavedlocation");
1707 value
= (ieDword
) CheckVariable( target
, parameters
->string0Parameter
);
1711 actor
->SetOrientation ( GetOrient( p
, actor
->Pos
), false);
1712 actor
->SetWait( 1 );
1713 Sender
->ReleaseCurrentAction(); // todo, blocking?
1716 /*pst and bg2 can play a song designated by index*/
1717 /*actually pst has some extra params not currently implemented*/
1718 /*switchplaylist could implement fade */
1719 void GameScript::StartSong(Scriptable
* /*Sender*/, Action
* parameters
)
1721 const char* string
= core
->GetMusicPlaylist( parameters
->int0Parameter
);
1722 if (!string
|| string
[0] == '*') {
1723 core
->GetMusicMgr()->HardEnd();
1725 core
->GetMusicMgr()->SwitchPlayList( string
, true );
1729 void GameScript::StartMusic(Scriptable
* Sender
, Action
* parameters
)
1731 Map
*map
= Sender
->GetCurrentArea();
1732 map
->PlayAreaSong(parameters
->int0Parameter
);
1735 /*iwd2 can set an areasong slot*/
1736 void GameScript::SetMusic(Scriptable
* Sender
, Action
* parameters
)
1738 //iwd2 seems to have 10 slots, dunno if it is important
1739 if (parameters
->int0Parameter
>4) return;
1740 Map
*map
= Sender
->GetCurrentArea();
1741 map
->SongHeader
.SongList
[parameters
->int0Parameter
]=parameters
->int1Parameter
;
1744 //optional integer parameter (isSpeech)
1745 void GameScript::PlaySound(Scriptable
* Sender
, Action
* parameters
)
1747 printf( "PlaySound(%s)\n", parameters
->string0Parameter
);
1748 core
->GetAudioDrv()->Play( parameters
->string0Parameter
, Sender
->Pos
.x
,
1749 Sender
->Pos
.y
, parameters
->int0Parameter
);
1752 void GameScript::PlaySoundPoint(Scriptable
* /*Sender*/, Action
* parameters
)
1754 printf( "PlaySound(%s)\n", parameters
->string0Parameter
);
1755 core
->GetAudioDrv()->Play( parameters
->string0Parameter
, parameters
->pointParameter
.x
, parameters
->pointParameter
.y
);
1758 void GameScript::PlaySoundNotRanged(Scriptable
* /*Sender*/, Action
* parameters
)
1760 printf( "PlaySound(%s)\n", parameters
->string0Parameter
);
1761 core
->GetAudioDrv()->Play( parameters
->string0Parameter
, 0, 0, 0);
1764 void GameScript::Continue(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1768 // creates area vvc at position of object
1769 void GameScript::CreateVisualEffectObject(Scriptable
* Sender
, Action
* parameters
)
1771 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1775 CreateVisualEffectCore(tar
, tar
->Pos
, parameters
->string0Parameter
, parameters
->int0Parameter
);
1778 // creates sticky vvc on actor or normal animation on object
1779 void GameScript::CreateVisualEffectObjectSticky(Scriptable
* Sender
, Action
* parameters
)
1781 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1785 if (tar
->Type
==ST_ACTOR
) {
1786 CreateVisualEffectCore((Actor
*) tar
, parameters
->string0Parameter
, parameters
->int0Parameter
);
1788 CreateVisualEffectCore(tar
, tar
->Pos
, parameters
->string0Parameter
, parameters
->int0Parameter
);
1792 // creates area effect at point
1793 void GameScript::CreateVisualEffect(Scriptable
* Sender
, Action
* parameters
)
1795 CreateVisualEffectCore(Sender
, parameters
->pointParameter
, parameters
->string0Parameter
, parameters
->int0Parameter
);
1798 void GameScript::DestroySelf(Scriptable
* Sender
, Action
* /*parameters*/)
1800 if (Sender
->Type
!= ST_ACTOR
) {
1803 Sender
->ClearActions();
1804 Actor
* actor
= ( Actor
* ) Sender
;
1805 actor
->DestroySelf();
1806 //actor->InternalFlags |= IF_CLEANUP;
1809 void GameScript::ScreenShake(Scriptable
* Sender
, Action
* parameters
)
1811 if (parameters
->int1Parameter
) { //IWD2 has a different profile
1812 core
->timer
->SetScreenShake( parameters
->int1Parameter
,
1813 parameters
->int2Parameter
, parameters
->int0Parameter
);
1815 core
->timer
->SetScreenShake( parameters
->pointParameter
.x
,
1816 parameters
->pointParameter
.y
, parameters
->int0Parameter
);
1818 Sender
->SetWait( parameters
->int0Parameter
);
1819 Sender
->ReleaseCurrentAction(); // todo, blocking?
1822 void GameScript::UnhideGUI(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1824 Game
* game
= core
->GetGame();
1825 game
->SetControlStatus(CS_HIDEGUI
, BM_NAND
);
1828 void GameScript::HideGUI(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1830 Game
* game
= core
->GetGame();
1831 game
->SetControlStatus(CS_HIDEGUI
, BM_OR
);
1834 void GameScript::LockScroll(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1836 GameControl
* gc
= core
->GetGameControl();
1838 gc
->SetScreenFlags(SF_LOCKSCROLL
, BM_OR
);
1842 void GameScript::UnlockScroll(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1844 GameControl
* gc
= core
->GetGameControl();
1846 gc
->SetScreenFlags(SF_LOCKSCROLL
, BM_NAND
);
1850 //no string, increase talkcount, no interrupt
1851 void GameScript::Dialogue(Scriptable
* Sender
, Action
* parameters
)
1853 BeginDialog( Sender
, parameters
, BD_SOURCE
| BD_TALKCOUNT
| BD_CHECKDIST
);
1856 void GameScript::DialogueForceInterrupt(Scriptable
* Sender
, Action
* parameters
)
1858 BeginDialog( Sender
, parameters
, BD_SOURCE
| BD_TALKCOUNT
| BD_INTERRUPT
);
1861 // not in IESDP but this one should affect ambients
1862 void GameScript::SoundActivate(Scriptable
* /*Sender*/, Action
* parameters
)
1864 AmbientMgr
* ambientmgr
= core
->GetAudioDrv()->GetAmbientMgr();
1865 if (parameters
->int0Parameter
) {
1866 ambientmgr
->activate(parameters
->objects
[1]->objectName
);
1868 ambientmgr
->deactivate(parameters
->objects
[1]->objectName
);
1872 // according to IESDP this action is about animations
1873 void GameScript::AmbientActivate(Scriptable
* Sender
, Action
* parameters
)
1875 AreaAnimation
* anim
= Sender
->GetCurrentArea( )->GetAnimation( parameters
->string0Parameter
);
1877 anim
= Sender
->GetCurrentArea( )->GetAnimation( parameters
->objects
[1]->objectName
);
1880 printf( "Script error: No Animation Named \"%s\" or \"%s\"\n",
1881 parameters
->string0Parameter
,parameters
->objects
[1]->objectName
);
1884 if (parameters
->int0Parameter
) {
1885 anim
->Flags
|= A_ANI_ACTIVE
;
1887 anim
->Flags
&= ~A_ANI_ACTIVE
;
1891 void GameScript::ChangeTileState(Scriptable
* Sender
, Action
* parameters
)
1893 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
1897 if (tar
->Type
!= ST_DOOR
) {
1900 Door
* door
= ( Door
* ) tar
;
1901 int state
= parameters
->int0Parameter
;
1903 door
->ToggleTiles(state
); /* default is false for playsound */
1907 void GameScript::StaticStart(Scriptable
* Sender
, Action
* parameters
)
1909 AreaAnimation
*anim
= Sender
->GetCurrentArea()->GetAnimation(parameters
->objects
[1]->objectName
);
1911 printf( "Script error: No Animation Named \"%s\"\n",
1912 parameters
->objects
[1]->objectName
);
1915 anim
->Flags
&=~A_ANI_PLAYONCE
;
1918 void GameScript::StaticStop(Scriptable
* Sender
, Action
* parameters
)
1920 AreaAnimation
*anim
= Sender
->GetCurrentArea()->GetAnimation(parameters
->objects
[1]->objectName
);
1922 printf( "Script error: No Animation Named \"%s\"\n",
1923 parameters
->objects
[1]->objectName
);
1926 anim
->Flags
|= A_ANI_PLAYONCE
;
1929 void GameScript::StaticPalette(Scriptable
* Sender
, Action
* parameters
)
1931 AreaAnimation
*anim
= Sender
->GetCurrentArea()->GetAnimation(parameters
->objects
[1]->objectName
);
1933 printf( "Script error: No Animation Named \"%s\"\n",
1934 parameters
->objects
[1]->objectName
);
1937 anim
->SetPalette( parameters
->string0Parameter
);
1940 //this is a special case of PlaySequence (with wait time, not for area anims)
1941 void GameScript::PlaySequenceTimed(Scriptable
* Sender
, Action
* parameters
)
1944 if (parameters
->objects
[1]) {
1945 tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1949 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
1952 Actor
* actor
= ( Actor
* ) tar
;
1953 actor
->SetStance( parameters
->int0Parameter
);
1954 int delay
= parameters
->int1Parameter
|| 1;
1955 actor
->SetWait( delay
);
1958 //waitanimation: waiting while animation of target is of a certain type
1959 void GameScript::WaitAnimation(Scriptable
* Sender
, Action
* parameters
)
1961 Scriptable
*tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1965 if (tar
->Type
!= ST_ACTOR
) {
1968 Actor
* actor
= ( Actor
* ) tar
;
1969 if (actor
->GetStance()!=parameters
->int0Parameter
) {
1970 Sender
->ReleaseCurrentAction();
1975 // PlaySequence without object parameter defaults to Sender
1976 void GameScript::PlaySequence(Scriptable
* Sender
, Action
* parameters
)
1979 if (parameters
->objects
[1]) {
1980 tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1982 //could be an animation
1983 AreaAnimation
* anim
= Sender
->GetCurrentArea( )->GetAnimation( parameters
->objects
[1]->objectName
);
1985 //set animation's cycle to parameters->int0Parameter;
1986 anim
->sequence
=parameters
->int0Parameter
;
1988 //what else to be done???
1989 anim
->InitAnimation();
1997 if (tar
->Type
!= ST_ACTOR
) {
2000 Actor
* actor
= ( Actor
* ) tar
;
2001 actor
->SetStance( parameters
->int0Parameter
);
2004 void GameScript::SetDialogue(Scriptable
* Sender
, Action
* parameters
)
2006 if (Sender
->Type
!= ST_ACTOR
) {
2009 Actor
* target
= ( Actor
* ) Sender
;
2010 target
->SetDialog( parameters
->string0Parameter
);
2013 void GameScript::ChangeDialogue(Scriptable
* Sender
, Action
* parameters
)
2015 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2019 if (tar
->Type
!= ST_ACTOR
) {
2022 Actor
* target
= ( Actor
* ) tar
;
2023 target
->SetDialog( parameters
->string0Parameter
);
2026 //string0, no interrupt, talkcount increased
2027 void GameScript::StartDialogue(Scriptable
* Sender
, Action
* parameters
)
2029 BeginDialog( Sender
, parameters
, BD_STRING0
| BD_TALKCOUNT
| BD_SETDIALOG
);
2032 //string0, no interrupt, talkcount increased, don't set default
2033 //optionally item name is used
2034 void GameScript::StartDialogueOverride(Scriptable
* Sender
, Action
* parameters
)
2036 int flags
= BD_STRING0
| BD_TALKCOUNT
;
2038 if (parameters
->int2Parameter
) {
2041 BeginDialog( Sender
, parameters
, flags
);
2044 //string0, no interrupt, talkcount increased, don't set default
2045 //optionally item name is used
2046 void GameScript::StartDialogueOverrideInterrupt(Scriptable
* Sender
,
2049 int flags
= BD_STRING0
| BD_TALKCOUNT
| BD_INTERRUPT
;
2051 if (parameters
->int2Parameter
) {
2054 BeginDialog( Sender
, parameters
, flags
);
2057 //start talking to oneself
2058 void GameScript::PlayerDialogue(Scriptable
* Sender
, Action
* parameters
)
2060 BeginDialog( Sender
, parameters
, BD_RESERVED
| BD_OWN
);
2063 //we hijack this action for the player initiated dialogue
2064 void GameScript::NIDSpecial1(Scriptable
* Sender
, Action
* parameters
)
2066 BeginDialog( Sender
, parameters
, BD_INTERRUPT
| BD_TARGET
/*| BD_NUMERIC*/ | BD_TALKCOUNT
| BD_CHECKDIST
);
2069 void GameScript::NIDSpecial2(Scriptable
* Sender
, Action
* /*parameters*/)
2071 if (Sender
->Type
!= ST_ACTOR
) {
2072 Sender
->ReleaseCurrentAction();
2075 Game
*game
=core
->GetGame();
2076 if (!game
->EveryoneStopped() ) {
2078 Sender
->SetWait( 1 * AI_UPDATE_TIME
);
2081 Actor
*actor
= (Actor
*) Sender
;
2082 if (!game
->EveryoneNearPoint(actor
->GetCurrentArea(), actor
->Pos
, true) ) {
2083 //we abort the command, everyone should be here
2084 Sender
->ReleaseCurrentAction();
2087 //travel direction passed to guiscript
2088 int direction
= Sender
->GetCurrentArea()->WhichEdge(actor
->Pos
);
2089 printf("Travel direction returned: %d\n", direction
);
2090 if (direction
==-1) {
2091 Sender
->ReleaseCurrentAction();
2094 core
->GetDictionary()->SetAt("Travel", (ieDword
) direction
);
2095 core
->GetGUIScriptEngine()->RunFunction( "OpenWorldMapWindow" );
2096 //sorry, i have absolutely no idea when i should do this :)
2097 Sender
->ReleaseCurrentAction();
2100 void GameScript::StartDialogueInterrupt(Scriptable
* Sender
, Action
* parameters
)
2102 BeginDialog( Sender
, parameters
,
2103 BD_STRING0
| BD_INTERRUPT
| BD_TALKCOUNT
| BD_SETDIALOG
);
2106 //No string, flags:0
2107 void GameScript::StartDialogueNoSet(Scriptable
* Sender
, Action
* parameters
)
2109 BeginDialog( Sender
, parameters
, BD_TALKCOUNT
| BD_SOURCE
);
2112 void GameScript::StartDialogueNoSetInterrupt(Scriptable
* Sender
,
2115 BeginDialog( Sender
, parameters
, BD_TALKCOUNT
| BD_SOURCE
| BD_INTERRUPT
);
2118 //no talkcount, using banter dialogs
2119 //probably banter dialogs are random, like rumours!
2120 //no, they aren't, but they increase interactcount
2121 void GameScript::Interact(Scriptable
* Sender
, Action
* parameters
)
2123 BeginDialog( Sender
, parameters
, BD_INTERACT
| BD_NOEMPTY
);
2126 static unsigned int FindNearPoint(Scriptable
* Sender
, Point
*&p1
, Point
*&p2
)
2128 unsigned int distance1
= Distance(*p1
, Sender
);
2129 unsigned int distance2
= Distance(*p2
, Sender
);
2130 if (distance1
<= distance2
) {
2140 //this is an immediate action without checking Sender
2141 void GameScript::DetectSecretDoor(Scriptable
* Sender
, Action
* parameters
)
2143 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
2147 if (tar
->Type
!= ST_DOOR
) {
2150 Door
* door
= ( Door
* ) tar
;
2151 if (door
->Flags
& DOOR_SECRET
) {
2152 door
->Flags
|= DOOR_FOUND
;
2156 //this is an immediate action without checking Sender
2157 void GameScript::Lock(Scriptable
* Sender
, Action
* parameters
)
2159 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2163 switch (tar
->Type
) {
2165 ((Door
*)tar
)->SetDoorLocked(true, true);
2168 ((Container
*)tar
)->SetContainerLocked(true);
2175 void GameScript::Unlock(Scriptable
* Sender
, Action
* parameters
)
2177 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2181 switch (tar
->Type
) {
2183 ((Door
*)tar
)->SetDoorLocked(false, true);
2186 ((Container
*)tar
)->SetContainerLocked(false);
2193 void GameScript::SetDoorLocked(Scriptable
* Sender
, Action
* parameters
)
2195 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2199 if (tar
->Type
!= ST_DOOR
) {
2202 Door
* door
= ( Door
* ) tar
;
2203 door
->SetDoorLocked( parameters
->int0Parameter
!=0, false);
2206 void GameScript::SetDoorFlag(Scriptable
* Sender
, Action
* parameters
)
2208 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2212 if (tar
->Type
!= ST_DOOR
) {
2215 Door
* door
= ( Door
* ) tar
;
2216 ieDword flag
= parameters
->int0Parameter
;
2218 //these are special flags
2219 if (flag
&DOOR_LOCKED
) {
2221 door
->SetDoorLocked(parameters
->int1Parameter
!=0, false);
2223 if (flag
&DOOR_OPEN
) {
2225 door
->SetDoorOpen(parameters
->int1Parameter
!=0, false, 0);
2228 if (parameters
->int1Parameter
) {
2235 void GameScript::RemoveTraps(Scriptable
* Sender
, Action
* parameters
)
2237 //only actors may try to pick a lock
2238 if (Sender
->Type
!= ST_ACTOR
) {
2239 Sender
->ReleaseCurrentAction();
2242 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2244 Sender
->ReleaseCurrentAction();
2247 unsigned int distance
;
2250 Container
*container
= NULL
;
2251 InfoPoint
*trigger
= NULL
;
2252 ScriptableType type
= tar
->Type
;
2257 door
= ( Door
* ) tar
;
2258 if (door
->IsOpen()) {
2259 //door is already open
2260 Sender
->ReleaseCurrentAction();
2264 otherp
= door
->toOpen
+1;
2265 distance
= FindNearPoint( Sender
, p
, otherp
);
2266 flags
= door
->Trapped
&& door
->TrapDetected
;
2269 container
= (Container
*) tar
;
2270 p
= &container
->Pos
;
2272 distance
= Distance(*p
, Sender
);
2273 flags
= container
->Trapped
&& container
->TrapDetected
;
2276 trigger
= (InfoPoint
*) tar
;
2277 // this point is incorrect! will cause actor to enter trap
2278 // need to find a point using trigger->outline
2281 distance
= Distance(tar
, Sender
);
2282 flags
= trigger
->Trapped
&& trigger
->TrapDetected
&& trigger
->CanDetectTrap();
2285 Sender
->ReleaseCurrentAction();
2288 Actor
* actor
= (Actor
*) Sender
;
2289 actor
->SetOrientation( GetOrient( *otherp
, actor
->Pos
), false);
2290 if (distance
<= MAX_OPERATING_DISTANCE
) {
2294 door
->TryDisarm(actor
);
2297 container
->TryDisarm(actor
);
2300 trigger
->TryDisarm(actor
);
2308 //core->DisplayString(STR_NOT_TRAPPED);
2311 MoveNearerTo(Sender
, *p
, MAX_OPERATING_DISTANCE
,0);
2315 Sender
->ReleaseCurrentAction();
2318 void GameScript::PickLock(Scriptable
* Sender
, Action
* parameters
)
2320 //only actors may try to pick a lock
2321 if (Sender
->Type
!= ST_ACTOR
) {
2322 Sender
->ReleaseCurrentAction();
2325 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2327 Sender
->ReleaseCurrentAction();
2330 unsigned int distance
;
2333 Container
*container
= NULL
;
2334 ScriptableType type
= tar
->Type
;
2339 door
= ( Door
* ) tar
;
2340 if (door
->IsOpen()) {
2341 //door is already open
2342 Sender
->ReleaseCurrentAction();
2346 otherp
= door
->toOpen
+1;
2347 distance
= FindNearPoint( Sender
, p
, otherp
);
2348 flags
= door
->Flags
&DOOR_LOCKED
;
2351 container
= (Container
*) tar
;
2352 p
= &container
->Pos
;
2354 distance
= Distance(*p
, Sender
);
2355 flags
= container
->Flags
&CONT_LOCKED
;
2358 Sender
->ReleaseCurrentAction();
2361 Actor
* actor
= (Actor
*) Sender
;
2362 actor
->SetOrientation( GetOrient( *otherp
, actor
->Pos
), false);
2363 if (distance
<= MAX_OPERATING_DISTANCE
) {
2365 if (type
==ST_DOOR
) {
2366 door
->TryPickLock(actor
);
2368 container
->TryPickLock(actor
);
2372 //core->DisplayString(STR_NOT_LOCKED);
2375 MoveNearerTo(Sender
, *p
, MAX_OPERATING_DISTANCE
,0);
2379 Sender
->ReleaseCurrentAction();
2382 void GameScript::OpenDoor(Scriptable
* Sender
, Action
* parameters
) {
2383 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2387 if (tar
->Type
!= ST_DOOR
) {
2390 Door
* door
= ( Door
* ) tar
;
2391 // no idea if this is right, or whether OpenDoor/CloseDoor should allow opening
2392 // of all doors, or some doors, or whether it should still check for non-actors
2393 if (Sender
->Type
== ST_ACTOR
) {
2394 Actor
*actor
= (Actor
*)Sender
;
2395 actor
->SetModal(MS_NONE
);
2396 if (!door
->TryUnlock(actor
)) {
2400 //if not an actor opens, it don't play sound
2401 door
->SetDoorOpen( true, (Sender
->Type
== ST_ACTOR
), 0 );
2402 Sender
->ReleaseCurrentAction();
2405 void GameScript::CloseDoor(Scriptable
* Sender
, Action
* parameters
) {
2406 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2410 if (tar
->Type
!= ST_DOOR
) {
2413 Door
* door
= ( Door
* ) tar
;
2414 // see comments in OpenDoor above
2415 if (Sender
->Type
== ST_ACTOR
) {
2416 Actor
*actor
= (Actor
*)Sender
;
2417 if (!door
->TryUnlock(actor
)) {
2421 //if not an actor closes, it don't play sound
2422 door
->SetDoorOpen( false, (Sender
->Type
== ST_ACTOR
), 0 );
2423 Sender
->ReleaseCurrentAction();
2426 void GameScript::ToggleDoor(Scriptable
* Sender
, Action
* /*parameters*/)
2428 if (Sender
->Type
!= ST_ACTOR
) {
2429 Sender
->ReleaseCurrentAction();
2432 Actor
*actor
= (Actor
*) Sender
;
2433 actor
->SetModal(MS_NONE
);
2435 // TargetDoor is set when GameControl makes the action, so should be fine
2436 // unless this action is quietly called by a script (and UseDoor in the
2437 // original engine crashes, so this is surely no worse..), but we should
2438 // maybe have a better solution
2439 Scriptable
* tar
= actor
->TargetDoor
;
2441 Sender
->ReleaseCurrentAction();
2444 if (tar
->Type
!= ST_DOOR
) {
2445 Sender
->ReleaseCurrentAction();
2448 Door
* door
= ( Door
* ) tar
;
2449 unsigned int distance
;
2450 Point
*p
= door
->toOpen
;
2451 Point
*otherp
= door
->toOpen
+1;
2452 distance
= FindNearPoint( Sender
, p
, otherp
);
2453 if (distance
<= MAX_OPERATING_DISTANCE
) {
2454 actor
->SetOrientation( GetOrient( *otherp
, actor
->Pos
), false);
2455 if (!door
->TryUnlock(actor
)) {
2456 core
->DisplayConstantString(STR_DOORLOCKED
,0xd7d7be,door
);
2457 //playsound unsuccessful opening of door
2459 core
->PlaySound(DS_CLOSE_FAIL
);
2461 core
->PlaySound(DS_OPEN_FAIL
);
2462 Sender
->ReleaseCurrentAction();
2463 return; //don't open door
2466 // should we be triggering the trap on close?
2467 door
->TriggerTrap(0, actor
->GetID());
2468 door
->SetDoorOpen( !door
->IsOpen(), true, actor
->GetID() );
2470 MoveNearerTo(Sender
, *p
, MAX_OPERATING_DISTANCE
,0);
2474 Sender
->ReleaseCurrentAction();
2477 void GameScript::ContainerEnable(Scriptable
* Sender
, Action
* parameters
)
2479 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2480 if (!tar
|| tar
->Type
!=ST_CONTAINER
) {
2483 Container
*cnt
= (Container
*) tar
;
2484 if (parameters
->int0Parameter
) {
2485 cnt
->Flags
&=~CONT_DISABLED
;
2487 cnt
->Flags
|=CONT_DISABLED
;
2491 void GameScript::MoveBetweenAreas(Scriptable
* Sender
, Action
* parameters
)
2493 if (Sender
->Type
!= ST_ACTOR
) {
2496 if (parameters
->string1Parameter
[0]) {
2497 CreateVisualEffectCore(Sender
, Sender
->Pos
, parameters
->string1Parameter
, 0);
2499 MoveBetweenAreasCore((Actor
*) Sender
, parameters
->string0Parameter
,
2500 parameters
->pointParameter
, parameters
->int0Parameter
, true);
2503 //spell is depleted, casting time is calculated, interruptible
2504 //FIXME The caster must meet the level requirements as set in the spell file
2505 void GameScript::Spell(Scriptable
* Sender
, Action
* parameters
)
2510 if (!ResolveSpellName( spellres
, parameters
) ) {
2511 Sender
->ReleaseCurrentAction();
2515 //if target was set, fire spell
2516 if (Sender
->LastTarget
) {
2517 Sender
->CastSpellEnd( spellres
);
2518 Sender
->ReleaseCurrentAction();
2522 //the target was converted to a point
2523 if(!Sender
->LastTargetPos
.isempty()) {
2524 Sender
->CastSpellPointEnd( spellres
);
2525 Sender
->ReleaseCurrentAction();
2530 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
2532 Sender
->ReleaseCurrentAction();
2536 if(Sender
->Type
==ST_ACTOR
) {
2537 Actor
*act
= (Actor
*) Sender
;
2539 unsigned int dist
= GetSpellDistance(spellres
, act
);
2541 //move near to target
2542 if (PersonalDistance(tar
, Sender
) > dist
) {
2543 MoveNearerTo(Sender
,tar
,dist
);
2548 if (tar
!= Sender
) {
2549 act
->SetOrientation( GetOrient( tar
->Pos
, act
->Pos
), false );
2552 //stop doing anything else
2553 act
->SetModal(MS_NONE
);
2555 int duration
= Sender
->CastSpell( spellres
, tar
, true );
2556 if (duration
!= -1) Sender
->SetWait(duration
);
2558 //if target was set, feed action back
2559 if (!Sender
->LastTarget
&& Sender
->LastTargetPos
.isempty()) {
2560 Sender
->ReleaseCurrentAction();
2564 //spell is depleted, casting time is calculated, interruptible
2565 //FIXME The caster must meet the level requirements as set in the spell file
2566 void GameScript::SpellPoint(Scriptable
* Sender
, Action
* parameters
)
2571 if (!ResolveSpellName( spellres
, parameters
) ) {
2572 Sender
->ReleaseCurrentAction();
2576 //if target was set, fire spell
2577 if (!Sender
->LastTargetPos
.isempty()) {
2578 Sender
->CastSpellPointEnd( spellres
);
2579 Sender
->ReleaseCurrentAction();
2583 if(Sender
->Type
==ST_ACTOR
) {
2584 Actor
*act
= (Actor
*) Sender
;
2586 unsigned int dist
= GetSpellDistance(spellres
, act
);
2588 //move near to target
2589 if (PersonalDistance(parameters
->pointParameter
, Sender
) > dist
) {
2590 MoveNearerTo(Sender
,parameters
->pointParameter
,dist
, 0);
2595 act
->SetOrientation( GetOrient( parameters
->pointParameter
, act
->Pos
), false );
2596 //stop doing anything else
2597 act
->SetModal(MS_NONE
);
2600 int duration
= Sender
->CastSpellPoint( spellres
, parameters
->pointParameter
, true );
2601 if (duration
!= -1) Sender
->SetWait(duration
);
2603 //if target was set, feed action back
2604 if (!Sender
->LastTarget
&& Sender
->LastTargetPos
.isempty()) {
2605 Sender
->ReleaseCurrentAction();
2609 //spell is not depleted (doesn't need to be memorised or known)
2610 //casting time is calculated, interruptible
2611 //FIXME The caster must meet the level requirements as set in the spell file
2612 void GameScript::SpellNoDec(Scriptable
* Sender
, Action
* parameters
)
2617 if (!ResolveSpellName( spellres
, parameters
) ) {
2618 Sender
->ReleaseCurrentAction();
2622 //if target was set, fire spell
2623 if (Sender
->LastTarget
) {
2624 Sender
->CastSpellEnd( spellres
);
2625 Sender
->ReleaseCurrentAction();
2629 //the target was converted to a point
2630 if(!Sender
->LastTargetPos
.isempty()) {
2631 Sender
->CastSpellPointEnd( spellres
);
2632 Sender
->ReleaseCurrentAction();
2637 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
2639 Sender
->ReleaseCurrentAction();
2644 if (Sender
->Type
==ST_ACTOR
) {
2645 Actor
*act
= (Actor
*) Sender
;
2646 if (tar
!= Sender
) {
2647 act
->SetOrientation( GetOrient( tar
->Pos
, act
->Pos
), false );
2650 //stop doing anything else
2651 act
->SetModal(MS_NONE
);
2653 int duration
= Sender
->CastSpell( spellres
, tar
, false );
2654 if (duration
!= -1) Sender
->SetWait(duration
);
2656 //if target was set, feed action back
2657 if (!Sender
->LastTarget
&& Sender
->LastTargetPos
.isempty()) {
2658 Sender
->ReleaseCurrentAction();
2662 //spell is not depleted (doesn't need to be memorised or known)
2663 //casting time is calculated, interruptible
2664 //FIXME The caster must meet the level requirements as set in the spell file
2665 void GameScript::SpellPointNoDec(Scriptable
* Sender
, Action
* parameters
)
2670 if (!ResolveSpellName( spellres
, parameters
) ) {
2671 Sender
->ReleaseCurrentAction();
2675 //if target was set, fire spell
2676 if (!Sender
->LastTargetPos
.isempty()) {
2677 Sender
->CastSpellPointEnd( spellres
);
2678 Sender
->ReleaseCurrentAction();
2683 if (Sender
->Type
==ST_ACTOR
) {
2684 Actor
*act
= (Actor
*) Sender
;
2685 act
->SetOrientation( GetOrient( parameters
->pointParameter
, act
->Pos
), false );
2687 //stop doing anything else
2688 act
->SetModal(MS_NONE
);
2691 int duration
= Sender
->CastSpellPoint( spellres
, parameters
->pointParameter
, false );
2692 if (duration
!= -1) Sender
->SetWait(duration
);
2694 //if target was set, feed action back
2695 if (Sender
->LastTargetPos
.isempty()) {
2696 Sender
->ReleaseCurrentAction();
2700 //spell is not depleted (doesn't need to be memorised or known)
2701 //casting time is calculated, not interruptable
2702 //FIXME The caster must meet the level requirements as set in the spell file
2703 void GameScript::ForceSpell(Scriptable
* Sender
, Action
* parameters
)
2708 if (!ResolveSpellName( spellres
, parameters
) ) {
2709 Sender
->ReleaseCurrentAction();
2713 //if target was set, fire spell
2714 if (Sender
->LastTarget
) {
2715 Sender
->CastSpellEnd( spellres
);
2716 Sender
->ReleaseCurrentAction();
2720 //the target was converted to a point
2721 if(!Sender
->LastTargetPos
.isempty()) {
2722 Sender
->CastSpellPointEnd( spellres
);
2723 Sender
->ReleaseCurrentAction();
2728 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
2730 Sender
->ReleaseCurrentAction();
2735 if (Sender
->Type
==ST_ACTOR
) {
2736 Actor
*act
= (Actor
*) Sender
;
2737 if (tar
!= Sender
) {
2738 act
->SetOrientation( GetOrient( tar
->Pos
, act
->Pos
), false );
2741 //stop doing anything else
2742 act
->SetModal(MS_NONE
);
2744 int duration
= Sender
->CastSpell (spellres
, tar
, false);
2745 if (duration
!= -1) Sender
->SetWait(duration
);
2747 //if target was set, feed action back
2748 if (!Sender
->LastTarget
&& Sender
->LastTargetPos
.isempty()) {
2749 Sender
->ReleaseCurrentAction();
2753 //spell is not depleted (doesn't need to be memorised or known)
2754 //casting time is calculated, not interruptable
2755 //FIXME The caster must meet the level requirements as set in the spell file
2756 void GameScript::ForceSpellPoint(Scriptable
* Sender
, Action
* parameters
)
2760 if (!ResolveSpellName( spellres
, parameters
) ) {
2761 Sender
->ReleaseCurrentAction();
2765 //if target was set, fire spell
2766 if (!Sender
->LastTargetPos
.isempty()) {
2767 Sender
->CastSpellPointEnd( spellres
);
2768 Sender
->ReleaseCurrentAction();
2773 if (Sender
->Type
==ST_ACTOR
) {
2774 Actor
*act
= (Actor
*) Sender
;
2775 act
->SetOrientation( GetOrient( parameters
->pointParameter
, act
->Pos
), false );
2777 //stop doing anything else
2778 act
->SetModal(MS_NONE
);
2781 int duration
= Sender
->CastSpellPoint (spellres
, parameters
->pointParameter
, false);
2782 if (duration
!= -1) Sender
->SetWait(duration
);
2784 //if target was set, feed action back
2785 if (Sender
->LastTargetPos
.isempty()) {
2786 Sender
->ReleaseCurrentAction();
2790 //ForceSpell with zero casting time
2791 //zero casting time, no depletion, not interruptable
2792 //FIXME The caster must meet the level requirements as set in the spell file
2793 void GameScript::ReallyForceSpell(Scriptable
* Sender
, Action
* parameters
)
2797 if (!ResolveSpellName( spellres
, parameters
) ) {
2798 Sender
->ReleaseCurrentAction();
2802 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2804 Sender
->ReleaseCurrentAction();
2807 if (Sender
->Type
== ST_ACTOR
) {
2808 Actor
*actor
= (Actor
*) Sender
;
2809 if (tar
!= Sender
) {
2810 actor
->SetOrientation( GetOrient( tar
->Pos
, actor
->Pos
), false );
2812 actor
->SetStance (IE_ANI_CONJURE
);
2814 Sender
->CastSpell (spellres
, tar
, false, true);
2815 if (tar
->Type
==ST_ACTOR
) {
2816 Sender
->CastSpellEnd(spellres
);
2818 Sender
->CastSpellPointEnd(spellres
);
2820 Sender
->ReleaseCurrentAction();
2823 //ForceSpellPoint with zero casting time
2824 //zero casting time, no depletion (finish casting at point), not interruptable
2826 //FIXME The caster must meet the level requirements as set in the spell file
2827 void GameScript::ReallyForceSpellPoint(Scriptable
* Sender
, Action
* parameters
)
2831 if (!ResolveSpellName( spellres
, parameters
) ) {
2832 Sender
->ReleaseCurrentAction();
2836 //Sender->LastTargetPos=parameters->pointParameter;
2837 if (Sender
->Type
== ST_ACTOR
) {
2838 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
2839 Sender
->ReleaseCurrentAction();
2842 Actor
*actor
= (Actor
*) Sender
;
2843 actor
->SetOrientation( GetOrient( parameters
->pointParameter
, actor
->Pos
), false );
2844 actor
->SetStance (IE_ANI_CONJURE
);
2846 Sender
->CastSpellPoint (spellres
, parameters
->pointParameter
, false, true);
2847 Sender
->CastSpellPointEnd(spellres
);
2848 Sender
->ReleaseCurrentAction();
2851 // this differs from ReallyForceSpell that this one allows dead Sender casting
2852 // zero casting time, no depletion
2853 void GameScript::ReallyForceSpellDead(Scriptable
* Sender
, Action
* parameters
)
2857 if (!ResolveSpellName( spellres
, parameters
) ) {
2858 Sender
->ReleaseCurrentAction();
2862 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2864 Sender
->ReleaseCurrentAction();
2867 Sender
->LastTargetPos
=parameters
->pointParameter
;
2869 if (Sender->Type == ST_ACTOR) {
2870 Actor *actor = (Actor *) Sender;
2871 //the dead don't wiggle their fingers
2872 //actor->SetStance (IE_ANI_CONJURE);
2875 Sender
->CastSpell (spellres
, tar
, false, true);
2876 if (tar
->Type
==ST_ACTOR
) {
2877 Sender
->CastSpellEnd(spellres
);
2879 Sender
->CastSpellPointEnd(spellres
);
2881 Sender
->ReleaseCurrentAction();
2884 void GameScript::Deactivate(Scriptable
* Sender
, Action
* parameters
)
2886 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2890 if (tar
->Type
!= ST_ACTOR
) {
2896 void GameScript::MakeGlobal(Scriptable
* Sender
, Action
* /*parameters*/)
2898 if (Sender
->Type
!= ST_ACTOR
) {
2901 Actor
* act
= ( Actor
* ) Sender
;
2902 core
->GetGame()->AddNPC( act
);
2905 void GameScript::UnMakeGlobal(Scriptable
* Sender
, Action
* /*parameters*/)
2907 if (Sender
->Type
!= ST_ACTOR
) {
2910 Actor
* act
= ( Actor
* ) Sender
;
2912 slot
= core
->GetGame()->InStore( act
);
2914 core
->GetGame()->DelNPC( slot
);
2918 //this apparently doesn't check the gold, thus could be used from non actors
2919 void GameScript::GivePartyGoldGlobal(Scriptable
* Sender
, Action
* parameters
)
2921 ieDword gold
= (ieDword
) CheckVariable( Sender
, parameters
->string0Parameter
, parameters
->string1Parameter
);
2922 if (Sender
->Type
== ST_ACTOR
) {
2923 Actor
* act
= ( Actor
* ) Sender
;
2924 ieDword mygold
= act
->GetStat(IE_GOLD
);
2925 if (mygold
< gold
) {
2928 //will get saved, not adjusted
2929 act
->SetBase(IE_GOLD
, act
->GetBase(IE_GOLD
)-gold
);
2931 core
->GetGame()->AddGold(gold
);
2934 void GameScript::CreatePartyGold(Scriptable
* /*Sender*/, Action
* parameters
)
2936 core
->GetGame()->AddGold(parameters
->int0Parameter
);
2939 void GameScript::GivePartyGold(Scriptable
* Sender
, Action
* parameters
)
2941 ieDword gold
= (ieDword
) parameters
->int0Parameter
;
2942 if (Sender
->Type
== ST_ACTOR
) {
2943 Actor
* act
= ( Actor
* ) Sender
;
2944 ieDword mygold
= act
->GetStat(IE_GOLD
);
2945 if (mygold
< gold
) {
2948 //will get saved, not adjusted
2949 act
->SetBase(IE_GOLD
, act
->GetBase(IE_GOLD
)-gold
);
2951 core
->GetGame()->AddGold(gold
);
2954 void GameScript::DestroyPartyGold(Scriptable
* /*Sender*/, Action
* parameters
)
2956 int gold
= core
->GetGame()->PartyGold
;
2957 if (gold
>parameters
->int0Parameter
) {
2958 gold
=parameters
->int0Parameter
;
2960 core
->GetGame()->AddGold(-gold
);
2963 void GameScript::TakePartyGold(Scriptable
* Sender
, Action
* parameters
)
2965 ieDword gold
= core
->GetGame()->PartyGold
;
2966 if (gold
>(ieDword
) parameters
->int0Parameter
) {
2967 gold
=(ieDword
) parameters
->int0Parameter
;
2969 core
->GetGame()->AddGold((ieDword
) -(int) gold
);
2970 if (Sender
->Type
== ST_ACTOR
) {
2971 Actor
* act
= ( Actor
* ) Sender
;
2972 act
->SetBase(IE_GOLD
, act
->GetBase(IE_GOLD
)+gold
);
2976 void GameScript::AddXPObject(Scriptable
* Sender
, Action
* parameters
)
2978 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2982 if (tar
->Type
!= ST_ACTOR
) {
2985 Actor
* actor
= ( Actor
* ) tar
;
2986 int xp
= parameters
->int0Parameter
;
2987 if (core
->GetStringReference(STR_GOTQUESTXP
) == (ieStrRef
) -1) {
2988 core
->DisplayConstantStringValue(STR_GOTXP
, 0xbcefbc, (ieDword
)xp
);
2990 core
->GetTokenDictionary()->SetAtCopy("EXPERIENCEAMOUNT", xp
);
2991 core
->DisplayConstantStringName(STR_GOTQUESTXP
, 0xbcefbc, actor
);
2993 actor
->AddExperience(xp
);
2996 void GameScript::AddXP2DA(Scriptable
* /*Sender*/, Action
* parameters
)
3000 if (core
->HasFeature(GF_HAS_EXPTABLE
) ) {
3001 xptable
.load("exptable");
3003 xptable
.load("xplist");
3006 if (parameters
->int0Parameter
>0) {
3007 core
->DisplayString(parameters
->int0Parameter
, 0x40f0f000,IE_STR_SOUND
);
3010 printMessage("GameScript","Can't perform ADDXP2DA",LIGHT_RED
);
3013 const char * xpvalue
= xptable
->QueryField( parameters
->string0Parameter
, "0" ); //level is unused
3015 if ( xpvalue
[0]=='P' && xpvalue
[1]=='_') {
3017 core
->GetGame()->ShareXP(atoi(xpvalue
+2), SX_DIVIDE
);
3020 core
->GetGame()->ShareXP(atoi(xpvalue
), 0 );
3024 void GameScript::AddExperienceParty(Scriptable
* /*Sender*/, Action
* parameters
)
3026 core
->GetGame()->ShareXP(parameters
->int0Parameter
, SX_DIVIDE
);
3029 //this needs moncrate.2da, but otherwise independent from GF_CHALLENGERATING
3030 void GameScript::AddExperiencePartyCR(Scriptable
* /*Sender*/, Action
* parameters
)
3032 core
->GetGame()->ShareXP(parameters
->int0Parameter
, SX_DIVIDE
|SX_CR
);
3035 void GameScript::AddExperiencePartyGlobal(Scriptable
* Sender
, Action
* parameters
)
3037 ieDword xp
= CheckVariable( Sender
, parameters
->string0Parameter
, parameters
->string1Parameter
);
3038 core
->GetGame()->ShareXP(xp
, SX_DIVIDE
);
3041 void GameScript::SetMoraleAI(Scriptable
* Sender
, Action
* parameters
)
3043 if (Sender
->Type
!= ST_ACTOR
) {
3046 Actor
* act
= ( Actor
* ) Sender
;
3047 act
->SetBase(IE_MORALE
, parameters
->int0Parameter
);
3050 void GameScript::IncMoraleAI(Scriptable
* Sender
, Action
* parameters
)
3052 if (Sender
->Type
!= ST_ACTOR
) {
3055 Actor
* act
= ( Actor
* ) Sender
;
3056 act
->SetBase(IE_MORALE
, parameters
->int0Parameter
+act
->GetBase(IE_MORALE
) );
3059 void GameScript::MoraleSet(Scriptable
* Sender
, Action
* parameters
)
3061 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3065 if (tar
->Type
!= ST_ACTOR
) {
3068 Actor
* act
= ( Actor
* ) tar
;
3069 act
->SetBase(IE_MORALEBREAK
, parameters
->int0Parameter
);
3072 void GameScript::MoraleInc(Scriptable
* Sender
, Action
* parameters
)
3074 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3078 if (tar
->Type
!= ST_ACTOR
) {
3081 Actor
* act
= ( Actor
* ) tar
;
3082 act
->SetBase(IE_MORALEBREAK
, act
->GetBase(IE_MORALEBREAK
)+parameters
->int0Parameter
);
3085 void GameScript::MoraleDec(Scriptable
* Sender
, Action
* parameters
)
3087 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3091 if (tar
->Type
!= ST_ACTOR
) {
3094 Actor
* act
= ( Actor
* ) tar
;
3095 act
->SetBase(IE_MORALEBREAK
, act
->GetBase(IE_MORALEBREAK
)-parameters
->int0Parameter
);
3098 void GameScript::JoinParty(Scriptable
* Sender
, Action
* parameters
)
3100 if (Sender
->Type
!= ST_ACTOR
) {
3103 /* calling this, so it is simpler to change */
3104 /* i'm not sure this is required here at all */
3105 SetBeenInPartyFlags(Sender
, parameters
);
3106 Actor
* act
= ( Actor
* ) Sender
;
3107 act
->SetBase( IE_EA
, EA_PC
);
3108 if (core
->HasFeature( GF_HAS_DPLAYER
)) {
3109 /* we must reset various existing scripts */
3110 act
->SetScript( "DEFAULT", AI_SCRIPT_LEVEL
, true );
3111 act
->SetScript( "", SCR_RACE
, true );
3112 act
->SetScript( "", SCR_GENERAL
, true );
3113 act
->SetScript( "DPLAYER2", SCR_DEFAULT
, false );
3115 AutoTable
pdtable("pdialog");
3117 const char* scriptname
= act
->GetScriptName();
3119 //set dialog only if we got a row
3120 if (pdtable
->GetRowIndex( scriptname
) != -1) {
3121 strnlwrcpy(resref
, pdtable
->QueryField( scriptname
, "JOIN_DIALOG_FILE"),8);
3122 act
->SetDialog( resref
);
3125 core
->GetGame()->JoinParty( act
, JP_JOIN
);
3126 core
->GetGUIScriptEngine()->RunFunction( "UpdatePortraitWindow" );
3129 void GameScript::LeaveParty(Scriptable
* Sender
, Action
* /*parameters*/)
3131 if (Sender
->Type
!= ST_ACTOR
) {
3134 Actor
* act
= ( Actor
* ) Sender
;
3135 core
->GetGame()->LeaveParty( act
);
3136 core
->GetGUIScriptEngine()->RunFunction( "UpdatePortraitWindow" );
3139 //HideCreature hides only the visuals of a creature
3140 //(feet circle and avatar)
3141 //the scripts of the creature are still running
3142 //iwd2 stores this flag in the MC field
3143 void GameScript::HideCreature(Scriptable
* Sender
, Action
* parameters
)
3145 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3146 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3149 Actor
* actor
= ( Actor
* ) tar
;
3150 actor
->BaseStats
[IE_AVATARREMOVAL
]=parameters
->int0Parameter
;
3153 //i have absolutely no idea why this is needed when we have HideCreature
3154 void GameScript::ForceHide(Scriptable
* Sender
, Action
* parameters
)
3156 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3160 if (tar
->Type
!= ST_ACTOR
) {
3163 Actor
* actor
= ( Actor
* ) tar
;
3164 actor
->BaseStats
[IE_AVATARREMOVAL
]=1;
3167 void GameScript::Activate(Scriptable
* Sender
, Action
* parameters
)
3169 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3170 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3173 // Deactivate hides, so this should unhide..
3178 void GameScript::ForceLeaveAreaLUA(Scriptable
* Sender
, Action
* parameters
)
3180 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3181 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3184 Actor
* actor
= ( Actor
* ) tar
;
3185 //the LoadMos ResRef may be empty
3186 strncpy(core
->GetGame()->LoadMos
, parameters
->string1Parameter
,8);
3187 MoveBetweenAreasCore( actor
, parameters
->string0Parameter
, parameters
->pointParameter
, parameters
->int0Parameter
, true);
3190 void GameScript::LeaveAreaLUA(Scriptable
* Sender
, Action
* parameters
)
3192 if (Sender
->Type
!= ST_ACTOR
) {
3195 Actor
* actor
= ( Actor
* ) Sender
;
3196 //the LoadMos ResRef may be empty
3197 strncpy(core
->GetGame()->LoadMos
, parameters
->string1Parameter
,8);
3198 MoveBetweenAreasCore( actor
, parameters
->string0Parameter
, parameters
->pointParameter
, parameters
->int0Parameter
, true);
3201 //this is a blocking action, because we have to move to the Entry
3202 void GameScript::LeaveAreaLUAEntry(Scriptable
* Sender
, Action
* parameters
)
3204 if (Sender
->Type
!= ST_ACTOR
) {
3205 Sender
->ReleaseCurrentAction();
3208 Actor
*actor
= (Actor
*) Sender
;
3209 Game
*game
= core
->GetGame();
3210 strncpy(game
->LoadMos
, parameters
->string1Parameter
,8);
3211 Point p
= GetEntryPoint(actor
->Area
, parameters
->string1Parameter
);
3213 Sender
->ReleaseCurrentAction();
3216 parameters
->pointParameter
=p
;
3217 LeaveAreaLUA(Sender
, parameters
);
3218 Sender
->ReleaseCurrentAction();
3221 void GameScript::LeaveAreaLUAPanic(Scriptable
* Sender
, Action
* parameters
)
3223 if (Sender
->Type
!= ST_ACTOR
) {
3226 Actor
* actor
= ( Actor
* ) Sender
;
3227 strncpy(core
->GetGame()->LoadMos
, parameters
->string1Parameter
,8);
3228 MoveBetweenAreasCore( actor
, parameters
->string0Parameter
, parameters
->pointParameter
, parameters
->int0Parameter
, true);
3231 //this is a blocking action, because we have to move to the Entry
3232 void GameScript::LeaveAreaLUAPanicEntry(Scriptable
* Sender
, Action
* parameters
)
3234 if (Sender
->Type
!= ST_ACTOR
) {
3235 Sender
->ReleaseCurrentAction();
3238 Actor
*actor
= (Actor
*) Sender
;
3239 Game
*game
= core
->GetGame();
3240 strncpy(game
->LoadMos
, parameters
->string1Parameter
,8);
3241 Point p
= GetEntryPoint(actor
->Area
, parameters
->string1Parameter
);
3243 Sender
->ReleaseCurrentAction();
3246 parameters
->pointParameter
=p
;
3247 LeaveAreaLUAPanic(Sender
, parameters
);
3248 Sender
->ReleaseCurrentAction();
3251 void GameScript::SetToken(Scriptable
* /*Sender*/, Action
* parameters
)
3253 //SetAt takes a newly created reference (no need of free/copy)
3254 char * str
= core
->GetString( parameters
->int0Parameter
);
3255 core
->GetTokenDictionary()->SetAt( parameters
->string1Parameter
, str
);
3258 //Assigns a numeric variable to the token
3259 void GameScript::SetTokenGlobal(Scriptable
* Sender
, Action
* parameters
)
3261 ieDword value
= CheckVariable( Sender
, parameters
->string0Parameter
);
3262 //using SetAtCopy because we need a copy of the value
3263 core
->GetTokenDictionary()->SetAtCopy( parameters
->string1Parameter
, value
);
3266 //Assigns the target object's name (not scriptname) to the token
3267 void GameScript::SetTokenObject(Scriptable
* Sender
, Action
* parameters
)
3269 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3270 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3273 Actor
* actor
= ( Actor
* ) tar
;
3274 core
->GetTokenDictionary()->SetAtCopy( parameters
->string0Parameter
, actor
->GetName(0) );
3277 void GameScript::PlayDead(Scriptable
* Sender
, Action
* parameters
)
3279 if (Sender
->Type
!= ST_ACTOR
) {
3280 Sender
->ReleaseCurrentAction();
3283 Actor
* actor
= ( Actor
* ) Sender
;
3284 if (Sender
->CurrentActionState
== 0) {
3285 Sender
->CurrentActionState
= 1;
3286 actor
->SetStance( IE_ANI_DIE
);
3287 actor
->playDeadCounter
= parameters
->int0Parameter
;
3288 actor
->NoInterrupt();
3290 if (actor
->playDeadCounter
== 0) {
3291 Sender
->ReleaseCurrentAction();
3295 /** no difference at this moment, but this action should be interruptable */
3296 /** probably that means, we don't have to issue the SetWait, but this needs */
3297 /** further research */
3298 void GameScript::PlayDeadInterruptable(Scriptable
* Sender
, Action
* parameters
)
3300 if (Sender
->Type
!= ST_ACTOR
) {
3303 Actor
* actor
= ( Actor
* ) Sender
;
3304 actor
->SetStance( IE_ANI_DIE
);
3305 //also set time for playdead!
3306 actor
->playDeadCounter
= parameters
->int0Parameter
;
3307 actor
->SetWait( 1 );
3308 Sender
->ReleaseCurrentAction(); // todo, blocking?
3311 /* this may not be correct, just a placeholder you can fix */
3312 void GameScript::Swing(Scriptable
* Sender
, Action
* /*parameters*/)
3314 if (Sender
->Type
!= ST_ACTOR
) {
3317 Actor
* actor
= ( Actor
* ) Sender
;
3318 actor
->SetStance( IE_ANI_ATTACK
);
3319 actor
->SetWait( 1 );
3322 /* this may not be correct, just a placeholder you can fix */
3323 void GameScript::SwingOnce(Scriptable
* Sender
, Action
* /*parameters*/)
3325 if (Sender
->Type
!= ST_ACTOR
) {
3328 Actor
* actor
= ( Actor
* ) Sender
;
3329 actor
->SetStance( IE_ANI_ATTACK
);
3330 actor
->SetWait( 1 );
3333 void GameScript::Recoil(Scriptable
* Sender
, Action
* /*parameters*/)
3335 if (Sender
->Type
!= ST_ACTOR
) {
3338 Actor
* actor
= ( Actor
* ) Sender
;
3339 actor
->SetStance( IE_ANI_DAMAGE
);
3340 actor
->SetWait( 1 );
3343 void GameScript::GlobalSetGlobal(Scriptable
* Sender
, Action
* parameters
)
3345 ieDword value
= CheckVariable( Sender
, parameters
->string0Parameter
);
3346 SetVariable( Sender
, parameters
->string1Parameter
, value
);
3349 /* adding the second variable to the first, they must be GLOBAL */
3350 void GameScript::AddGlobals(Scriptable
* Sender
, Action
* parameters
)
3352 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
, "GLOBAL");
3353 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
, "GLOBAL");
3354 SetVariable( Sender
, parameters
->string0Parameter
, "GLOBAL", value1
+ value2
);
3357 /* adding the second variable to the first, they could be area or locals */
3358 void GameScript::GlobalAddGlobal(Scriptable
* Sender
, Action
* parameters
)
3360 ieDword value1
= CheckVariable( Sender
,
3361 parameters
->string0Parameter
);
3362 ieDword value2
= CheckVariable( Sender
,
3363 parameters
->string1Parameter
);
3364 SetVariable( Sender
, parameters
->string0Parameter
, value1
+ value2
);
3367 /* adding the number to the global, they could be area or locals */
3368 void GameScript::IncrementGlobal(Scriptable
* Sender
, Action
* parameters
)
3370 ieDword value
= CheckVariable( Sender
, parameters
->string0Parameter
);
3371 SetVariable( Sender
, parameters
->string0Parameter
,
3372 value
+ parameters
->int0Parameter
);
3375 /* adding the number to the global ONLY if the first global is zero */
3376 void GameScript::IncrementGlobalOnce(Scriptable
* Sender
, Action
* parameters
)
3378 ieDword value
= CheckVariable( Sender
, parameters
->string0Parameter
);
3382 value
= CheckVariable( Sender
, parameters
->string1Parameter
);
3383 SetVariable( Sender
, parameters
->string1Parameter
,
3384 value
+ parameters
->int0Parameter
);
3387 void GameScript::GlobalSubGlobal(Scriptable
* Sender
, Action
* parameters
)
3389 ieDword value1
= CheckVariable( Sender
,
3390 parameters
->string0Parameter
);
3391 ieDword value2
= CheckVariable( Sender
,
3392 parameters
->string1Parameter
);
3393 SetVariable( Sender
, parameters
->string0Parameter
, value1
- value2
);
3396 void GameScript::GlobalAndGlobal(Scriptable
* Sender
, Action
* parameters
)
3398 ieDword value1
= CheckVariable( Sender
,
3399 parameters
->string0Parameter
);
3400 ieDword value2
= CheckVariable( Sender
,
3401 parameters
->string1Parameter
);
3402 SetVariable( Sender
, parameters
->string0Parameter
, value1
&& value2
);
3405 void GameScript::GlobalOrGlobal(Scriptable
* Sender
, Action
* parameters
)
3407 ieDword value1
= CheckVariable( Sender
,
3408 parameters
->string0Parameter
);
3409 ieDword value2
= CheckVariable( Sender
,
3410 parameters
->string1Parameter
);
3411 SetVariable( Sender
, parameters
->string0Parameter
, value1
|| value2
);
3414 void GameScript::GlobalBOrGlobal(Scriptable
* Sender
, Action
* parameters
)
3416 ieDword value1
= CheckVariable( Sender
,
3417 parameters
->string0Parameter
);
3418 ieDword value2
= CheckVariable( Sender
,
3419 parameters
->string1Parameter
);
3420 SetVariable( Sender
, parameters
->string0Parameter
, value1
| value2
);
3423 void GameScript::GlobalBAndGlobal(Scriptable
* Sender
, Action
* parameters
)
3425 ieDword value1
= CheckVariable( Sender
,
3426 parameters
->string0Parameter
);
3427 ieDword value2
= CheckVariable( Sender
,
3428 parameters
->string1Parameter
);
3429 SetVariable( Sender
, parameters
->string0Parameter
, value1
& value2
);
3432 void GameScript::GlobalXorGlobal(Scriptable
* Sender
, Action
* parameters
)
3434 ieDword value1
= CheckVariable( Sender
,
3435 parameters
->string0Parameter
);
3436 ieDword value2
= CheckVariable( Sender
,
3437 parameters
->string1Parameter
);
3438 SetVariable( Sender
, parameters
->string0Parameter
, value1
^ value2
);
3441 void GameScript::GlobalBOr(Scriptable
* Sender
, Action
* parameters
)
3443 ieDword value1
= CheckVariable( Sender
,
3444 parameters
->string0Parameter
);
3445 SetVariable( Sender
, parameters
->string0Parameter
,
3446 value1
| parameters
->int0Parameter
);
3449 void GameScript::GlobalBAnd(Scriptable
* Sender
, Action
* parameters
)
3451 ieDword value1
= CheckVariable( Sender
,
3452 parameters
->string0Parameter
);
3453 SetVariable( Sender
, parameters
->string0Parameter
,
3454 value1
& parameters
->int0Parameter
);
3457 void GameScript::GlobalXor(Scriptable
* Sender
, Action
* parameters
)
3459 ieDword value1
= CheckVariable( Sender
,
3460 parameters
->string0Parameter
);
3461 SetVariable( Sender
, parameters
->string0Parameter
,
3462 value1
^ parameters
->int0Parameter
);
3465 void GameScript::GlobalMax(Scriptable
* Sender
, Action
* parameters
)
3467 long value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3468 if (value1
> parameters
->int0Parameter
) {
3469 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3473 void GameScript::GlobalMin(Scriptable
* Sender
, Action
* parameters
)
3475 long value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3476 if (value1
< parameters
->int0Parameter
) {
3477 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3481 void GameScript::BitClear(Scriptable
* Sender
, Action
* parameters
)
3483 ieDword value1
= CheckVariable( Sender
,
3484 parameters
->string0Parameter
);
3485 SetVariable( Sender
, parameters
->string0Parameter
,
3486 value1
& ~parameters
->int0Parameter
);
3489 void GameScript::GlobalShL(Scriptable
* Sender
, Action
* parameters
)
3491 ieDword value1
= CheckVariable( Sender
,
3492 parameters
->string0Parameter
);
3493 ieDword value2
= parameters
->int0Parameter
;
3499 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3502 void GameScript::GlobalShR(Scriptable
* Sender
, Action
* parameters
)
3504 ieDword value1
= CheckVariable( Sender
,
3505 parameters
->string0Parameter
);
3506 ieDword value2
= parameters
->int0Parameter
;
3512 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3515 void GameScript::GlobalMaxGlobal(Scriptable
* Sender
, Action
* parameters
)
3517 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3518 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
);
3519 if (value1
< value2
) {
3520 SetVariable( Sender
, parameters
->string0Parameter
, value2
);
3524 void GameScript::GlobalMinGlobal(Scriptable
* Sender
, Action
* parameters
)
3526 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3527 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
);
3528 if (value1
> value2
) {
3529 SetVariable( Sender
, parameters
->string0Parameter
, value2
);
3533 void GameScript::GlobalShLGlobal(Scriptable
* Sender
, Action
* parameters
)
3535 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3536 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
);
3542 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3544 void GameScript::GlobalShRGlobal(Scriptable
* Sender
, Action
* parameters
)
3546 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3547 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
);
3553 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3556 void GameScript::ClearAllActions(Scriptable
* Sender
, Action
* /*parameters*/)
3558 Actor
*except
= NULL
;
3559 if (Sender
->Type
==ST_ACTOR
) {
3560 except
= (Actor
*) Sender
;
3562 Map
*map
= Sender
->GetCurrentArea();
3563 ieDword gametime
= core
->GetGame()->GameTime
;
3564 int i
= map
->GetActorCount(true);
3566 Actor
* act
= map
->GetActor(i
,true);
3567 if (act
&& act
!=except
) {
3568 if (!act
->ValidTarget(GA_NO_DEAD
) ) {
3571 //Do we need this???
3572 if (!act
->Schedule(gametime
, false) ) {
3575 act
->ClearActions();
3577 act
->SetModal(MS_NONE
);
3582 void GameScript::ClearActions(Scriptable
* Sender
, Action
* parameters
)
3584 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3588 tar
->ClearActions();
3589 if (tar
->Type
==ST_ACTOR
) {
3590 Actor
* act
= (Actor
*) tar
;
3592 //not sure about this
3593 //act->SetModal(MS_NONE);
3597 void GameScript::SetNumTimesTalkedTo(Scriptable
* Sender
, Action
* parameters
)
3599 if (Sender
->Type
!= ST_ACTOR
) {
3602 Actor
* actor
= ( Actor
* ) Sender
;
3603 actor
->TalkCount
= parameters
->int0Parameter
;
3606 void GameScript::StartMovie(Scriptable
* Sender
, Action
* parameters
)
3608 core
->PlayMovie( parameters
->string0Parameter
);
3609 Sender
->ReleaseCurrentAction(); // should this be blocking?
3612 void GameScript::SetLeavePartyDialogFile(Scriptable
* Sender
, Action
* /*parameters*/)
3614 if (Sender
->Type
!= ST_ACTOR
) {
3617 AutoTable
pdtable("pdialog");
3618 Actor
* act
= ( Actor
* ) Sender
;
3619 const char* scriptingname
= act
->GetScriptName();
3620 act
->SetDialog( pdtable
->QueryField( scriptingname
, "POST_DIALOG_FILE" ) );
3623 void GameScript::TextScreen(Scriptable
* Sender
, Action
* parameters
)
3625 strnlwrcpy(core
->GetGame()->LoadMos
, parameters
->string0Parameter
,8);
3626 core
->GetGUIScriptEngine()->RunFunction( "StartTextScreen" );
3627 core
->GetVideoDriver()->SetMouseEnabled(true);
3629 Sender
->ReleaseCurrentAction(); // should this be blocking?
3632 void GameScript::IncrementChapter(Scriptable
* Sender
, Action
* parameters
)
3634 TextScreen(Sender
, parameters
); // textscreen will release blocking for us
3635 core
->GetGame()->IncrementChapter();
3638 void GameScript::SetCriticalPathObject(Scriptable
* Sender
, Action
* parameters
)
3640 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3641 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3644 Actor
* actor
= ( Actor
* ) tar
;
3645 if (parameters
->int0Parameter
) {
3646 actor
->SetMCFlag(MC_PLOT_CRITICAL
, BM_OR
);
3648 actor
->SetMCFlag(MC_PLOT_CRITICAL
, BM_NAND
);
3652 void GameScript::SetBeenInPartyFlags(Scriptable
* Sender
, Action
* /*parameters*/)
3654 if (Sender
->Type
!= ST_ACTOR
) {
3657 Actor
* actor
= ( Actor
* ) Sender
;
3658 //it is bit 15 of the multi-class flags (confirmed)
3659 actor
->SetMCFlag(MC_BEENINPARTY
, BM_OR
);
3662 /*iwd2 sets the high MC bits this way*/
3663 void GameScript::SetCreatureAreaFlag(Scriptable
* Sender
, Action
* parameters
)
3665 if (Sender
->Type
!= ST_ACTOR
) {
3668 Actor
* actor
= ( Actor
* ) Sender
;
3669 actor
->SetMCFlag(parameters
->int0Parameter
, parameters
->int1Parameter
);
3672 //this will be a global change, fixme if it should be local
3673 void GameScript::SetTextColor(Scriptable
* /*Sender*/, Action
* parameters
)
3676 memcpy(&c
,¶meters
->int0Parameter
,4);
3677 core
->SetInfoTextColor(c
);
3680 void GameScript::BitGlobal(Scriptable
* Sender
, Action
* parameters
)
3682 ieDword value
= CheckVariable(Sender
, parameters
->string0Parameter
);
3683 HandleBitMod( value
, parameters
->int0Parameter
, parameters
->int1Parameter
);
3684 SetVariable(Sender
, parameters
->string0Parameter
, value
);
3687 void GameScript::GlobalBitGlobal(Scriptable
* Sender
, Action
* parameters
)
3689 ieDword value1
= CheckVariable(Sender
, parameters
->string0Parameter
);
3690 ieDword value2
= CheckVariable(Sender
, parameters
->string1Parameter
);
3691 HandleBitMod( value1
, value2
, parameters
->int1Parameter
);
3692 SetVariable(Sender
, parameters
->string0Parameter
, value1
);
3695 void GameScript::SetVisualRange(Scriptable
* Sender
, Action
* parameters
)
3697 if (Sender
->Type
!= ST_ACTOR
) {
3700 Actor
* actor
= ( Actor
* ) Sender
;
3701 actor
->SetBase(IE_VISUALRANGE
,parameters
->int0Parameter
);
3704 void GameScript::MakeUnselectable(Scriptable
* Sender
, Action
* parameters
)
3706 Sender
->UnselectableTimer
=parameters
->int0Parameter
;
3709 if (Sender
->Type
!= ST_ACTOR
) {
3712 Actor
* actor
= ( Actor
* ) Sender
;
3713 if (parameters
->int0Parameter
) {
3714 // flags may be wrong
3715 core
->GetGame()->SelectActor(actor
, false, SELECT_QUIET
);
3718 actor
->SetCircleSize();
3721 void GameScript::Debug(Scriptable
* /*Sender*/, Action
* parameters
)
3723 InDebug
=parameters
->int0Parameter
;
3724 printMessage("GameScript",parameters
->string0Parameter
,YELLOW
);
3727 void GameScript::IncrementProficiency(Scriptable
* Sender
, Action
* parameters
)
3729 unsigned int idx
= parameters
->int0Parameter
;
3733 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3737 if (tar
->Type
!= ST_ACTOR
) {
3740 Actor
* target
= ( Actor
* ) tar
;
3741 //start of the proficiency stats
3742 target
->SetBase(IE_PROFICIENCYBASTARDSWORD
+idx
,
3743 target
->GetBase(IE_PROFICIENCYBASTARDSWORD
+idx
)+parameters
->int1Parameter
);
3746 void GameScript::IncrementExtraProficiency(Scriptable
* Sender
, Action
* parameters
)
3748 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3752 if (tar
->Type
!= ST_ACTOR
) {
3755 Actor
* target
= ( Actor
* ) tar
;
3756 target
->SetBase(IE_FREESLOTS
, target
->GetBase(IE_FREESLOTS
)+parameters
->int0Parameter
);
3759 //the third parameter is a GemRB extension
3760 void GameScript::AddJournalEntry(Scriptable
* /*Sender*/, Action
* parameters
)
3762 core
->GetGame()->AddJournalEntry(parameters
->int0Parameter
, parameters
->int1Parameter
, parameters
->int2Parameter
);
3765 void GameScript::SetQuestDone(Scriptable
* /*Sender*/, Action
* parameters
)
3767 Game
*game
= core
->GetGame();
3768 game
->DeleteJournalEntry(parameters
->int0Parameter
);
3769 game
->AddJournalEntry(parameters
->int0Parameter
, IE_GAM_QUEST_DONE
, parameters
->int2Parameter
);
3773 void GameScript::RemoveJournalEntry(Scriptable
* /*Sender*/, Action
* parameters
)
3775 core
->GetGame()->DeleteJournalEntry(parameters
->int0Parameter
);
3778 void GameScript::SetInternal(Scriptable
* Sender
, Action
* parameters
)
3780 unsigned int idx
= parameters
->int0Parameter
;
3784 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3788 if (tar
->Type
!= ST_ACTOR
) {
3791 Actor
* target
= ( Actor
* ) tar
;
3792 //start of the internal stats
3793 target
->SetBase(IE_INTERNAL_0
+idx
, parameters
->int1Parameter
);
3796 void GameScript::IncInternal(Scriptable
* Sender
, Action
* parameters
)
3798 unsigned int idx
= parameters
->int0Parameter
;
3802 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3803 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3806 Actor
* target
= ( Actor
* ) tar
;
3807 //start of the internal stats
3808 target
->SetBase(IE_INTERNAL_0
+idx
,
3809 target
->GetBase(IE_INTERNAL_0
+idx
)+parameters
->int1Parameter
);
3812 void GameScript::DestroyAllEquipment(Scriptable
* Sender
, Action
* /*parameters*/)
3814 Inventory
*inv
=NULL
;
3816 switch (Sender
->Type
) {
3818 inv
= &(((Actor
*) Sender
)->inventory
);
3821 inv
= &(((Container
*) Sender
)->inventory
);
3826 inv
->DestroyItem("",0,(ieDword
) ~0); //destroy any and all
3830 void GameScript::DestroyItem(Scriptable
* Sender
, Action
* parameters
)
3832 Inventory
*inv
=NULL
;
3834 switch (Sender
->Type
) {
3836 inv
= &(((Actor
*) Sender
)->inventory
);
3839 inv
= &(((Container
*) Sender
)->inventory
);
3844 inv
->DestroyItem(parameters
->string0Parameter
,0,1); //destroy one (even indestructible?)
3848 //negative destroygold creates gold
3849 void GameScript::DestroyGold(Scriptable
* Sender
, Action
* parameters
)
3851 if (Sender
->Type
!=ST_ACTOR
)
3853 Actor
*act
=(Actor
*) Sender
;
3854 int max
=(int) act
->GetStat(IE_GOLD
);
3855 if (max
>parameters
->int0Parameter
) {
3856 max
=parameters
->int0Parameter
;
3858 act
->SetBase(IE_GOLD
, act
->GetBase(IE_GOLD
)-max
);
3861 void GameScript::DestroyPartyItem(Scriptable
* /*Sender*/, Action
* parameters
)
3863 Game
*game
= core
->GetGame();
3864 int i
= game
->GetPartySize(false);
3866 if (parameters
->int0Parameter
) {
3872 Inventory
*inv
= &(game
->GetPC( i
,false )->inventory
);
3873 int res
=inv
->DestroyItem(parameters
->string0Parameter
,0,count
);
3874 if ( (count
== 1) && res
) {
3880 /* this is a gemrb extension */
3881 void GameScript::DestroyPartyItemNum(Scriptable
* /*Sender*/, Action
* parameters
)
3883 Game
*game
= core
->GetGame();
3884 int i
= game
->GetPartySize(false);
3886 count
= parameters
->int0Parameter
;
3888 Inventory
*inv
= &(game
->GetPC( i
,false )->inventory
);
3889 count
-= inv
->DestroyItem(parameters
->string0Parameter
,0,count
);
3896 void GameScript::DestroyAllDestructableEquipment(Scriptable
* Sender
, Action
* /*parameters*/)
3898 Inventory
*inv
=NULL
;
3900 switch (Sender
->Type
) {
3902 inv
= &(((Actor
*) Sender
)->inventory
);
3905 inv
= &(((Container
*) Sender
)->inventory
);
3910 inv
->DestroyItem("", IE_INV_ITEM_DESTRUCTIBLE
, (ieDword
) ~0);
3914 void GameScript::SetApparentName(Scriptable
* Sender
, Action
* parameters
)
3916 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3917 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3920 Actor
* target
= ( Actor
* ) tar
;
3921 target
->SetName(parameters
->int0Parameter
,1);
3924 void GameScript::SetRegularName(Scriptable
* Sender
, Action
* parameters
)
3926 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3927 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3930 Actor
* target
= ( Actor
* ) tar
;
3931 target
->SetName(parameters
->int0Parameter
,2);
3934 /** this is a gemrb extension */
3935 void GameScript::UnloadArea(Scriptable
* /*Sender*/, Action
* parameters
)
3937 int map
=core
->GetGame()->FindMap(parameters
->string0Parameter
);
3939 core
->GetGame()->DelMap(map
, parameters
->int0Parameter
);
3943 void GameScript::Kill(Scriptable
* Sender
, Action
* parameters
)
3945 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3946 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3949 Actor
* target
= ( Actor
* ) tar
;
3950 target
->SetBase(IE_HITPOINTS
,(ieDword
) -100);
3953 void GameScript::SetGabber(Scriptable
* Sender
, Action
* parameters
)
3955 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3956 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3959 GameControl
* gc
= core
->GetGameControl();
3960 if (gc
->GetDialogueFlags()&DF_IN_DIALOG
) {
3961 gc
->speakerID
= ((Actor
*) tar
)->globalID
;
3963 printMessage("GameScript","Can't set gabber!",YELLOW
);
3967 void GameScript::ReputationSet(Scriptable
* /*Sender*/, Action
* parameters
)
3969 core
->GetGame()->SetReputation(parameters
->int0Parameter
*10);
3972 void GameScript::ReputationInc(Scriptable
* /*Sender*/, Action
* parameters
)
3974 Game
*game
= core
->GetGame();
3975 game
->SetReputation( (int) game
->Reputation
+ parameters
->int0Parameter
*10);
3978 void GameScript::FullHeal(Scriptable
* Sender
, Action
* parameters
)
3980 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3981 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3984 Actor
*scr
= (Actor
*) tar
;
3985 //0 means full healing
3986 //Heal() might contain curing of some conditions
3987 //if FullHeal doesn't do that, replace this with a SetBase
3988 //fullhealex might still be the curing action
3992 void GameScript::RemovePaladinHood(Scriptable
* Sender
, Action
* /*parameters*/)
3994 if (Sender
->Type
!=ST_ACTOR
) {
3997 Actor
*act
= (Actor
*) Sender
;
3998 act
->SetMCFlag(MC_FALLEN_PALADIN
, BM_OR
);
4001 void GameScript::RemoveRangerHood(Scriptable
* Sender
, Action
* /*parameters*/)
4003 if (Sender
->Type
!=ST_ACTOR
) {
4006 Actor
*act
= (Actor
*) Sender
;
4007 act
->SetMCFlag(MC_FALLEN_RANGER
, BM_OR
);
4010 void GameScript::RegainPaladinHood(Scriptable
* Sender
, Action
* /*parameters*/)
4012 if (Sender
->Type
!=ST_ACTOR
) {
4015 Actor
*act
= (Actor
*) Sender
;
4016 act
->SetMCFlag(MC_FALLEN_PALADIN
, BM_NAND
);
4019 void GameScript::RegainRangerHood(Scriptable
* Sender
, Action
* /*parameters*/)
4021 if (Sender
->Type
!=ST_ACTOR
) {
4024 Actor
*act
= (Actor
*) Sender
;
4025 act
->SetMCFlag(MC_FALLEN_RANGER
, BM_NAND
);
4028 //transfering item from Sender to target, target must be an actor
4029 //if target can't get it, it will be dropped at its feet
4030 //a container or an actor can take an item from someone
4031 void GameScript::GetItem(Scriptable
* Sender
, Action
* parameters
)
4033 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4034 MoveItemCore(tar
, Sender
, parameters
->string0Parameter
,0,0);
4037 //getting one single item
4038 void GameScript::TakePartyItem(Scriptable
* Sender
, Action
* parameters
)
4040 Game
*game
=core
->GetGame();
4041 int i
=game
->GetPartySize(false);
4043 int res
=MoveItemCore(game
->GetPC(i
,false), Sender
, parameters
->string0Parameter
,0,IE_INV_ITEM_UNSTEALABLE
);
4044 if (res
!=MIC_NOITEM
) return;
4048 //getting x single item
4049 void GameScript::TakePartyItemNum(Scriptable
* Sender
, Action
* parameters
)
4051 int count
= parameters
->int0Parameter
;
4052 Game
*game
=core
->GetGame();
4053 int i
=game
->GetPartySize(false);
4055 int res
=MoveItemCore(game
->GetPC(i
,false), Sender
, parameters
->string0Parameter
,0, IE_INV_ITEM_UNSTEALABLE
);
4056 if (res
== MIC_GOTITEM
) {
4064 void GameScript::TakePartyItemRange(Scriptable
* Sender
, Action
* parameters
)
4066 Game
*game
=core
->GetGame();
4067 int i
=game
->GetPartySize(false);
4069 Actor
*ac
= game
->GetPC(i
,false);
4070 if (Distance(Sender
, ac
)<MAX_OPERATING_DISTANCE
) {
4071 while (MoveItemCore(ac
, Sender
, parameters
->string0Parameter
,0,IE_INV_ITEM_UNSTEALABLE
)==MIC_GOTITEM
) { }
4076 void GameScript::TakePartyItemAll(Scriptable
* Sender
, Action
* parameters
)
4078 Game
*game
=core
->GetGame();
4079 int i
=game
->GetPartySize(false);
4081 while (MoveItemCore(game
->GetPC(i
,false), Sender
, parameters
->string0Parameter
,0, IE_INV_ITEM_UNSTEALABLE
)==MIC_GOTITEM
) { }
4085 //an actor can 'give' an item to a container or another actor
4086 void GameScript::GiveItem(Scriptable
*Sender
, Action
* parameters
)
4088 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4089 MoveItemCore(Sender
, tar
, parameters
->string0Parameter
,0,0);
4092 //this action creates an item in a container or a creature
4093 //if there is an object it works as GiveItemCreate
4094 //otherwise it creates the item on the Sender
4095 void GameScript::CreateItem(Scriptable
*Sender
, Action
* parameters
)
4098 if (parameters
->objects
[1]) {
4099 tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4109 myinv
= &((Actor
*) tar
)->inventory
;
4112 myinv
= &((Container
*) tar
)->inventory
;
4118 CREItem
*item
= new CREItem();
4119 CreateItemCore(item
, parameters
->string0Parameter
, parameters
->int0Parameter
, parameters
->int1Parameter
, parameters
->int2Parameter
);
4120 if (tar
->Type
==ST_CONTAINER
) {
4121 myinv
->AddItem(item
);
4123 if ( ASI_SUCCESS
!= myinv
->AddSlotItem(item
, SLOT_ONLYINVENTORY
)) {
4124 Map
*map
=tar
->GetCurrentArea();
4125 // drop it at my feet
4126 map
->AddItemToLocation(tar
->Pos
, item
);
4127 if (((Actor
*)tar
)->InParty
) core
->DisplayConstantString(STR_INVFULL_ITEMDROP
, 0xbcefbc);
4129 if (((Actor
*)tar
)->InParty
) core
->DisplayConstantString(STR_GOTITEM
, 0xbcefbc);
4134 void GameScript::CreateItemNumGlobal(Scriptable
*Sender
, Action
* parameters
)
4138 switch(Sender
->Type
) {
4140 myinv
= &((Actor
*) Sender
)->inventory
;
4143 myinv
= &((Container
*) Sender
)->inventory
;
4148 int value
= CheckVariable( Sender
, parameters
->string0Parameter
);
4149 CREItem
*item
= new CREItem();
4150 CreateItemCore(item
, parameters
->string1Parameter
, value
, 0, 0);
4151 if (Sender
->Type
==ST_CONTAINER
) {
4152 myinv
->AddItem(item
);
4154 if ( ASI_SUCCESS
!= myinv
->AddSlotItem(item
, SLOT_ONLYINVENTORY
)) {
4155 Map
*map
=Sender
->GetCurrentArea();
4156 // drop it at my feet
4157 map
->AddItemToLocation(Sender
->Pos
, item
);
4158 if (((Actor
*)Sender
)->InParty
) core
->DisplayConstantString(STR_INVFULL_ITEMDROP
, 0xbcefbc);
4160 if (((Actor
*)Sender
)->InParty
) core
->DisplayConstantString(STR_GOTITEM
, 0xbcefbc);
4165 void GameScript::TakeItemReplace(Scriptable
*Sender
, Action
* parameters
)
4167 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4168 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
4172 Actor
*scr
= (Actor
*) tar
;
4174 int slot
= scr
->inventory
.RemoveItem(parameters
->string1Parameter
, 0, &item
);
4176 item
= new CREItem();
4178 CreateItemCore(item
, parameters
->string0Parameter
, -1, 0, 0);
4179 if (ASI_SUCCESS
!= scr
->inventory
.AddSlotItem(item
,slot
)) {
4180 Map
*map
= scr
->GetCurrentArea();
4181 map
->AddItemToLocation(Sender
->Pos
, item
);
4185 //same as equipitem, but with additional slots parameter, and object to perform action
4186 void GameScript::XEquipItem(Scriptable
*Sender
, Action
* parameters
)
4188 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4190 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4193 Actor
*actor
= (Actor
*) tar
;
4194 int slot
= actor
->inventory
.FindItem(parameters
->string0Parameter
, 0);
4198 actor
->inventory
.EquipItem(slot
);
4199 actor
->ReinitQuickSlots();
4202 //iwd2 also has a flag for unequip (it might collide with original!)
4203 void GameScript::EquipItem(Scriptable
*Sender
, Action
* parameters
)
4205 if (Sender
->Type
!=ST_ACTOR
) {
4208 Actor
*actor
= (Actor
*) Sender
;
4209 int slot
= actor
->inventory
.FindItem(parameters
->string0Parameter
, IE_INV_ITEM_UNDROPPABLE
);
4216 if (parameters
->int0Parameter
) {
4217 //unequip item, and move it to the inventory
4218 slot2
= SLOT_ONLYINVENTORY
;
4220 //equip item if possible
4221 slot2
= SLOT_AUTOEQUIP
;
4223 CREItem
*si
= actor
->inventory
.RemoveItem(slot
);
4225 if (actor
->inventory
.AddSlotItem(si
, slot2
)==ASI_FAILED
) {
4226 Map
*map
= Sender
->GetCurrentArea();
4228 //drop item at the feet of the character instead of destroying it
4229 map
->AddItemToLocation(Sender
->Pos
, si
);
4235 actor
->ReinitQuickSlots();
4238 void GameScript::DropItem(Scriptable
*Sender
, Action
* parameters
)
4240 if (Sender
->Type
!=ST_ACTOR
) {
4241 Sender
->ReleaseCurrentAction();
4244 if (Distance(parameters
->pointParameter
, Sender
) > 10) {
4245 MoveNearerTo(Sender
, parameters
->pointParameter
, 10,0);
4248 Actor
*scr
= (Actor
*) Sender
;
4249 Map
*map
= Sender
->GetCurrentArea();
4251 if (parameters
->string0Parameter
[0]) {
4252 //dropping location isn't exactly our place, this is why i didn't use a simple DropItem
4253 scr
->inventory
.DropItemAtLocation(parameters
->string0Parameter
,
4254 0, map
, parameters
->pointParameter
);
4256 //this should be converted from scripting slot to physical slot
4257 scr
->inventory
.DropItemAtLocation(parameters
->int0Parameter
, 0, map
, parameters
->pointParameter
);
4260 Sender
->ReleaseCurrentAction();
4263 void GameScript::DropInventory(Scriptable
*Sender
, Action
* /*parameters*/)
4265 if (Sender
->Type
!=ST_ACTOR
) {
4268 Actor
*scr
= (Actor
*) Sender
;
4269 scr
->DropItem("",0);
4272 //this should work on containers!
4273 //using the same code for DropInventoryEXExclude
4274 void GameScript::DropInventoryEX(Scriptable
*Sender
, Action
* parameters
)
4276 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4280 Inventory
*inv
= NULL
;
4281 switch (Sender
->Type
) {
4283 inv
= &(((Actor
*) tar
)->inventory
);
4286 inv
= &(((Container
*) tar
)->inventory
);
4291 int x
= inv
->GetSlotCount();
4292 Map
*area
= tar
->GetCurrentArea();
4294 if (parameters
->string0Parameter
[0]) {
4295 const char *resref
= inv
->GetSlotItem(x
)->ItemResRef
;
4296 if (!strnicmp(parameters
->string0Parameter
, resref
, 8)) {
4300 inv
->DropItemAtLocation(x
, 0, area
, tar
->Pos
);
4305 void GameScript::GivePartyAllEquipment(Scriptable
*Sender
, Action
* /*parameters*/)
4307 if (Sender
->Type
!=ST_ACTOR
) {
4310 Game
*game
= core
->GetGame();
4311 // pick the first actor first
4312 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
4313 Actor
*tar
= game
->GetPC(i
,false);
4314 //don't try to give self, it would be an infinite loop
4315 if (tar
==(Actor
*) Sender
)
4317 while(MoveItemCore(Sender
, tar
, "",0,0)!=MIC_NOITEM
) { }
4321 //This is unsure, Plunder could be just handling ground piles and not dead actors
4322 void GameScript::Plunder(Scriptable
*Sender
, Action
* parameters
)
4324 if (Sender
->Type
!=ST_ACTOR
) {
4325 Sender
->ReleaseCurrentAction();
4328 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
4330 Sender
->ReleaseCurrentAction();
4334 //you must be joking
4336 Sender
->ReleaseCurrentAction();
4340 if (tar
->Type
== ST_ACTOR
) {
4341 Actor
*scr
= (Actor
*) tar
;
4342 //can plunder only dead actors
4343 if (! (scr
->BaseStats
[IE_STATE_ID
]&STATE_DEAD
) ) {
4344 Sender
->ReleaseCurrentAction();
4348 if (PersonalDistance(Sender
, tar
)>MAX_OPERATING_DISTANCE
) {
4349 MoveNearerTo(Sender
, tar
->Pos
, MAX_OPERATING_DISTANCE
,0);
4352 //move all movable item from the target to the Sender
4353 //the rest will be dropped at the feet of Sender
4354 while(MoveItemCore(tar
, Sender
, "",0,0)!=MIC_NOITEM
) { }
4355 Sender
->ReleaseCurrentAction();
4358 void GameScript::MoveInventory(Scriptable
*Sender
, Action
* parameters
)
4360 Scriptable
* src
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4361 if (!src
|| src
->Type
!=ST_ACTOR
) {
4364 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[2] );
4365 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4368 //don't try to move to self, it would create infinite loop
4371 //move all movable item from the target to the Sender
4372 //the rest will be dropped at the feet of Sender
4373 while(MoveItemCore(src
, tar
, "",0,0)!=MIC_NOITEM
) { }
4376 void GameScript::PickPockets(Scriptable
*Sender
, Action
* parameters
)
4378 if (Sender
->Type
!=ST_ACTOR
) {
4379 Sender
->ReleaseCurrentAction();
4382 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
4383 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4384 Sender
->ReleaseCurrentAction();
4387 Actor
*snd
= (Actor
*) Sender
;
4388 Actor
*scr
= (Actor
*) tar
;
4389 //for PP one must go REALLY close
4391 if (PersonalDistance(Sender
, tar
)>10 ) {
4392 MoveNearerTo(Sender
, tar
, 10);
4396 if (scr
->LastTarget
) {
4397 core
->DisplayConstantString(STR_PICKPOCKET_EVIL
,0xffffff);
4398 Sender
->ReleaseCurrentAction();
4402 int skill
= snd
->GetStat(IE_PICKPOCKET
) - scr
->GetStat(IE_PICKPOCKET
);
4403 skill
+=core
->Roll(1,100,1);
4406 core
->DisplayConstantString(STR_PICKPOCKET_FAIL
,0xffffff);
4407 tar
->LastOpenFailed
=snd
->GetID();
4408 Sender
->ReleaseCurrentAction();
4412 //find a candidate item for stealing (unstealable items are noticed)
4413 int ret
= MoveItemCore(tar
, Sender
, "", IE_INV_ITEM_UNSTEALABLE
, IE_INV_ITEM_STOLEN
);
4414 if (ret
==MIC_NOITEM
) {
4417 if (scr
->GetStat(IE_GOLD
)>0) {
4418 money
=RandomNumValue
%(scr
->GetStat(IE_GOLD
)+1);
4422 core
->DisplayConstantString(STR_PICKPOCKET_NONE
,0xffffff);
4423 Sender
->ReleaseCurrentAction();
4426 CREItem
*item
= new CREItem();
4427 CreateItemCore(item
, core
->GoldResRef
, money
, 0, 0);
4428 if ( ASI_SUCCESS
== snd
->inventory
.AddSlotItem(item
, SLOT_ONLYINVENTORY
)) {
4429 scr
->SetBase(IE_GOLD
,scr
->GetBase(IE_GOLD
)-money
);
4431 Map
*map
=Sender
->GetCurrentArea();
4432 // drop it at my feet
4433 map
->AddItemToLocation(Sender
->Pos
, item
);
4434 if (((Actor
*)Sender
)->InParty
) core
->DisplayConstantString(STR_INVFULL_ITEMDROP
, 0xbcefbc);
4435 Sender
->ReleaseCurrentAction();
4440 core
->DisplayConstantString(STR_PICKPOCKET_DONE
,0xffffff);
4441 DisplayStringCore(snd
, VB_PP_SUCC
, DS_CONSOLE
|DS_CONST
);
4442 Sender
->ReleaseCurrentAction();
4445 void GameScript::TakeItemList(Scriptable
* Sender
, Action
* parameters
)
4447 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4448 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4451 AutoTable
tab(parameters
->string0Parameter
);
4456 int rows
= tab
->GetRowCount();
4457 for (int i
=0;i
<rows
;i
++) {
4458 MoveItemCore(tar
, Sender
, tab
->QueryField(i
,0), 0, IE_INV_ITEM_UNSTEALABLE
);
4462 void GameScript::TakeItemListParty(Scriptable
* Sender
, Action
* parameters
)
4464 AutoTable
tab(parameters
->string0Parameter
);
4468 Game
*game
= core
->GetGame();
4469 int rows
= tab
->GetRowCount();
4470 for (int i
=0;i
<rows
;i
++) {
4471 int j
= game
->GetPartySize(false);
4473 Actor
*tar
= game
->GetPC(j
, false);
4474 MoveItemCore(tar
, Sender
, tab
->QueryField(i
,0), 0, IE_INV_ITEM_UNSTEALABLE
);
4479 void GameScript::TakeItemListPartyNum(Scriptable
* Sender
, Action
* parameters
)
4481 AutoTable
tab(parameters
->string0Parameter
);
4485 Game
*game
= core
->GetGame();
4486 int rows
= tab
->GetRowCount();
4487 for (int i
=0;i
<rows
;i
++) {
4488 int count
= parameters
->int0Parameter
;
4489 int j
= game
->GetPartySize(false);
4491 Actor
*tar
= game
->GetPC(j
, false);
4492 int res
=MoveItemCore(tar
, Sender
, tab
->QueryField(i
,0), 0, IE_INV_ITEM_UNSTEALABLE
);
4493 if (res
==MIC_GOTITEM
) {
4503 void GameScript::SetRestEncounterProbabilityDay(Scriptable
* Sender
, Action
* parameters
)
4505 Map
*map
=Sender
->GetCurrentArea();
4506 map
->RestHeader
.DayChance
= (ieWord
) parameters
->int0Parameter
;
4509 void GameScript::SetRestEncounterProbabilityNight(Scriptable
* Sender
, Action
* parameters
)
4511 Map
*map
=Sender
->GetCurrentArea();
4512 map
->RestHeader
.NightChance
= (ieWord
) parameters
->int0Parameter
;
4516 void GameScript::SetRestEncounterChance(Scriptable
* Sender
, Action
* parameters
)
4518 Map
*map
=Sender
->GetCurrentArea();
4519 map
->RestHeader
.DayChance
= (ieWord
) parameters
->int0Parameter
;
4520 map
->RestHeader
.NightChance
= (ieWord
) parameters
->int1Parameter
;
4523 //easily hardcoded end sequence
4524 void GameScript::EndCredits(Scriptable
* /*Sender*/, Action
* /*parameters*/)
4526 core
->PlayMovie("credits");
4529 //easily hardcoded end sequence
4530 void GameScript::ExpansionEndCredits(Scriptable
* /*Sender*/, Action
* /*parameters*/)
4532 core
->PlayMovie("ecredit");
4535 //always quits game, but based on game it can play end animation, or display
4538 //QuitGame (play two of 3 movies in PST, display death screen with strref)
4539 //EndGame (display death screen with strref)
4540 void GameScript::QuitGame(Scriptable
* Sender
, Action
* parameters
)
4542 ClearAllActions(Sender
, parameters
);
4543 core
->GetDictionary()->SetAt("QuitGame1", (ieDword
) parameters
->int0Parameter
);
4544 core
->GetDictionary()->SetAt("QuitGame2", (ieDword
) parameters
->int1Parameter
);
4545 core
->GetDictionary()->SetAt("QuitGame3", (ieDword
) parameters
->int2Parameter
);
4546 core
->SetNextScript("QuitGame");
4549 void GameScript::StopMoving(Scriptable
* Sender
, Action
* /*parameters*/)
4551 if (Sender
->Type
!=ST_ACTOR
) {
4554 Actor
*actor
= (Actor
*) Sender
;
4558 void GameScript::ApplyDamage(Scriptable
* Sender
, Action
* parameters
)
4562 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4563 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4566 damagee
= (Actor
*) tar
;
4567 if (Sender
->Type
==ST_ACTOR
) {
4568 damager
=(Actor
*) Sender
;
4572 damagee
->Damage(parameters
->int0Parameter
, parameters
->int1Parameter
, damager
);
4575 void GameScript::ApplyDamagePercent(Scriptable
* Sender
, Action
* parameters
)
4579 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4580 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4583 damagee
= (Actor
*) tar
;
4584 if (Sender
->Type
==ST_ACTOR
) {
4585 damager
=(Actor
*) Sender
;
4589 damagee
->Damage(damagee
->GetBase(IE_HITPOINTS
)*parameters
->int0Parameter
/100, parameters
->int1Parameter
, damager
);
4592 void GameScript::Damage(Scriptable
* Sender
, Action
* parameters
)
4596 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4597 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4600 damagee
= (Actor
*) tar
;
4601 if (Sender
->Type
==ST_ACTOR
) {
4602 damager
=(Actor
*) Sender
;
4606 int damage
= damagee
->LuckyRoll( (parameters
->int1Parameter
>>12)&15, (parameters
->int1Parameter
>>4)&255, parameters
->int1Parameter
&15, 0, 1, damager
);
4607 int type
=MOD_ADDITIVE
;
4608 switch(parameters
->int0Parameter
) {
4619 damagee
->Damage( damage
, type
, damager
);
4622 void GameScript::SetHomeLocation(Scriptable* Sender, Action* parameters)
4624 Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] );
4625 if (!tar || tar->Type!=ST_ACTOR) {
4628 Movable *movable = (Movable *) tar; //not actor, though it is the only moveable
4629 movable->Destination = parameters->pointParameter;
4630 //no movement should be started here, i think
4634 void GameScript::SetMasterArea(Scriptable
* /*Sender*/, Action
* parameters
)
4636 core
->GetGame()->SetMasterArea(parameters
->string0Parameter
);
4639 void GameScript::Berserk(Scriptable
* Sender
, Action
* /*parameters*/)
4641 if (Sender
->Type
!=ST_ACTOR
) {
4644 Actor
*act
= (Actor
*) Sender
;
4645 act
->SetBaseBit(IE_STATE_ID
, STATE_BERSERK
, true);
4648 void GameScript::Panic(Scriptable
* Sender
, Action
* /*parameters*/)
4650 if (Sender
->Type
!=ST_ACTOR
) {
4653 Actor
*act
= (Actor
*) Sender
;
4657 /* as of now: removes panic and berserk */
4658 void GameScript::Calm(Scriptable
* Sender
, Action
* /*parameters*/)
4660 if (Sender
->Type
!=ST_ACTOR
) {
4663 Actor
*act
= (Actor
*) Sender
;
4664 act
->SetBaseBit(IE_STATE_ID
, STATE_BERSERK
|STATE_PANIC
, false);
4667 void GameScript::RevealAreaOnMap(Scriptable
* /*Sender*/, Action
* parameters
)
4669 WorldMap
*worldmap
= core
->GetWorldMap();
4671 printf("Can't find worldmap!\n");
4674 // WMP_ENTRY_ADJACENT because otherwise revealed bg2 areas are unreachable from city gates
4675 worldmap
->SetAreaStatus(parameters
->string0Parameter
, WMP_ENTRY_VISIBLE
|WMP_ENTRY_ADJACENT
, BM_OR
);
4676 core
->DisplayConstantString(STR_WORLDMAPCHANGE
, 0xc8ffc8);
4679 void GameScript::HideAreaOnMap( Scriptable
* /*Sender*/, Action
* parameters
)
4681 WorldMap
*worldmap
= core
->GetWorldMap();
4683 printf("Can't find worldmap!\n");
4686 // WMP_ENTRY_ADJACENT because otherwise revealed bg2 areas are unreachable from city gates
4687 worldmap
->SetAreaStatus(parameters
->string0Parameter
, WMP_ENTRY_VISIBLE
|WMP_ENTRY_ADJACENT
, BM_NAND
);
4690 void GameScript::SendTrigger(Scriptable
* Sender
, Action
* parameters
)
4692 Scriptable
*tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4696 tar
->TriggerID
=parameters
->int0Parameter
;
4699 void GameScript::Shout( Scriptable
* Sender
, Action
* parameters
)
4701 if (Sender
->Type
!=ST_ACTOR
) {
4704 //according to IESDP silenced creatures cannot use shout
4705 Actor
*actor
= (Actor
*) Sender
;
4706 if (actor
->GetStat( IE_STATE_ID
) & STATE_SILENCED
) {
4709 Map
*map
=Sender
->GetCurrentArea();
4710 //max. shouting distance, please adjust it if you know better
4711 map
->Shout(actor
, parameters
->int0Parameter
, MAX_TRAVELING_DISTANCE
);
4714 void GameScript::GlobalShout( Scriptable
* Sender
, Action
* parameters
)
4716 if (Sender
->Type
!=ST_ACTOR
) {
4719 //according to IESDP silenced creatures cannot use shout
4720 Actor
*actor
= (Actor
*) Sender
;
4721 if (actor
->GetStat( IE_STATE_ID
) & STATE_SILENCED
) {
4724 Map
*map
=Sender
->GetCurrentArea();
4725 // 0 means unlimited shout distance
4726 map
->Shout(actor
, parameters
->int0Parameter
, 0);
4729 void GameScript::Help( Scriptable
* Sender
, Action
* /*parameters*/)
4731 if (Sender
->Type
!=ST_ACTOR
) {
4734 Map
*map
=Sender
->GetCurrentArea();
4735 map
->Shout((Actor
*) Sender
, 0, 40);
4738 void GameScript::GiveOrder(Scriptable
* Sender
, Action
* parameters
)
4740 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4742 tar
->LastOrderer
= Sender
->GetGlobalID();
4743 tar
->LastOrder
= parameters
->int0Parameter
;
4747 void GameScript::AddMapnote( Scriptable
* Sender
, Action
* parameters
)
4749 Map
*map
=Sender
->GetCurrentArea();
4750 char *str
= core
->GetString( parameters
->int0Parameter
, 0);
4751 map
->AddMapNote(parameters
->pointParameter
, parameters
->int1Parameter
, str
, parameters
->int0Parameter
);
4754 void GameScript::RemoveMapnote( Scriptable
* Sender
, Action
* parameters
)
4756 Map
*map
=Sender
->GetCurrentArea();
4757 map
->RemoveMapNote(parameters
->pointParameter
);
4760 void GameScript::AttackOneRound( Scriptable
* Sender
, Action
* parameters
)
4762 if (Sender
->Type
!= ST_ACTOR
) {
4763 Sender
->ReleaseCurrentAction();
4766 //using auto target!
4768 if (!parameters
->objects
[1]) {
4769 GameControl
*gc
= core
->GetGameControl();
4770 tar
= gc
->GetTarget();
4772 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4774 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4775 Sender
->ReleaseCurrentAction();
4779 //actor is already incapable of attack
4780 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4781 Sender
->ReleaseCurrentAction();
4785 if (!Sender
->CurrentActionState
) {
4786 Sender
->CurrentActionState
= ROUND_SIZE
;
4789 AttackCore(Sender
, tar
, 0);
4791 if (Sender
->CurrentActionState
== 1) {
4792 //this is the LastDisarmFailed field, but this is an actor
4793 //Sender->LastTarget = 0;
4794 Sender
->ReleaseCurrentAction();
4796 Sender
->CurrentActionState
--;
4800 void GameScript::RunningAttackNoSound( Scriptable
* Sender
, Action
* parameters
)
4802 if (Sender
->Type
!= ST_ACTOR
) {
4803 Sender
->ReleaseCurrentAction();
4806 //using auto target!
4808 if (!parameters
->objects
[1]) {
4809 GameControl
*gc
= core
->GetGameControl();
4810 tar
= gc
->GetTarget();
4812 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4814 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4815 Sender
->ReleaseCurrentAction();
4819 //actor is already incapable of attack
4820 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4821 Sender
->ReleaseCurrentAction();
4825 AttackCore(Sender
, tar
, AC_NO_SOUND
|AC_RUNNING
);
4828 void GameScript::AttackNoSound( Scriptable
* Sender
, Action
* parameters
)
4830 if (Sender
->Type
!= ST_ACTOR
) {
4831 Sender
->ReleaseCurrentAction();
4834 //using auto target!
4836 if (!parameters
->objects
[1]) {
4837 GameControl
*gc
= core
->GetGameControl();
4838 tar
= gc
->GetTarget();
4840 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4842 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4843 Sender
->ReleaseCurrentAction();
4847 //actor is already incapable of attack
4848 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4849 Sender
->ReleaseCurrentAction();
4853 AttackCore(Sender
, tar
, AC_NO_SOUND
);
4856 void GameScript::RunningAttack( Scriptable
* Sender
, Action
* parameters
)
4858 if (Sender
->Type
!= ST_ACTOR
) {
4859 Sender
->ReleaseCurrentAction();
4862 //using auto target!
4864 if (!parameters
->objects
[1]) {
4865 GameControl
*gc
= core
->GetGameControl();
4866 tar
= gc
->GetTarget();
4868 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4870 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4871 Sender
->ReleaseCurrentAction();
4875 //actor is already incapable of attack
4876 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4877 Sender
->ReleaseCurrentAction();
4881 AttackCore(Sender
, tar
, AC_RUNNING
);
4884 void GameScript::Attack( Scriptable
* Sender
, Action
* parameters
)
4886 if (Sender
->Type
!= ST_ACTOR
) {
4887 Sender
->ReleaseCurrentAction();
4890 //using auto target!
4892 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4894 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) || tar
== Sender
) {
4895 Sender
->ReleaseCurrentAction();
4899 //actor is already incapable of attack
4900 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4901 Sender
->ReleaseCurrentAction();
4905 AttackCore(Sender
, tar
, 0);
4908 void GameScript::ForceAttack( Scriptable
* Sender
, Action
* parameters
)
4910 Scriptable
* scr
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4911 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
4914 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[2], GA_NO_DEAD
);
4915 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4918 //this is a hack, we use a gui variable for our own hideous reasons?
4919 if (tar
->Type
==ST_ACTOR
) {
4920 GameControl
*gc
= core
->GetGameControl();
4922 //saving the target object ID from the gui variable
4924 strncpy(Tmp
,"NIDSpecial3()",sizeof(Tmp
) );
4925 scr
->AddAction( GenerateActionDirect(Tmp
, (Actor
*) tar
) );
4929 snprintf(Tmp
, sizeof(Tmp
), "BashDoor(%s)", tar
->GetScriptName());
4930 scr
->AddAction ( GenerateAction(Tmp
) );
4934 void GameScript::AttackReevaluate( Scriptable
* Sender
, Action
* parameters
)
4936 if (Sender
->Type
!= ST_ACTOR
) {
4937 Sender
->ReleaseCurrentAction();
4941 if (!Sender
->CurrentActionState
) {
4942 Sender
->CurrentActionState
= parameters
->int0Parameter
;
4943 // TODO: reevaluate target (set CurrentActionTarget to 0) if we are not actively in combat
4947 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4948 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4949 Sender
->ReleaseCurrentAction();
4953 //actor is already incapable of attack
4954 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4955 Sender
->ReleaseCurrentAction();
4959 AttackCore(Sender
, tar
, 0);
4961 Sender
->CurrentActionState
--;
4964 void GameScript::Explore( Scriptable
* Sender
, Action
* /*parameters*/)
4966 Sender
->GetCurrentArea( )->Explore(-1);
4969 void GameScript::UndoExplore( Scriptable
* Sender
, Action
* /*parameters*/)
4971 Sender
->GetCurrentArea( )->Explore(0);
4974 void GameScript::ExploreMapChunk( Scriptable
* Sender
, Action
* parameters
)
4976 Map
*map
= Sender
->GetCurrentArea();
4978 There is a mode flag in int1Parameter, but i don't know what is it,
4979 our implementation uses it for LOS=1, or no LOS=0
4980 ExploreMapChunk will reveal both visibility/explored map, but the
4981 visibility will fade in the next update cycle (which is quite frequent)
4983 map
->ExploreMapChunk(parameters
->pointParameter
, parameters
->int0Parameter
, parameters
->int1Parameter
);
4986 void GameScript::StartStore( Scriptable
* Sender
, Action
* parameters
)
4988 if (core
->GetCurrentStore() ) {
4991 core
->SetCurrentStore( parameters
->string0Parameter
, Sender
->GetScriptName());
4992 //core->GetGUIScriptEngine()->RunFunction( "OpenStoreWindow" );
4993 core
->SetEventFlag(EF_OPENSTORE
);
4994 //sorry, i have absolutely no idea when i should do this :)
4995 Sender
->ReleaseCurrentAction();
4998 //The integer parameter is a GemRB extension, if set to 1, the player
4999 //gains experience for learning the spell
5000 void GameScript::AddSpecialAbility( Scriptable
* Sender
, Action
* parameters
)
5002 if (Sender
->Type
!= ST_ACTOR
) {
5005 Actor
*actor
= (Actor
*) Sender
;
5006 actor
->LearnSpell (parameters
->string0Parameter
, parameters
->int0Parameter
|LS_MEMO
|LS_LEARN
);
5007 core
->SetEventFlag(EF_ACTION
);
5010 void GameScript::RemoveSpell( Scriptable
* Sender
, Action
* parameters
)
5012 if (Sender
->Type
!=ST_ACTOR
) {
5015 Actor
*actor
= (Actor
*) Sender
;
5016 if (parameters
->string0Parameter
[0]) {
5017 actor
->spellbook
.RemoveSpell(parameters
->string0Parameter
);
5020 actor
->spellbook
.RemoveSpell(parameters
->int0Parameter
);
5023 void GameScript::SetScriptName( Scriptable
* Sender
, Action
* parameters
)
5025 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5026 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5029 tar
->SetScriptName(parameters
->string0Parameter
);
5033 //advance time with a constant
5034 //This is in seconds according to IESDP
5035 void GameScript::AdvanceTime(Scriptable
* /*Sender*/, Action
* parameters
)
5037 core
->GetGame()->AdvanceTime(parameters
->int0Parameter
*1000/AI_UPDATE_TIME
);
5040 //advance at least one day, then stop at next day/dusk/night/morning
5041 //oops, not TimeODay is used but Time (this means we got hours)
5042 //i'm not sure if we should add a whole day either, needs more research
5043 void GameScript::DayNight(Scriptable
* /*Sender*/, Action
* parameters
)
5045 // first, calculate the current number of hours.
5046 int padding
= ((core
->GetGame()->GameTime
/ AI_UPDATE_TIME
) % 7200) / 300;
5047 // then, calculate the offset (in hours) required to take us to the desired hour.
5048 padding
= (24 + parameters
->int0Parameter
- padding
) % 24;
5049 // then, advance one day (7200), plus the desired number of hours.
5050 core
->GetGame()->AdvanceTime(AI_UPDATE_TIME
*(7200 + padding
*300));
5053 //implement pst style parameters:
5054 //suggested dream - unused
5055 //if suggested dream is 0, then area flags determine the 'movie'
5056 //hp - number of hps healed
5057 //renting - crashes pst, we simply ignore it
5058 void GameScript::RestParty(Scriptable
* Sender
, Action
* parameters
)
5060 Game
*game
= core
->GetGame();
5061 game
->RestParty(REST_NOAREA
|REST_NOMOVE
|REST_NOCRITTER
, parameters
->int0Parameter
, parameters
->int1Parameter
);
5062 Sender
->ReleaseCurrentAction();
5065 //doesn't advance game time, just refreshes spells of target
5066 //this is a non-blocking action
5067 void GameScript::Rest(Scriptable
* Sender
, Action
* /*parameters*/)
5069 if (Sender
->Type
!=ST_ACTOR
) {
5072 Actor
*actor
= (Actor
*) Sender
;
5073 actor
->spellbook
.ChargeAllSpells();
5074 //check if this should be a full heal
5076 actor
->fxqueue
.RemoveExpiredEffects(0xffffffff);
5079 //doesn't advance game time (unsure), just refreshes spells of target
5080 void GameScript::RestNoSpells(Scriptable
* Sender
, Action
* /*parameters*/)
5082 if (Sender
->Type
!=ST_ACTOR
) {
5085 Actor
*actor
= (Actor
*) Sender
;
5086 //check if this should be a full heal
5088 actor
->fxqueue
.RemoveExpiredEffects(0xffffffff);
5091 //this is most likely advances time
5092 void GameScript::RestUntilHealed(Scriptable
* Sender
, Action
* /*parameters*/)
5094 if (Sender
->Type
!=ST_ACTOR
) {
5097 Actor
*actor
= (Actor
*) Sender
;
5099 //not sure if this should remove timed effects
5100 //more like execute them hour by hour :>
5104 //removes all delayed/duration/semi permanent effects (like a ctrl-r)
5105 void GameScript::ClearPartyEffects(Scriptable
* /*Sender*/, Action
* /*parameters*/)
5107 Game
*game
= core
->GetGame();
5108 int i
= game
->GetPartySize(false);
5110 Actor
*tar
= game
->GetPC(i
, false);
5111 tar
->fxqueue
.RemoveExpiredEffects(0xffffffff);
5115 //iwd2 removes effects from a single sprite
5116 void GameScript::ClearSpriteEffects(Scriptable
* Sender
, Action
* parameters
)
5118 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5119 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5122 Actor
*actor
= (Actor
*) tar
;
5123 actor
->fxqueue
.RemoveExpiredEffects(0xffffffff);
5126 //IWD2 special, can mark only actors, hope it is enough
5127 void GameScript::MarkObject(Scriptable
* Sender
, Action
* parameters
)
5129 if (Sender
->Type
!= ST_ACTOR
) {
5132 //unsure, could mark dead objects?
5133 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
5134 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5137 Actor
*actor
= (Actor
*) Sender
;
5138 actor
->LastMarked
= ((Actor
*) tar
)->GetID();
5139 //if this doesn't modify LastSeen, then remove this line
5140 actor
->LastSeen
= actor
->LastMarked
;
5143 void GameScript::SetDialogueRange(Scriptable
* Sender
, Action
* parameters
)
5145 if (Sender
->Type
!= ST_ACTOR
) {
5148 Actor
*actor
= (Actor
*) Sender
;
5149 actor
->SetBase( IE_DIALOGRANGE
, parameters
->int0Parameter
);
5152 void GameScript::SetGlobalTint(Scriptable
* /*Sender*/, Action
* parameters
)
5154 core
->GetVideoDriver()->SetFadeColor(parameters
->int0Parameter
, parameters
->int1Parameter
, parameters
->int2Parameter
);
5157 void GameScript::SetArmourLevel(Scriptable
* Sender
, Action
* parameters
)
5159 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5160 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5163 Actor
*actor
= (Actor
*) Sender
;
5164 actor
->SetBase( IE_ARMOR_TYPE
, parameters
->int0Parameter
);
5167 void GameScript::RandomWalk(Scriptable
* Sender
, Action
* /*parameters*/)
5169 if (Sender
->Type
!= ST_ACTOR
) {
5170 Sender
->ReleaseCurrentAction();
5173 Actor
* actor
= ( Actor
* ) Sender
;
5174 actor
->RandomWalk( true, false );
5175 Sender
->ReleaseCurrentAction();
5178 void GameScript::RandomRun(Scriptable
* Sender
, Action
* /*parameters*/)
5180 if (Sender
->Type
!= ST_ACTOR
) {
5181 Sender
->ReleaseCurrentAction();
5184 Actor
* actor
= ( Actor
* ) Sender
;
5185 actor
->RandomWalk( true, true );
5186 Sender
->ReleaseCurrentAction();
5189 void GameScript::RandomWalkContinuous(Scriptable
* Sender
, Action
* /*parameters*/)
5191 if (Sender
->Type
!= ST_ACTOR
) {
5192 Sender
->ReleaseCurrentAction();
5195 Actor
* actor
= ( Actor
* ) Sender
;
5196 actor
->RandomWalk( false, false );
5199 void GameScript::RandomFly(Scriptable
* Sender
, Action
* /*parameters*/)
5201 if (Sender
->Type
!= ST_ACTOR
) {
5202 Sender
->ReleaseCurrentAction();
5205 Actor
* actor
= ( Actor
* ) Sender
;
5208 actor
->SetOrientation(actor
->GetOrientation()-1, false);
5210 actor
->SetOrientation(actor
->GetOrientation()+1, false);
5212 //fly in this direction for 5 steps
5213 actor
->MoveLine(5, GL_PASS
, actor
->GetOrientation() );
5214 //readding the action to the end of the queue
5215 //Sender->AddAction( parameters );
5216 //Sender->ReleaseCurrentAction();
5219 //UseContainer uses the predefined target (like Nidspecial1 dialog hack)
5220 void GameScript::UseContainer(Scriptable
* Sender
, Action
* /*parameters*/)
5222 if (Sender
->Type
!= ST_ACTOR
) {
5223 Sender
->ReleaseCurrentAction();
5226 Actor
*actor
= (Actor
*)Sender
;
5227 Container
*container
= core
->GetCurrentContainer();
5229 printMessage("GameScript","No container selected!", YELLOW
);
5230 Sender
->ReleaseCurrentAction();
5234 ieDword distance
= PersonalDistance(Sender
, container
);
5235 ieDword needed
= MAX_OPERATING_DISTANCE
;
5236 if (container
->Type
==IE_CONTAINER_PILE
) {
5237 needed
= 0; // less than a search square (width)
5239 if (distance
<=needed
)
5241 //check if the container is unlocked
5242 if (!container
->TryUnlock(actor
)) {
5243 //playsound can't open container
5244 //display string, etc
5245 core
->DisplayConstantString(STR_CONTLOCKED
,0xd7d7be,container
);
5246 Sender
->ReleaseCurrentAction();
5249 Actor
*actor
= (Actor
*)Sender
;
5250 actor
->SetModal(MS_NONE
);
5251 container
->TriggerTrap(0, actor
->GetID());
5252 core
->SetCurrentContainer(actor
, container
, true);
5253 Sender
->ReleaseCurrentAction();
5256 MoveNearerTo(Sender
, container
, needed
);
5259 //call the usecontainer action in target (not used)
5260 void GameScript::ForceUseContainer(Scriptable
* Sender
, Action
* parameters
)
5262 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5263 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
5264 Sender
->ReleaseCurrentAction(); //why blocking???
5268 sprintf( Tmp
, "UseContainer()");
5269 Action
*newaction
= GenerateAction(Tmp
);
5270 tar
->AddActionInFront(newaction
);
5271 Sender
->ReleaseCurrentAction(); //why blocking???
5274 //these actions directly manipulate a game variable (as the original engine)
5275 void GameScript::SetMazeEasier(Scriptable
* Sender
, Action
* /*parameters*/)
5277 int value
= CheckVariable( Sender
, "MAZEDIFFICULTY","GLOBAL");
5279 SetVariable(Sender
, "MAZEDIFFICULTY", "GLOBAL", value
-1);
5283 void GameScript::SetMazeHarder(Scriptable
* Sender
, Action
* /*parameters*/)
5285 int value
= CheckVariable( Sender
, "MAZEDIFFICULTY","GLOBAL");
5287 SetVariable(Sender
, "MAZEDIFFICULTY", "GLOBAL", value
+1);
5291 void GameScript::StartRainNow(Scriptable
* /*Sender*/, Action
* /*parameters*/)
5293 core
->GetGame()->StartRainOrSnow( false, WB_RAIN
|WB_LIGHTNING
);
5296 void GameScript::Weather(Scriptable
* /*Sender*/, Action
* parameters
)
5298 Game
*game
= core
->GetGame();
5299 switch(parameters
->int0Parameter
& WB_FOG
) {
5301 game
->StartRainOrSnow( false, 0);
5304 game
->StartRainOrSnow( true, WB_RAIN
|WB_LIGHTNING
);
5307 game
->StartRainOrSnow( true, WB_SNOW
);
5310 game
->StartRainOrSnow( true, WB_FOG
);
5315 void GameScript::CopyGroundPilesTo(Scriptable
* Sender
, Action
* parameters
)
5317 Map
*map
= Sender
->GetCurrentArea();
5318 Map
*othermap
= core
->GetGame()->GetMap( parameters
->string0Parameter
, false );
5322 map
->CopyGroundPiles( othermap
, parameters
->pointParameter
);
5326 void GameScript::PlayBardSong(Scriptable
* Sender
, Action
* /*parameters*/)
5328 if (Sender
->Type
!=ST_ACTOR
) {
5331 //actually this one must use int0Parameter to set a bardsong
5332 Actor
*actor
= (Actor
*) Sender
;
5333 actor
->SetModal( MS_BATTLESONG
);
5336 void GameScript::BattleSong(Scriptable
* Sender
, Action
* /*parameters*/)
5338 if (Sender
->Type
!=ST_ACTOR
) {
5341 Actor
*actor
= (Actor
*) Sender
;
5342 actor
->SetModal( MS_BATTLESONG
);
5345 void GameScript::FindTraps(Scriptable
* Sender
, Action
* /*parameters*/)
5347 if (Sender
->Type
!=ST_ACTOR
) {
5350 Actor
*actor
= (Actor
*) Sender
;
5351 actor
->SetModal( MS_DETECTTRAPS
);
5354 void GameScript::Hide(Scriptable
* Sender
, Action
* /*parameters*/)
5356 if (Sender
->Type
!=ST_ACTOR
) {
5359 Actor
*actor
= (Actor
*) Sender
;
5361 if (actor
->TryToHide()) {
5362 actor
->SetModal(MS_STEALTH
);
5364 //TODO: expiry isn't instant (skill based transition?)
5368 void GameScript::Turn(Scriptable
* Sender
, Action
* /*parameters*/)
5370 if (Sender
->Type
!=ST_ACTOR
) {
5373 Actor
*actor
= (Actor
*) Sender
;
5375 if (actor
->Modified
[IE_DISABLEDBUTTON
] & (1<<ACT_TURN
)) {
5379 int skill
= actor
->GetStat(IE_TURNUNDEADLEVEL
);
5380 if (skill
< 1) return;
5382 actor
->SetModal(MS_TURNUNDEAD
);
5386 void GameScript::TurnAMT(Scriptable
* Sender
, Action
* parameters
)
5388 if (Sender
->Type
!=ST_ACTOR
) {
5389 Sender
->ReleaseCurrentAction();
5392 Actor
*actor
= (Actor
*) Sender
;
5393 actor
->SetOrientation(actor
->GetOrientation()+parameters
->int0Parameter
, true);
5394 actor
->SetWait( 1 );
5395 Sender
->ReleaseCurrentAction(); // todo, blocking?
5398 void GameScript::RandomTurn(Scriptable
* Sender
, Action
* /*parameters*/)
5400 if (Sender
->Type
!=ST_ACTOR
) {
5401 Sender
->ReleaseCurrentAction();
5404 Actor
*actor
= (Actor
*) Sender
;
5405 actor
->SetOrientation(rand() % MAX_ORIENT
, true);
5406 actor
->SetWait( 1 );
5407 Sender
->ReleaseCurrentAction(); // todo, blocking?
5410 void GameScript::AttachTransitionToDoor(Scriptable
* Sender
, Action
* parameters
)
5412 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5413 if (!tar
|| tar
->Type
!= ST_DOOR
) {
5416 Door
* door
= ( Door
* ) tar
;
5417 strnspccpy(door
->LinkedInfo
, parameters
->string0Parameter
, 32);
5420 /*getting a handle of a temporary actor resource to copy its selected attributes*/
5421 void GameScript::ChangeAnimation(Scriptable
* Sender
, Action
* parameters
)
5423 if (Sender
->Type
!=ST_ACTOR
) {
5426 ChangeAnimationCore((Actor
*) Sender
, parameters
->string0Parameter
,1);
5429 void GameScript::ChangeAnimationNoEffect(Scriptable
* Sender
, Action
* parameters
)
5431 if (Sender
->Type
!=ST_ACTOR
) {
5434 ChangeAnimationCore((Actor
*) Sender
, parameters
->string0Parameter
,0);
5437 void GameScript::Polymorph(Scriptable
* Sender
, Action
* parameters
)
5439 if (Sender
->Type
!=ST_ACTOR
) {
5442 Actor
*act
= (Actor
*) Sender
;
5443 act
->SetBase(IE_ANIMATION_ID
, parameters
->int0Parameter
);
5446 void GameScript::PolymorphCopy(Scriptable
* Sender
, Action
* parameters
)
5448 if (Sender
->Type
!=ST_ACTOR
) {
5451 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5452 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5455 PolymorphCopyCore((Actor
*) Sender
, (Actor
*) tar
, false);
5458 /* according to IESDP this only copies the animation ID */
5459 void GameScript::PolymorphCopyBase(Scriptable
* Sender
, Action
* parameters
)
5461 if (Sender
->Type
!=ST_ACTOR
) {
5464 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5465 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5468 Actor
*act
= (Actor
*) Sender
;
5469 Actor
*actor
= (Actor
*) tar
;
5470 act
->SetBase(IE_ANIMATION_ID
, actor
->GetBase(IE_ANIMATION_ID
) );
5473 void GameScript::SaveGame(Scriptable
* /*Sender*/, Action
* parameters
)
5476 char FolderName
[_MAX_PATH
];
5477 const char *folder
= "";
5479 AutoTable
tab("savegame");
5481 type
= atoi(tab
->QueryField((unsigned int) -1));
5483 char * str
= core
->GetString( parameters
->int0Parameter
, IE_STR_STRREFOFF
);
5484 snprintf (FolderName
, sizeof(FolderName
), "%s - %s", tab
->QueryField(0), str
);
5485 core
->FreeString( str
);
5486 folder
= FolderName
;
5488 folder
= tab
->QueryField(parameters
->int0Parameter
);
5491 core
->GetSaveGameIterator()->CreateSaveGame(parameters
->int0Parameter
, folder
);
5494 /*EscapeAreaMove(S:Area*,I:X*,I:Y*,I:Face*)*/
5495 void GameScript::EscapeArea(Scriptable
* Sender
, Action
* parameters
)
5497 printf("EscapeArea/EscapeAreaMove\n");
5498 if (Sender
->Type
!=ST_ACTOR
) {
5499 Sender
->ReleaseCurrentAction();
5502 Map
*map
= Sender
->GetCurrentArea();
5504 Sender
->ReleaseCurrentAction();
5508 Point p
= Sender
->Pos
;
5509 map
->TMap
->AdjustNearestTravel(p
);
5511 if (parameters
->string0Parameter
[0]) {
5512 Point
q((short) parameters
->int0Parameter
, (short) parameters
->int1Parameter
);
5513 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, q
, 0, parameters
->int2Parameter
);
5515 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, p
, EA_DESTROY
, parameters
->int0Parameter
);
5517 //EscapeAreaCore will do its ReleaseCurrentAction
5518 //Sender->ReleaseCurrentAction();
5521 void GameScript::EscapeAreaDestroy(Scriptable
* Sender
, Action
* parameters
)
5523 printf("EscapeAreaDestroy\n");
5524 if (Sender
->Type
!=ST_ACTOR
) {
5525 Sender
->ReleaseCurrentAction();
5528 Map
*map
= Sender
->GetCurrentArea();
5530 Sender
->ReleaseCurrentAction();
5535 Point p
= Sender
->Pos
;
5536 map
->TMap
->AdjustNearestTravel(p
);
5537 //EscapeAreaCore will do its ReleaseCurrentAction
5538 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, p
, EA_DESTROY
, parameters
->int0Parameter
);
5541 /*EscapeAreaObjectMove(S:Area*,I:X*,I:Y*,I:Face*)*/
5542 void GameScript::EscapeAreaObject(Scriptable
* Sender
, Action
* parameters
)
5544 printf("EscapeAreaObject\n");
5545 if (Sender
->Type
!=ST_ACTOR
) {
5546 Sender
->ReleaseCurrentAction();
5549 Map
*map
= Sender
->GetCurrentArea();
5551 Sender
->ReleaseCurrentAction();
5555 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5557 Sender
->ReleaseCurrentAction();
5561 if (parameters
->string0Parameter
[0]) {
5562 Point
q((short) parameters
->int0Parameter
, (short) parameters
->int1Parameter
);
5563 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, q
, 0, parameters
->int2Parameter
);
5565 EscapeAreaCore( Sender
, p
, 0, p
, EA_DESTROY
, parameters
->int0Parameter
);
5567 //EscapeAreaCore will do its ReleaseCurrentAction
5570 //This one doesn't require the object to be seen?
5571 //We don't have that feature yet, so this is the same as EscapeAreaObject
5572 void GameScript::EscapeAreaObjectNoSee(Scriptable
* Sender
, Action
* parameters
)
5574 printf("EscapeAreaObjectNoSee\n");
5575 if (Sender
->Type
!=ST_ACTOR
) {
5576 Sender
->ReleaseCurrentAction();
5579 Map
*map
= Sender
->GetCurrentArea();
5581 Sender
->ReleaseCurrentAction();
5585 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5587 Sender
->ReleaseCurrentAction();
5591 Sender
->SetWait(parameters
->int0Parameter
);
5592 if (parameters
->string0Parameter
[0]) {
5593 Point
q((short) parameters
->int0Parameter
, (short) parameters
->int1Parameter
);
5594 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, q
, 0, parameters
->int2Parameter
);
5596 EscapeAreaCore( Sender
, p
, 0, p
, EA_DESTROY
|EA_NOSEE
, parameters
->int0Parameter
);
5598 //EscapeAreaCore will do its ReleaseCurrentAction
5601 //takes first fitting item from container at feet, doesn't seem to be working in the original engines
5602 void GameScript::PickUpItem(Scriptable
* Sender
, Action
* parameters
)
5604 if (Sender
->Type
!=ST_ACTOR
) {
5607 Actor
*scr
= (Actor
*) Sender
;
5608 Map
*map
= scr
->GetCurrentArea();
5609 Container
*c
= map
->GetPile(scr
->Pos
);
5610 if (!c
) { //this shouldn't happen, but lets prepare for the worst
5614 //the following part is coming from GUISCript.cpp with trivial changes
5615 int Slot
= c
->inventory
.FindItem(parameters
->string0Parameter
, 0);
5619 int res
= core
->CanMoveItem(c
->inventory
.GetSlotItem(Slot
) );
5620 if (!res
) { //cannot move
5623 CREItem
*item
= c
->RemoveItem(Slot
,0);
5627 if (res
!=-1 && scr
->InParty
) { //it is gold and we got the party pool!
5630 res
= scr
->inventory
.AddSlotItem(item
, SLOT_ONLYINVENTORY
);
5631 if (res
!=ASI_SUCCESS
) { //putting it back
5635 item_is_gold
: //we take gold!
5637 core
->GetGame()->PartyGold
+= res
;
5638 //if you want message here then use
5639 //core->GetGame()->AddGold(res);
5641 scr
->SetBase( IE_GOLD
, scr
->GetBase(IE_GOLD
) + res
);
5646 void GameScript::ChangeStoreMarkup(Scriptable
* /*Sender*/, Action
* parameters
)
5648 bool has_current
= false;
5652 Store
*store
= core
->GetCurrentStore();
5654 store
= core
->SetCurrentStore(parameters
->string0Parameter
,NULL
);
5656 if (strnicmp(store
->Name
, parameters
->string0Parameter
, 8) ) {
5657 //not the current store, we need some dirty hack
5659 strnlwrcpy(current
, store
->Name
, 8);
5660 strnuprcpy(owner
, store
->GetOwner(), 32);
5663 store
->BuyMarkup
= parameters
->int0Parameter
;
5664 store
->SellMarkup
= parameters
->int1Parameter
;
5665 //additional markup, is this depreciation???
5666 store
->DepreciationRate
= parameters
->int2Parameter
;
5668 //setting back old store (this will save our current store)
5669 core
->SetCurrentStore(current
, owner
);
5673 void GameScript::SetEncounterProbability(Scriptable
* /*Sender*/, Action
* parameters
)
5675 WorldMap
*wmap
= core
->GetWorldMap(parameters
->string0Parameter
);
5677 //no such starting area
5680 WMPAreaLink
*link
= wmap
->GetLink(parameters
->string0Parameter
, parameters
->string1Parameter
);
5684 link
->EncounterChance
= parameters
->int0Parameter
;
5687 void GameScript::SpawnPtActivate(Scriptable
* Sender
, Action
* parameters
)
5689 if (parameters
->objects
[1]) {
5690 Map
*map
= Sender
->GetCurrentArea();
5691 Spawn
*spawn
= map
->GetSpawn(parameters
->objects
[1]->objectName
);
5698 void GameScript::SpawnPtDeactivate(Scriptable
* Sender
, Action
* parameters
)
5700 if (parameters
->objects
[1]) {
5701 Map
*map
= Sender
->GetCurrentArea();
5702 Spawn
*spawn
= map
->GetSpawn(parameters
->objects
[1]->objectName
);
5709 void GameScript::SpawnPtSpawn(Scriptable
* Sender
, Action
* parameters
)
5711 if (parameters
->objects
[1]) {
5712 Map
*map
= Sender
->GetCurrentArea();
5713 Spawn
*spawn
= map
->GetSpawn(parameters
->objects
[1]->objectName
);
5715 spawn
->Enabled
= 1; //??? maybe use an unconditionality flag
5716 map
->TriggerSpawn(spawn
);
5721 void GameScript::ApplySpell(Scriptable
* Sender
, Action
* parameters
)
5725 if (!ResolveSpellName( spellres
, parameters
) ) {
5729 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5733 if (tar
->Type
==ST_ACTOR
) {
5734 //apply spell on target
5738 if (Sender->Type==ST_ACTOR) {
5739 owner = (Actor *) Sender;
5741 owner = (Actor *) tar;
5744 //core->ApplySpell(spellres, (Actor *) tar, owner, parameters->int1Parameter);
5745 core
->ApplySpell(spellres
, (Actor
*) tar
, Sender
, parameters
->int1Parameter
);
5747 //no idea about this one
5751 if (Sender->Type==ST_ACTOR) {
5752 owner = (Actor *) Sender;
5757 //apply spell on point
5759 GetPositionFromScriptable(tar
, d
, false);
5760 //core->ApplySpellPoint(spellres, tar->GetCurrentArea(), d, owner, parameters->int1Parameter);
5761 core
->ApplySpellPoint(spellres
, tar
->GetCurrentArea(), d
, Sender
, parameters
->int1Parameter
);
5765 void GameScript::ApplySpellPoint(Scriptable
* Sender
, Action
* parameters
)
5770 if (!ResolveSpellName( spellres
, parameters
) ) {
5774 if (Sender
->Type
==ST_ACTOR
) {
5775 owner
= (Actor
*) Sender
;
5779 core
->ApplySpellPoint(spellres
, Sender
->GetCurrentArea(), parameters
->pointParameter
, owner
, parameters
->int1Parameter
);
5782 //this is a gemrb extension
5783 //sets a variable to the stat value
5784 void GameScript::GetStat(Scriptable
* Sender
, Action
* parameters
)
5788 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5789 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5792 Actor
* actor
= ( Actor
* ) tar
;
5793 value
= actor
->GetStat( parameters
->int0Parameter
);
5795 SetVariable( Sender
, parameters
->string0Parameter
, value
);
5798 void GameScript::BreakInstants(Scriptable
* Sender
, Action
* /*parameters*/)
5800 //don't do anything, apparently the point of this action is to
5801 //delay the execution of further actions to the next AI cycle
5803 Sender
->ReleaseCurrentAction(); // this doesn't really need to block
5806 //an interesting improvement would be to pause game for a given duration
5807 void GameScript::PauseGame(Scriptable
* Sender
, Action
* /*parameters*/)
5809 GameControl
*gc
= core
->GetGameControl();
5811 gc
->SetDialogueFlags(DF_FREEZE_SCRIPTS
, BM_OR
);
5812 core
->DisplayConstantString(STR_SCRIPTPAUSED
,0xff0000);
5814 // releasing this action allows actions to continue executing,
5815 // so we force a wait
5817 Sender
->ReleaseCurrentAction(); // does this need to block?
5820 void GameScript::SetNoOneOnTrigger(Scriptable
* Sender
, Action
* parameters
)
5824 if (!parameters
->objects
[1]) {
5827 ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
5829 if (!ip
|| (ip
->Type
!=ST_TRIGGER
&& ip
->Type
!=ST_TRAVEL
&& ip
->Type
!=ST_PROXIMITY
)) {
5830 printf("Script error: No Trigger Named \"%s\"\n", parameters
->objects
[1]->objectName
);
5833 ip
->LastEntered
= 0;
5834 ip
->LastTrigger
= 0;
5835 ip
->LastTriggerObject
= 0;
5838 void GameScript::UseDoor(Scriptable
* Sender
, Action
* parameters
)
5840 GameControl
*gc
= core
->GetGameControl();
5842 Sender
->ReleaseCurrentAction();
5846 gc
->target_mode
= TARGET_MODE_NONE
;
5847 OpenDoor(Sender
, parameters
);
5849 Sender
->ReleaseCurrentAction(); // this is blocking, OpenDoor is not
5852 //this will force bashing the door
5853 void GameScript::BashDoor(Scriptable
* Sender
, Action
* parameters
)
5855 GameControl
*gc
= core
->GetGameControl();
5857 Sender
->ReleaseCurrentAction();
5861 gc
->target_mode
= TARGET_MODE_ATTACK
; //for bashing doors too
5862 OpenDoor(Sender
, parameters
);
5864 Sender
->ReleaseCurrentAction(); // this is blocking, OpenDoor is not
5868 void GameScript::ActivatePortalCursor(Scriptable
* Sender
, Action
* parameters
)
5872 if (!parameters
->objects
[1]) {
5875 ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
5880 if (ip
->Type
!=ST_PROXIMITY
&& ip
->Type
!=ST_TRAVEL
) {
5883 InfoPoint
*tar
= (InfoPoint
*) ip
;
5884 if (parameters
->int0Parameter
) {
5885 tar
->Trapped
|=PORTAL_CURSOR
;
5887 tar
->Trapped
&=~PORTAL_CURSOR
;
5892 void GameScript::EnablePortalTravel(Scriptable
* Sender
, Action
* parameters
)
5896 if (!parameters
->objects
[1]) {
5899 ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
5904 if (ip
->Type
!=ST_PROXIMITY
&& ip
->Type
!=ST_TRAVEL
) {
5907 InfoPoint
*tar
= (InfoPoint
*) ip
;
5908 if (parameters
->int0Parameter
) {
5909 tar
->Trapped
|=PORTAL_TRAVEL
;
5911 tar
->Trapped
&=~PORTAL_TRAVEL
;
5915 //unhardcoded iwd action (for the forge entrance change)
5916 void GameScript::ChangeDestination(Scriptable
* Sender
, Action
* parameters
)
5918 InfoPoint
*ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
5919 if (ip
&& (ip
->Type
==ST_TRAVEL
) ) {
5920 strnlwrcpy(ip
->Destination
, parameters
->string0Parameter
, 32);
5924 void GameScript::MoveCursorPoint(Scriptable
* /*Sender*/, Action
* parameters
)
5926 core
->GetVideoDriver()->MoveMouse(parameters
->pointParameter
.x
, parameters
->pointParameter
.y
);
5929 //false means, no talk
5930 void GameScript::DialogueInterrupt(Scriptable
* Sender
, Action
* parameters
)
5932 if (Sender
->Type
!=ST_ACTOR
) {
5935 Actor
* actor
= ( Actor
* ) Sender
;
5936 if ( parameters
->int0Parameter
!= 0 ) {
5937 actor
->SetMCFlag(MC_NO_TALK
, BM_NAND
);
5939 actor
->SetMCFlag(MC_NO_TALK
, BM_OR
);
5943 void GameScript::EquipMostDamagingMelee(Scriptable
* Sender
, Action
* /*parameters*/)
5945 if (Sender
->Type
!=ST_ACTOR
) {
5948 Actor
* actor
= ( Actor
* ) Sender
;
5949 actor
->inventory
.EquipBestWeapon(EQUIP_MELEE
);
5952 void GameScript::EquipRanged(Scriptable
* Sender
, Action
* /*parameters*/)
5954 if (Sender
->Type
!=ST_ACTOR
) {
5957 Actor
* actor
= ( Actor
* ) Sender
;
5958 actor
->inventory
.EquipBestWeapon(EQUIP_RANGED
);
5961 //will equip best weapon regardless of range considerations
5962 void GameScript::EquipWeapon(Scriptable
* Sender
, Action
* /*parameters*/)
5964 if (Sender
->Type
!=ST_ACTOR
) {
5967 Actor
* actor
= ( Actor
* ) Sender
;
5968 actor
->inventory
.EquipBestWeapon(EQUIP_MELEE
|EQUIP_RANGED
);
5971 void GameScript::SetBestWeapon(Scriptable
* Sender
, Action
* parameters
)
5973 if (Sender
->Type
!=ST_ACTOR
) {
5977 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5978 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5981 Actor
* actor
= ( Actor
* ) Sender
;
5983 Actor
*target
= (Actor
*) tar
;
5984 if (PersonalDistance(actor
,target
)>(unsigned int) parameters
->int0Parameter
) {
5985 actor
->inventory
.EquipBestWeapon(EQUIP_RANGED
);
5987 actor
->inventory
.EquipBestWeapon(EQUIP_MELEE
);
5991 void GameScript::FakeEffectExpiryCheck(Scriptable
* Sender
, Action
* parameters
)
5993 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5994 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5997 Actor
*target
= (Actor
*) tar
;
5998 target
->fxqueue
.RemoveExpiredEffects(parameters
->int0Parameter
);
6001 void GameScript::SetInterrupt(Scriptable
* Sender
, Action
* parameters
)
6003 if (parameters
->int0Parameter
) {
6004 Sender
->Interrupt();
6006 Sender
->NoInterrupt();
6010 void GameScript::SelectWeaponAbility(Scriptable
* Sender
, Action
* parameters
)
6012 if (Sender
->Type
!=ST_ACTOR
) {
6015 Actor
*scr
= (Actor
*) Sender
;
6016 int slot
= parameters
->int0Parameter
;
6017 int wslot
= scr
->inventory
.GetWeaponSlot();
6019 if (core
->QuerySlotType(slot
)&SLOT_WEAPON
) {
6021 if (slot
<0 || slot
>=MAX_QUICKWEAPONSLOT
) {
6024 scr
->SetEquippedQuickSlot(slot
, parameters
->int1Parameter
);
6028 wslot
= scr
->inventory
.GetQuickSlot();
6029 if (core
->QuerySlotType(slot
)&SLOT_ITEM
) {
6031 if (slot
<0 || slot
>=MAX_QUICKITEMSLOT
) {
6035 scr
->PCStats
->QuickItemHeaders
[slot
]=(ieWord
) parameters
->int1Parameter
;
6040 void GameScript::UseItem(Scriptable
* Sender
, Action
* parameters
)
6042 if (Sender
->Type
!=ST_ACTOR
) {
6043 Sender
->ReleaseCurrentAction();
6046 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6048 Sender
->ReleaseCurrentAction();
6051 Actor
*act
= (Actor
*) Sender
;
6053 ieDword header
, flags
;
6056 if (parameters
->string0Parameter
[0]) {
6057 Slot
= act
->inventory
.FindItem(parameters
->string0Parameter
, 0);
6058 //this IS in the original game code (ability)
6059 header
= parameters
->int0Parameter
;
6060 flags
= parameters
->int1Parameter
;
6062 Slot
= parameters
->int0Parameter
;
6063 //this is actually not in the original game code
6064 header
= parameters
->int1Parameter
;
6065 flags
= parameters
->int2Parameter
;
6069 Sender
->ReleaseCurrentAction();
6073 if (!ResolveItemName( itemres
, act
, Slot
) ) {
6074 Sender
->ReleaseCurrentAction();
6078 unsigned int dist
= GetItemDistance(itemres
, header
);
6080 if (PersonalDistance(tar
->Pos
, Sender
) > dist
) {
6081 MoveNearerTo(Sender
, tar
, dist
);
6085 act
->UseItem(Slot
, header
, tar
, flags
);
6086 Sender
->ReleaseCurrentAction();
6089 void GameScript::UseItemPoint(Scriptable
* Sender
, Action
* parameters
)
6091 if (Sender
->Type
!=ST_ACTOR
) {
6092 Sender
->ReleaseCurrentAction();
6096 Actor
*act
= (Actor
*) Sender
;
6102 if (parameters
->string0Parameter
[0]) {
6103 Slot
= act
->inventory
.FindItem(parameters
->string0Parameter
, 0);
6104 //this IS in the original game code (ability)
6105 header
= parameters
->int0Parameter
;
6106 flags
= parameters
->int1Parameter
;
6108 Slot
= parameters
->int0Parameter
;
6109 //this is actually not in the original game code
6110 header
= parameters
->int1Parameter
;
6111 flags
= parameters
->int2Parameter
;
6115 Sender
->ReleaseCurrentAction();
6119 if (!ResolveItemName( itemres
, act
, Slot
) ) {
6120 Sender
->ReleaseCurrentAction();
6124 unsigned int dist
= GetItemDistance(itemres
, header
);
6126 if (PersonalDistance(parameters
->pointParameter
, Sender
) > dist
) {
6127 MoveNearerTo(Sender
, parameters
->pointParameter
, dist
, 0);
6131 act
->UseItemPoint(Slot
, header
, parameters
->pointParameter
, flags
);
6132 Sender
->ReleaseCurrentAction();
6135 //addfeat will be able to remove feats too
6136 //(the second int parameter is a bitmode)
6137 void GameScript::AddFeat(Scriptable
* Sender
, Action
* parameters
)
6139 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6140 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6143 Actor
*actor
= (Actor
*)tar
;
6144 actor
->SetFeat(parameters
->int0Parameter
, parameters
->int1Parameter
);
6147 void GameScript::MatchHP(Scriptable
* Sender
, Action
* parameters
)
6149 if (Sender
->Type
!=ST_ACTOR
) {
6152 Actor
*scr
= (Actor
*) Sender
;
6153 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6154 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6157 Actor
*actor
= (Actor
*)tar
;
6158 switch (parameters
->int0Parameter
) {
6159 case 1: //sadly the hpflags are not the same as stats
6160 actor
->SetBase(IE_HITPOINTS
,scr
->GetBase(IE_HITPOINTS
));
6163 actor
->SetBase(IE_MAXHITPOINTS
, scr
->GetBase(IE_MAXHITPOINTS
));
6165 default: //this is gemrb extension
6166 actor
->SetBase(parameters
->int0Parameter
, scr
->GetBase(parameters
->int0Parameter
));
6171 void GameScript::ChangeColor(Scriptable
* Sender
, Action
* parameters
)
6173 if (Sender
->Type
!=ST_ACTOR
) {
6176 Actor
*scr
= (Actor
*) Sender
;
6177 ieDword stat
= parameters
->int0Parameter
;
6178 if (stat
<9 || stat
>14) {
6181 stat
+= IE_COLORS
- 9;
6182 scr
->SetBase(stat
, (scr
->GetBase(stat
)&~255)|(parameters
->int1Parameter
&255));
6185 void GameScript::AddKit(Scriptable
* Sender
, Action
* parameters
)
6187 if (Sender
->Type
!=ST_ACTOR
) {
6190 Actor
*scr
= (Actor
*) Sender
;
6191 //remove previous kit stuff
6192 scr
->SetBase(IE_KIT
, parameters
->int0Parameter
);
6195 void GameScript::AddSuperKit(Scriptable
* Sender
, Action
* parameters
)
6197 if (Sender
->Type
!=ST_ACTOR
) {
6200 Actor
*scr
= (Actor
*) Sender
;
6201 scr
->SetBase(IE_KIT
, parameters
->int0Parameter
);
6204 void GameScript::SetSelection(Scriptable
* /*Sender*/, Action
* parameters
)
6206 GameControl
*gc
= core
->GetGameControl();
6210 gc
->SelectActor(parameters
->int0Parameter
, parameters
->int1Parameter
);
6213 //this action is weird in the original game, because it overwrites ALL
6215 //in this version, if a stat is set to 0, it won't change
6216 //it will alter only the main IDS stats
6217 void GameScript::ChangeAIType(Scriptable
* Sender
, Action
* parameters
)
6219 if (Sender
->Type
!=ST_ACTOR
) {
6222 Object
*ob
= parameters
->objects
[1];
6226 Actor
*scr
= (Actor
*) Sender
;
6227 for (int i
=0;i
<MAX_OBJECT_FIELDS
;i
++) {
6228 int val
= ob
->objectFields
[i
];
6230 if (!strnicmp(ObjectIDSTableNames
[i
],"ea",8)) {
6231 scr
->SetBase(IE_EA
, val
);
6234 if (!strnicmp(ObjectIDSTableNames
[i
],"general",8)) {
6235 scr
->SetBase(IE_GENERAL
, val
);
6238 if (!strnicmp(ObjectIDSTableNames
[i
],"race",8)) {
6239 scr
->SetBase(IE_RACE
, val
);
6242 if (!strnicmp(ObjectIDSTableNames
[i
],"class",8)) {
6243 scr
->SetBase(IE_CLASS
, val
);
6246 if (!strnicmp(ObjectIDSTableNames
[i
],"gender",8)) {
6247 scr
->SetBase(IE_SEX
, val
);
6250 if (!strnicmp(ObjectIDSTableNames
[i
],"specific",8)) {
6251 scr
->SetBase(IE_SPECIFIC
, val
);
6254 if (!strnicmp(ObjectIDSTableNames
[i
],"align",8)) {
6255 scr
->SetBase(IE_ALIGNMENT
, val
);
6261 void GameScript::Follow(Scriptable
* Sender
, Action
* parameters
)
6263 if (Sender
->Type
!=ST_ACTOR
) {
6267 Actor
*scr
= (Actor
*)Sender
;
6268 scr
->FollowOffset
= parameters
->pointParameter
;
6271 void GameScript::FollowCreature(Scriptable
* Sender
, Action
* parameters
)
6273 if (Sender
->Type
!=ST_ACTOR
) {
6274 Sender
->ReleaseCurrentAction();
6278 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6279 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6280 Sender
->ReleaseCurrentAction();
6283 Actor
*scr
= (Actor
*)Sender
;
6284 Actor
*actor
= (Actor
*)tar
;
6285 scr
->LastFollowed
= actor
->GetID();
6286 scr
->FollowOffset
.empty();
6287 if (!scr
->InMove() || scr
->Destination
!= actor
->Pos
) {
6288 scr
->WalkTo(actor
->Pos
, 0, 1);
6292 void GameScript::RunFollow(Scriptable
* Sender
, Action
* parameters
)
6294 if (Sender
->Type
!=ST_ACTOR
) {
6295 Sender
->ReleaseCurrentAction();
6299 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6300 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6301 Sender
->ReleaseCurrentAction();
6304 Actor
*scr
= (Actor
*)Sender
;
6305 Actor
*actor
= (Actor
*)tar
;
6306 scr
->LastFollowed
= actor
->GetID();
6307 scr
->FollowOffset
.empty();
6308 if (!scr
->InMove() || scr
->Destination
!= actor
->Pos
) {
6309 scr
->WalkTo(actor
->Pos
, IF_RUNNING
, 1);
6313 void GameScript::ProtectPoint(Scriptable
* Sender
, Action
* parameters
)
6315 if (Sender
->Type
!=ST_ACTOR
) {
6316 Sender
->ReleaseCurrentAction();
6319 Actor
*scr
= (Actor
*)Sender
;
6320 if (!scr
->InMove() || scr
->Destination
!= parameters
->pointParameter
) {
6321 scr
->WalkTo( parameters
->pointParameter
, 0, 1 );
6323 // we should handle 'Protect' here rather than just unblocking
6324 Sender
->ReleaseCurrentAction();
6327 void GameScript::ProtectObject(Scriptable
* Sender
, Action
* parameters
)
6329 if (Sender
->Type
!=ST_ACTOR
) {
6330 Sender
->ReleaseCurrentAction();
6334 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6335 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6336 Sender
->ReleaseCurrentAction();
6339 Actor
*scr
= (Actor
*)Sender
;
6340 Actor
*actor
= (Actor
*)tar
;
6341 scr
->LastFollowed
= actor
->GetID();
6342 scr
->LastProtected
= actor
->GetID();
6344 scr
->FollowOffset
.x
= parameters
->int0Parameter
;
6345 scr
->FollowOffset
.y
= parameters
->int0Parameter
;
6346 if (!scr
->InMove() || scr
->Destination
!= tar
->Pos
) {
6347 scr
->WalkTo( tar
->Pos
, 0, MAX_OPERATING_DISTANCE
);
6349 // we should handle 'Protect' here rather than just unblocking
6350 Sender
->ReleaseCurrentAction();
6353 //keeps following the object in formation
6354 void GameScript::FollowObjectFormation(Scriptable
* Sender
, Action
* parameters
)
6356 GameControl
*gc
= core
->GetGameControl();
6358 Sender
->ReleaseCurrentAction();
6361 if (Sender
->Type
!=ST_ACTOR
) {
6362 Sender
->ReleaseCurrentAction();
6366 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6367 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6368 Sender
->ReleaseCurrentAction();
6371 Actor
*scr
= (Actor
*)Sender
;
6372 Actor
*actor
= (Actor
*)tar
;
6373 scr
->LastFollowed
= actor
->GetID();
6374 ieDword formation
= parameters
->int0Parameter
;
6375 ieDword pos
= parameters
->int1Parameter
;
6376 scr
->FollowOffset
= gc
->GetFormationOffset(formation
, pos
);
6377 if (!scr
->InMove() || scr
->Destination
!= tar
->Pos
) {
6378 scr
->WalkTo( tar
->Pos
, 0, 1 );
6380 Sender
->ReleaseCurrentAction();
6383 //walks to a specific offset of target (quite like movetoobject)
6384 void GameScript::Formation(Scriptable
* Sender
, Action
* parameters
)
6386 GameControl
*gc
= core
->GetGameControl();
6388 Sender
->ReleaseCurrentAction();
6391 if (Sender
->Type
!=ST_ACTOR
) {
6392 Sender
->ReleaseCurrentAction();
6395 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6397 Sender
->ReleaseCurrentAction();
6400 Actor
*scr
= (Actor
*)Sender
;
6401 ieDword formation
= parameters
->int0Parameter
;
6402 ieDword pos
= parameters
->int1Parameter
;
6403 Point FollowOffset
= gc
->GetFormationOffset(formation
, pos
);
6404 FollowOffset
.x
+=tar
->Pos
.x
;
6405 FollowOffset
.y
+=tar
->Pos
.y
;
6406 if (!scr
->InMove() || scr
->Destination
!= FollowOffset
) {
6407 scr
->WalkTo( FollowOffset
, 0, 1 );
6411 void GameScript::TransformItem(Scriptable
* Sender
, Action
* parameters
)
6413 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6414 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6417 TransformItemCore((Actor
*)tar
, parameters
, true);
6420 void GameScript::TransformPartyItem(Scriptable
* /*Sender*/, Action
* parameters
)
6422 Game
*game
= core
->GetGame();
6423 int i
= game
->GetPartySize(false);
6425 Actor
*tar
= game
->GetPC(i
, false);
6426 TransformItemCore(tar
, parameters
, true);
6430 void GameScript::TransformItemAll(Scriptable
* Sender
, Action
* parameters
)
6432 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6433 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6436 TransformItemCore((Actor
*)tar
, parameters
, false);
6439 void GameScript::TransformPartyItemAll(Scriptable
* /*Sender*/, Action
* parameters
)
6441 Game
*game
= core
->GetGame();
6442 int i
= game
->GetPartySize(false);
6444 Actor
*tar
= game
->GetPC(i
, false);
6445 TransformItemCore(tar
, parameters
, false);
6449 void GameScript::GeneratePartyMember(Scriptable
* /*Sender*/, Action
* parameters
)
6451 AutoTable
pcs("bios");
6455 const char* string
= pcs
->QueryField( parameters
->int0Parameter
, 0 );
6456 int pos
= gamedata
->LoadCreature(string
,0,false);
6460 Actor
*actor
= core
->GetGame()->GetNPC(pos
);
6464 actor
->SetOrientation(parameters
->int1Parameter
, false);
6465 actor
->MoveTo(parameters
->pointParameter
);
6468 void GameScript::EnableFogDither(Scriptable
* /*Sender*/, Action
* /*parameters*/)
6470 core
->FogOfWar
|=FOG_DRAWFOG
;
6473 void GameScript::DisableFogDither(Scriptable
* /*Sender*/, Action
* /*parameters*/)
6475 core
->FogOfWar
&=~FOG_DRAWFOG
;
6478 void DeleteAllSpriteCovers()
6480 Game
*game
= core
->GetGame();
6481 int i
= game
->GetPartySize(false);
6483 Selectable
*tar
= (Selectable
*) game
->GetPC(i
, false);
6484 tar
->SetSpriteCover(NULL
);
6488 void GameScript::EnableSpriteDither(Scriptable
* /*Sender*/, Action
* /*parameters*/)
6490 core
->FogOfWar
&=~FOG_DITHERSPRITES
;
6491 DeleteAllSpriteCovers();
6494 void GameScript::DisableSpriteDither(Scriptable
* /*Sender*/, Action
* /*parameters*/)
6496 core
->FogOfWar
|=~FOG_DITHERSPRITES
;
6497 DeleteAllSpriteCovers();
6500 //the PST crew apparently loved hardcoding stuff
6501 ieResRef RebusResRef
={"DABUS1"};
6503 void GameScript::FloatRebus(Scriptable
* Sender
, Action
* parameters
)
6505 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6506 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6509 Actor
*actor
= (Actor
*)tar
;
6510 RebusResRef
[5]=(char) core
->Roll(1,5,'0');
6511 ScriptedAnimation
*vvc
= gamedata
->GetScriptedAnimation(RebusResRef
, 0);
6513 //setting the height
6514 vvc
->ZPos
=actor
->size
*20;
6516 //maybe this needs setting up some time
6517 vvc
->SetDefaultDuration(20);
6518 actor
->AddVVCell(vvc
);
6522 void GameScript::IncrementKillStat(Scriptable
* Sender
, Action
* parameters
)
6524 DataFileMgr
* ini
= core
->GetBeastsINI();
6529 sprintf(key
,"%d", parameters
->int0Parameter
);
6530 const char *variable
= ini
->GetKeyAsString( key
, "killvar", NULL
);
6534 ieDword value
= CheckVariable( Sender
, variable
, "GLOBAL" ) + 1;
6535 SetVariable( Sender
, variable
, "GLOBAL", value
);
6538 //this action plays a vvc animation over target
6539 //we simply apply the appropriate opcode on the target (see iwdopcodes)
6540 //the list of vvcs is in iwdshtab.2da
6541 EffectRef fx_iwd_visual_spell_hit_ref
={"IWDVisualSpellHit",NULL
,-1};
6543 void GameScript::SpellHitEffectSprite(Scriptable
* Sender
, Action
* parameters
)
6545 Scriptable
* src
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6549 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[2] );
6550 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6553 int opcode
= EffectQueue::ResolveEffect(fx_iwd_visual_spell_hit_ref
);
6554 Effect
*fx
= core
->GetEffect(opcode
);
6556 //invalid effect name didn't resolve to opcode
6561 fx
->Parameter2
= parameters
->int0Parameter
;
6562 //height (not sure if this is in the opcode, but seems acceptable)
6563 fx
->Parameter1
= parameters
->int1Parameter
;
6564 fx
->Probability1
=100;
6565 fx
->TimingMode
=FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES
;
6566 core
->ApplyEffect(fx
, (Actor
*) tar
, src
);
6569 void GameScript::SpellHitEffectPoint(Scriptable
* Sender
, Action
* parameters
)
6571 Scriptable
* src
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6576 int opcode
= EffectQueue::ResolveEffect(fx_iwd_visual_spell_hit_ref
);
6577 Effect
*fx
= core
->GetEffect(opcode
);
6579 //invalid effect name didn't resolve to opcode
6584 fx
->Parameter2
= parameters
->int0Parameter
;
6585 //height (not sure if this is in the opcode, but seems acceptable)
6586 fx
->Parameter1
= parameters
->int1Parameter
;
6587 fx
->Probability1
=100;
6588 fx
->TimingMode
=FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES
;
6589 fx
->PosX
=parameters
->pointParameter
.x
;
6590 fx
->PosY
=parameters
->pointParameter
.y
;
6591 core
->ApplyEffect(fx
, NULL
, src
);
6595 void GameScript::ClickLButtonObject(Scriptable
* Sender
, Action
* parameters
)
6597 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6599 Sender
->ReleaseCurrentAction(); // this is blocking for some reason?
6602 ClickCore(Sender
, tar
->Pos
, GEM_MB_ACTION
, parameters
->int0Parameter
);
6605 void GameScript::ClickLButtonPoint(Scriptable
* Sender
, Action
* parameters
)
6607 ClickCore(Sender
, parameters
->pointParameter
, GEM_MB_ACTION
, parameters
->int0Parameter
);
6610 void GameScript::ClickRButtonObject(Scriptable
* Sender
, Action
* parameters
)
6612 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6614 Sender
->ReleaseCurrentAction(); // this is blocking for some reason?
6617 ClickCore(Sender
, tar
->Pos
, GEM_MB_MENU
, parameters
->int0Parameter
);
6620 void GameScript::ClickRButtonPoint(Scriptable
* Sender
, Action
* parameters
)
6622 ClickCore(Sender
, parameters
->pointParameter
, GEM_MB_MENU
, parameters
->int0Parameter
);
6625 void GameScript::DoubleClickLButtonObject(Scriptable
* Sender
, Action
* parameters
)
6627 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6629 Sender
->ReleaseCurrentAction(); // this is blocking for some reason?
6632 ClickCore(Sender
, tar
->Pos
, GEM_MB_ACTION
|GEM_MB_DOUBLECLICK
, parameters
->int0Parameter
);
6635 void GameScript::DoubleClickLButtonPoint(Scriptable
* Sender
, Action
* parameters
)
6637 ClickCore(Sender
, parameters
->pointParameter
, GEM_MB_ACTION
|GEM_MB_DOUBLECLICK
, parameters
->int0Parameter
);
6640 void GameScript::DoubleClickRButtonObject(Scriptable
* Sender
, Action
* parameters
)
6642 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6644 Sender
->ReleaseCurrentAction(); // this is blocking for some reason?
6647 ClickCore(Sender
, tar
->Pos
, GEM_MB_MENU
|GEM_MB_DOUBLECLICK
, parameters
->int0Parameter
);
6650 void GameScript::DoubleClickRButtonPoint(Scriptable
* Sender
, Action
* parameters
)
6652 ClickCore(Sender
, parameters
->pointParameter
, GEM_MB_MENU
|GEM_MB_DOUBLECLICK
, parameters
->int0Parameter
);
6655 //Picks 5 lines from wish.2da
6656 //Gets the 5 values (column is int0parameter) from the table.
6657 //Sets the five wishpowerNN to 1, while resets the rest to 0.
6658 //TODO: investigate what happens with * values
6659 void GameScript::SetupWish(Scriptable
* Sender
, Action
* parameters
)
6661 SetupWishCore(Sender
, parameters
->int0Parameter
, parameters
->int1Parameter
);
6664 //The same as the previous action, except that the column parameter comes from
6665 //the target object's wisdom directly (this action is not used in the original)
6666 void GameScript::SetupWishObject(Scriptable
* Sender
, Action
* parameters
)
6668 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6669 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6672 SetupWishCore(Sender
, ((Actor
*)tar
)->GetStat(IE_WIS
), parameters
->int0Parameter
);
6675 //GemRB specific action
6676 //Sets up multiple tokens randomly (one per 2da row)
6677 //the row label column sets the token names
6678 void GameScript::SetToken2DA(Scriptable
* /*Sender*/, Action
* parameters
)
6682 ieVariable tokenname
;
6684 AutoTable
tm(parameters
->string0Parameter
);
6686 printStatus( "ERROR", LIGHT_RED
);
6687 printf( "Cannot find %s.2da.\n", parameters
->string0Parameter
);
6691 count
= tm
->GetRowCount();
6692 for(i
=0;i
<count
;i
++) {
6693 //roll a random number between 0 and column #
6694 j
= core
->Roll(1,tm
->GetColumnCount(i
),-1);
6695 strnuprcpy(tokenname
, tm
->GetRowName(i
), 32);
6696 core
->GetTokenDictionary()->SetAtCopy( tokenname
, tm
->QueryField(i
, j
) );
6700 //this is a gemrb extension for scriptable tracks
6701 void GameScript::SetTrackString(Scriptable
* Sender
, Action
* parameters
)
6703 Map
*map
= Sender
->GetCurrentArea();
6705 map
->SetTrackString(parameters
->int0Parameter
, parameters
->int1Parameter
, parameters
->int2Parameter
);
6708 void GameScript::StateOverrideFlag(Scriptable
* /*Sender*/, Action
* parameters
)
6710 core
->GetGame()->StateOverrideFlag
= parameters
->int0Parameter
;
6713 void GameScript::StateOverrideTime(Scriptable
* /*Sender*/, Action
* parameters
)
6715 core
->GetGame()->StateOverrideTime
= parameters
->int0Parameter
;
6718 void GameScript::BanterBlockFlag(Scriptable
* /*Sender*/, Action
* parameters
)
6720 core
->GetGame()->BanterBlockFlag
= parameters
->int0Parameter
;
6723 void GameScript::BanterBlockTime(Scriptable
* /*Sender*/, Action
* parameters
)
6725 core
->GetGame()->BanterBlockTime
= parameters
->int0Parameter
;