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"
38 //------------------------------------------------------------
40 //-------------------------------------------------------------
42 void GameScript::SetExtendedNight(Scriptable
* Sender
, Action
* parameters
)
44 Map
*map
=Sender
->GetCurrentArea();
45 //sets the 'can rest other' bit
46 if (parameters
->int0Parameter
) {
47 map
->AreaType
|=AT_EXTENDED_NIGHT
;
49 map
->AreaType
&=~AT_EXTENDED_NIGHT
;
53 void GameScript::SetAreaRestFlag(Scriptable
* Sender
, Action
* parameters
)
55 Map
*map
=Sender
->GetCurrentArea();
56 //sets the 'can rest other' bit
57 if (parameters
->int0Parameter
) {
58 map
->AreaType
|=AT_CAN_REST
;
60 map
->AreaType
&=~AT_CAN_REST
;
64 void GameScript::AddAreaFlag(Scriptable
* Sender
, Action
* parameters
)
66 Map
*map
=Sender
->GetCurrentArea();
67 map
->AreaFlags
|=parameters
->int0Parameter
;
70 void GameScript::RemoveAreaFlag(Scriptable
* Sender
, Action
* parameters
)
72 Map
*map
=Sender
->GetCurrentArea();
73 map
->AreaFlags
&=~parameters
->int0Parameter
;
76 void GameScript::SetAreaFlags(Scriptable
* Sender
, Action
* parameters
)
78 Map
*map
=Sender
->GetCurrentArea();
79 ieDword value
= map
->AreaFlags
;
80 HandleBitMod( value
, parameters
->int0Parameter
, parameters
->int1Parameter
);
84 void GameScript::AddAreaType(Scriptable
* Sender
, Action
* parameters
)
86 Map
*map
=Sender
->GetCurrentArea();
87 map
->AreaType
|=parameters
->int0Parameter
;
90 void GameScript::RemoveAreaType(Scriptable
* Sender
, Action
* parameters
)
92 Map
*map
=Sender
->GetCurrentArea();
93 map
->AreaType
&=~parameters
->int0Parameter
;
96 void GameScript::NoActionAtAll(Scriptable
* /*Sender*/, Action
* /*parameters*/)
101 // this action stops modal actions, so...
102 void GameScript::NoAction(Scriptable
* Sender
, Action
* /*parameters*/)
104 if (Sender
->Type
!=ST_ACTOR
) {
107 Actor
*actor
= (Actor
*) Sender
;
108 actor
->SetModal( MS_NONE
);
111 void GameScript::SG(Scriptable
* Sender
, Action
* parameters
)
113 SetVariable( Sender
, parameters
->string0Parameter
, "GLOBAL", parameters
->int0Parameter
);
116 void GameScript::SetGlobal(Scriptable
* Sender
, Action
* parameters
)
118 SetVariable( Sender
, parameters
->string0Parameter
, parameters
->int0Parameter
);
121 void GameScript::SetGlobalRandom(Scriptable
* Sender
, Action
* parameters
)
123 int max
=parameters
->int1Parameter
-parameters
->int0Parameter
+1;
125 SetVariable( Sender
, parameters
->string0Parameter
, RandomNumValue
%max
+parameters
->int0Parameter
);
127 SetVariable( Sender
, parameters
->string0Parameter
, 0);
131 void GameScript::StartTimer(Scriptable
* Sender
, Action
* parameters
)
133 Sender
->StartTimer(parameters
->int0Parameter
, parameters
->int1Parameter
);
136 void GameScript::StartRandomTimer(Scriptable
* Sender
, Action
* parameters
)
138 ieDword value
= core
->Roll(1, parameters
->int2Parameter
-parameters
->int1Parameter
, parameters
->int2Parameter
-1);
139 Sender
->StartTimer(parameters
->int0Parameter
, value
);
142 void GameScript::SetGlobalTimer(Scriptable
* Sender
, Action
* parameters
)
146 mytime
=core
->GetGame()->GameTime
; //gametime (should increase it)
147 SetVariable( Sender
, parameters
->string0Parameter
,
148 parameters
->int0Parameter
*AI_UPDATE_TIME
+ mytime
);
151 void GameScript::SetGlobalTimerRandom(Scriptable
* Sender
, Action
* parameters
)
155 int random
=parameters
->int1Parameter
-parameters
->int0Parameter
+1;
157 random
= RandomNumValue
% random
+ parameters
->int0Parameter
;
161 mytime
=core
->GetGame()->GameTime
; //gametime (should increase it)
162 SetVariable( Sender
, parameters
->string0Parameter
, random
*AI_UPDATE_TIME
+ mytime
);
165 void GameScript::SetGlobalTimerOnce(Scriptable
* Sender
, Action
* parameters
)
167 ieDword mytime
= CheckVariable( Sender
, parameters
->string0Parameter
);
171 mytime
=core
->GetGame()->GameTime
; //gametime (should increase it)
172 SetVariable( Sender
, parameters
->string0Parameter
,
173 parameters
->int0Parameter
*AI_UPDATE_TIME
+ mytime
);
176 void GameScript::RealSetGlobalTimer(Scriptable
* Sender
, Action
* parameters
)
178 ieDword mytime
=core
->GetGame()->RealTime
;
180 SetVariable( Sender
, parameters
->string0Parameter
,
181 parameters
->int0Parameter
+ mytime
);
184 void GameScript::ChangeAllegiance(Scriptable
* Sender
, Action
* parameters
)
186 Scriptable
*scr
= Sender
;
187 if (parameters
->objects
[1]) {
188 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
190 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
193 Actor
* actor
= ( Actor
* ) scr
;
194 actor
->SetBase( IE_EA
, parameters
->int0Parameter
);
197 void GameScript::ChangeGeneral(Scriptable
* Sender
, Action
* parameters
)
199 Scriptable
*scr
= Sender
;
200 if (parameters
->objects
[1]) {
201 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
203 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
206 Actor
* actor
= ( Actor
* ) scr
;
207 actor
->SetBase( IE_GENERAL
, parameters
->int0Parameter
);
210 void GameScript::ChangeRace(Scriptable
* Sender
, Action
* parameters
)
212 Scriptable
*scr
= Sender
;
213 if (parameters
->objects
[1]) {
214 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
216 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
219 Actor
* actor
= ( Actor
* ) scr
;
220 actor
->SetBase( IE_RACE
, parameters
->int0Parameter
);
223 void GameScript::ChangeClass(Scriptable
* Sender
, Action
* parameters
)
225 Scriptable
*scr
= Sender
;
226 if (parameters
->objects
[1]) {
227 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
229 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
232 Actor
* actor
= ( Actor
* ) scr
;
233 actor
->SetBase( IE_CLASS
, parameters
->int0Parameter
);
236 void GameScript::SetNamelessClass(Scriptable
* /*Sender*/, Action
* parameters
)
238 //same as Protagonist
239 Actor
* actor
= core
->GetGame()->GetPC(0, false);
240 actor
->SetBase( IE_CLASS
, parameters
->int0Parameter
);
243 void GameScript::SetNamelessDisguise(Scriptable
* Sender
, Action
* parameters
)
245 SetVariable(Sender
, "APPEARANCE", "GLOBAL", parameters
->int0Parameter
);
246 core
->SetEventFlag(EF_UPDATEANIM
);
249 void GameScript::ChangeSpecifics(Scriptable
* Sender
, Action
* parameters
)
251 Scriptable
*scr
= Sender
;
252 if (parameters
->objects
[1]) {
253 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
255 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
258 Actor
* actor
= ( Actor
* ) scr
;
259 actor
->SetBase( IE_SPECIFIC
, parameters
->int0Parameter
);
262 void GameScript::PermanentStatChange(Scriptable
* Sender
, Action
* parameters
)
264 Scriptable
*scr
= Sender
;
265 if (parameters
->objects
[1]) {
266 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
268 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
271 Actor
* actor
= ( Actor
* ) scr
;
273 switch (parameters
->int1Parameter
) {
275 value
= actor
->GetBase(parameters
->int0Parameter
);
276 value
-= parameters
->int2Parameter
;
279 value
= actor
->GetBase(parameters
->int0Parameter
);
280 value
+= parameters
->int2Parameter
;
283 default: //no idea what happens
284 value
= parameters
->int2Parameter
;
287 actor
->SetBase( parameters
->int0Parameter
, value
);
290 void GameScript::ChangeStat(Scriptable
* Sender
, Action
* parameters
)
292 Scriptable
*scr
= Sender
;
293 if (parameters
->objects
[1]) {
294 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
296 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
299 Actor
* actor
= ( Actor
* ) scr
;
300 ieDword value
= parameters
->int1Parameter
;
301 if (parameters
->int2Parameter
==1) {
302 value
+=actor
->GetBase(parameters
->int0Parameter
);
304 actor
->SetBase( parameters
->int0Parameter
, value
);
307 void GameScript::ChangeStatGlobal(Scriptable
* Sender
, Action
* parameters
)
309 Scriptable
*scr
= Sender
;
310 if (parameters
->objects
[1]) {
311 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
313 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
316 ieDword value
= (ieDword
) CheckVariable( Sender
, parameters
->string0Parameter
, parameters
->string1Parameter
);
317 Actor
* actor
= ( Actor
* ) scr
;
318 if (parameters
->int1Parameter
==1) {
319 value
+=actor
->GetBase(parameters
->int0Parameter
);
321 actor
->SetBase( parameters
->int0Parameter
, value
);
324 void GameScript::ChangeGender(Scriptable
* Sender
, Action
* parameters
)
326 Scriptable
*scr
= Sender
;
327 if (parameters
->objects
[1]) {
328 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
330 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
333 Actor
* actor
= ( Actor
* ) scr
;
334 actor
->SetBase( IE_SEX
, parameters
->int0Parameter
);
337 void GameScript::ChangeAlignment(Scriptable
* Sender
, Action
* parameters
)
339 Scriptable
*scr
= Sender
;
340 if (parameters
->objects
[1]) {
341 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
343 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
346 Actor
* actor
= ( Actor
* ) scr
;
347 actor
->SetBase( IE_ALIGNMENT
, parameters
->int0Parameter
);
350 void GameScript::SetFaction(Scriptable
* Sender
, Action
* parameters
)
352 Scriptable
*scr
= Sender
;
353 if (parameters
->objects
[1]) {
354 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
356 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
359 Actor
* actor
= ( Actor
* ) scr
;
360 actor
->SetBase( IE_FACTION
, parameters
->int0Parameter
);
363 void GameScript::SetHP(Scriptable
* Sender
, Action
* parameters
)
365 Scriptable
*scr
= Sender
;
366 if (parameters
->objects
[1]) {
367 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
369 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
372 Actor
* actor
= ( Actor
* ) scr
;
373 actor
->SetBase( IE_HITPOINTS
, parameters
->int0Parameter
);
376 void GameScript::SetHPPercent(Scriptable
* Sender
, Action
* parameters
)
378 Scriptable
*scr
= Sender
;
379 if (parameters
->objects
[1]) {
380 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
382 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
385 Actor
* actor
= ( Actor
* ) scr
;
386 actor
->NewBase( IE_HITPOINTS
, parameters
->int0Parameter
, MOD_PERCENT
);
389 void GameScript::AddHP(Scriptable
* Sender
, Action
* parameters
)
391 Scriptable
*scr
= Sender
;
392 if (parameters
->objects
[1]) {
393 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
395 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
398 Actor
* actor
= ( Actor
* ) scr
;
399 actor
->NewBase(IE_HITPOINTS
, parameters
->int0Parameter
, MOD_ADDITIVE
);
402 //this works on an object (pst)
403 //but can also work on actor itself (gemrb)
404 void GameScript::SetTeam(Scriptable
* Sender
, Action
* parameters
)
406 Scriptable
*scr
= Sender
;
407 if (parameters
->objects
[1]) {
408 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
410 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
413 Actor
* actor
= ( Actor
* ) scr
;
414 actor
->SetBase( IE_TEAM
, parameters
->int0Parameter
);
417 //this works on an object (gemrb)
418 //or on Myself if object isn't given (iwd2)
419 void GameScript::SetTeamBit(Scriptable
* Sender
, Action
* parameters
)
421 Scriptable
*scr
= Sender
;
422 if (parameters
->objects
[1]) {
423 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
425 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
428 Actor
* actor
= ( Actor
* ) scr
;
429 if (parameters
->int1Parameter
) {
430 actor
->SetBase( IE_TEAM
, actor
->GetStat(IE_TEAM
) | parameters
->int0Parameter
);
432 actor
->SetBase( IE_TEAM
, actor
->GetStat(IE_TEAM
) & ~parameters
->int0Parameter
);
436 void GameScript::TriggerActivation(Scriptable
* Sender
, Action
* parameters
)
440 if (!parameters
->objects
[1]) {
443 ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
445 if (!ip
|| (ip
->Type
!=ST_TRIGGER
&& ip
->Type
!=ST_TRAVEL
&& ip
->Type
!=ST_PROXIMITY
)) {
446 printf("Script error: No Trigger Named \"%s\"\n", parameters
->objects
[1]->objectName
);
449 InfoPoint
*trigger
= (InfoPoint
*) ip
;
450 if ( parameters
->int0Parameter
!= 0 ) {
451 trigger
->Flags
&= ~TRAP_DEACTIVATED
;
453 trigger
->Flags
|= TRAP_DEACTIVATED
;
457 void GameScript::FadeToColor(Scriptable
* Sender
, Action
* parameters
)
459 core
->timer
->SetFadeToColor( parameters
->pointParameter
.x
);
460 // Sender->SetWait( parameters->pointParameter.x );
461 Sender
->ReleaseCurrentAction(); // todo, blocking?
464 void GameScript::FadeFromColor(Scriptable
* Sender
, Action
* parameters
)
466 core
->timer
->SetFadeFromColor( parameters
->pointParameter
.x
);
467 // Sender->SetWait( parameters->pointParameter.x );
468 Sender
->ReleaseCurrentAction(); // todo, blocking?
471 void GameScript::FadeToAndFromColor(Scriptable
* Sender
, Action
* parameters
)
473 core
->timer
->SetFadeToColor( parameters
->pointParameter
.x
);
474 core
->timer
->SetFadeFromColor( parameters
->pointParameter
.x
);
475 // Sender->SetWait( parameters->pointParameter.x<<1 ); //multiply by 2
476 Sender
->ReleaseCurrentAction(); // todo, blocking?
479 void GameScript::JumpToPoint(Scriptable
* Sender
, Action
* parameters
)
481 if (Sender
->Type
!= ST_ACTOR
) {
484 Actor
* ab
= ( Actor
* ) Sender
;
485 ab
->SetPosition( parameters
->pointParameter
, true );
488 void GameScript::JumpToPointInstant(Scriptable
* Sender
, Action
* parameters
)
490 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
491 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
494 Actor
* ab
= ( Actor
* ) tar
;
495 ab
->SetPosition( parameters
->pointParameter
, true );
498 /** instant jump to location saved in stats */
499 /** default subject is the current actor */
500 void GameScript::JumpToSavedLocation(Scriptable
* Sender
, Action
* parameters
)
502 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
506 if (tar
->Type
!= ST_ACTOR
) {
509 Actor
*actor
= (Actor
*) tar
;
510 Point
p((short) actor
->GetStat(IE_SAVEDXPOS
), (short) actor
->GetStat(IE_SAVEDYPOS
) );
511 actor
->SetPosition(p
, true );
512 actor
->SetOrientation( actor
->GetStat(IE_SAVEDFACE
), false );
515 void GameScript::JumpToObject(Scriptable
* Sender
, Action
* parameters
)
517 if (Sender
->Type
!= ST_ACTOR
) {
520 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
525 const Map
*map
= tar
->GetCurrentArea();
528 if (parameters
->string0Parameter
[0]) {
529 CreateVisualEffectCore(Sender
, Sender
->Pos
, parameters
->string0Parameter
, 0);
531 MoveBetweenAreasCore( (Actor
*) Sender
, map
->GetScriptName(), tar
->Pos
, -1, true);
535 void GameScript::TeleportParty(Scriptable
* /*Sender*/, Action
* parameters
)
537 Game
*game
= core
->GetGame();
538 int i
= game
->GetPartySize(false);
540 Actor
*tar
= game
->GetPC(i
, false);
541 MoveBetweenAreasCore( tar
, parameters
->string1Parameter
,
542 parameters
->pointParameter
, -1, true);
546 //this is unfinished, maybe the original moves actors too?
548 void GameScript::MoveToExpansion(Scriptable
* Sender
, Action
* /*parameters*/)
550 Game
*game
= core
->GetGame();
552 game
->SetExpansion(1);
553 core
->GetDictionary()->SetAt( "PlayMode", 2 );
554 //TODO: set the new world map
556 int i
= game
->GetPartySize(false);
558 Actor
*actor
= game
->GetPC(i
, false);
559 game
->InitActorPos(actor
);
562 SaveGameIterator
*sg
= core
->GetSaveGameIterator();
566 core
->SetEventFlag(EF_MASTERSCRIPT
);
567 Sender
->ReleaseCurrentAction();
570 //add some animation effects too?
571 void GameScript::ExitPocketPlane(Scriptable
* /*Sender*/, Action
* /*parameters*/)
573 Game
*game
= core
->GetGame();
574 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
575 Actor
* act
= game
->GetPC( i
, false );
577 if (game
->GetPlaneLocationCount() <= (unsigned int)i
) {
578 // what are we meant to do here?
579 printf("argh, couldn't restore party member %d!", i
+ 1);
582 GAMLocationEntry
*gle
= game
->GetPlaneLocationEntry(i
);
583 MoveBetweenAreasCore(act
, gle
->AreaResRef
, gle
->Pos
, -1, true);
587 // presumably this is correct
588 game
->ClearPlaneLocations();
591 //moves pcs and npcs from an area to another area
592 void GameScript::MoveGlobalsTo(Scriptable
* /*Sender*/, Action
* parameters
)
594 Game
*game
= core
->GetGame();
595 int i
= game
->GetPartySize(false);
597 Actor
*tar
= game
->GetPC(i
, false);
598 //if the actor isn't in the area, we don't care
599 if (strnicmp(tar
->Area
, parameters
->string0Parameter
,8) ) {
602 MoveBetweenAreasCore( tar
, parameters
->string1Parameter
,
603 parameters
->pointParameter
, -1, true);
605 i
= game
->GetNPCCount();
607 Actor
*tar
= game
->GetNPC(i
);
608 //if the actor isn't in the area, we don't care
609 if (strnicmp(tar
->Area
, parameters
->string0Parameter
,8) ) {
612 MoveBetweenAreasCore( tar
, parameters
->string1Parameter
,
613 parameters
->pointParameter
, -1, true);
617 void GameScript::MoveGlobal(Scriptable
* Sender
, Action
* parameters
)
619 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
620 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
624 MoveBetweenAreasCore( (Actor
*) tar
, parameters
->string0Parameter
,
625 parameters
->pointParameter
, -1, true);
628 //we also allow moving to door, container
629 void GameScript::MoveGlobalObject(Scriptable
* Sender
, Action
* parameters
)
631 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
632 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
635 Scriptable
* to
= GetActorFromObject( Sender
, parameters
->objects
[2] );
639 const Map
*map
= to
->GetCurrentArea();
642 MoveBetweenAreasCore( (Actor
*) tar
, map
->GetScriptName(),
647 void GameScript::MoveGlobalObjectOffScreen(Scriptable
* Sender
, Action
* parameters
)
649 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
650 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
653 Scriptable
* to
= GetActorFromObject( Sender
, parameters
->objects
[2] );
657 MoveBetweenAreasCore( (Actor
*) tar
, parameters
->string0Parameter
,
661 //don't use offset from Sender
662 void GameScript::CreateCreature(Scriptable
* Sender
, Action
* parameters
)
664 CreateCreatureCore( Sender
, parameters
, CC_CHECK_IMPASSABLE
|CC_CHECK_OVERLAP
|CC_SCRIPTNAME
);
667 //another highly redundant action
668 void GameScript::CreateCreatureDoor(Scriptable
* Sender
, Action
* parameters
)
670 //we hack this to death
671 strcpy(parameters
->string1Parameter
, "SPDIMNDR");
672 CreateCreatureCore( Sender
, parameters
, CC_CHECK_IMPASSABLE
|CC_CHECK_OVERLAP
| CC_PLAY_ANIM
);
675 //another highly redundant action
676 void GameScript::CreateCreatureObjectDoor(Scriptable
* Sender
, Action
* parameters
)
678 //we hack this to death
679 strcpy(parameters
->string1Parameter
, "SPDIMNDR");
680 CreateCreatureCore( Sender
, parameters
, CC_OFFSET
| CC_CHECK_IMPASSABLE
|CC_CHECK_OVERLAP
| CC_PLAY_ANIM
);
683 //don't use offset from Sender
684 void GameScript::CreateCreatureImpassable(Scriptable
* Sender
, Action
* parameters
)
686 CreateCreatureCore( Sender
, parameters
, CC_CHECK_OVERLAP
);
689 void GameScript::CreateCreatureImpassableAllowOverlap(Scriptable
* Sender
, Action
* parameters
)
691 CreateCreatureCore( Sender
, parameters
, 0 );
694 //use offset from Sender
695 void GameScript::CreateCreatureAtFeet(Scriptable
* Sender
, Action
* parameters
)
697 CreateCreatureCore( Sender
, parameters
, CC_OFFSET
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
);
700 void GameScript::CreateCreatureOffScreen(Scriptable
* Sender
, Action
* parameters
)
702 CreateCreatureCore( Sender
, parameters
, CC_OFFSCREEN
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
);
705 //creates copy at actor, plays animation
706 void GameScript::CreateCreatureObjectCopy(Scriptable
* Sender
, Action
* parameters
)
708 CreateCreatureCore( Sender
, parameters
, CC_OBJECT
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
| CC_COPY
| CC_PLAY_ANIM
);
711 //creates copy at absolute point
712 void GameScript::CreateCreatureCopyPoint(Scriptable
* Sender
, Action
* parameters
)
714 CreateCreatureCore( Sender
, parameters
, CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
| CC_COPY
| CC_PLAY_ANIM
);
717 //this is the same, object + offset
718 //using this for simple createcreatureobject, (0 offsets)
719 //createcreatureobjecteffect may have animation
720 void GameScript::CreateCreatureObjectOffset(Scriptable
* Sender
, Action
* parameters
)
722 CreateCreatureCore( Sender
, parameters
, CC_OBJECT
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
| CC_PLAY_ANIM
);
725 void GameScript::CreateCreatureObjectOffScreen(Scriptable
* Sender
, Action
* parameters
)
727 CreateCreatureCore( Sender
, parameters
, CC_OFFSCREEN
| CC_OBJECT
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
);
730 //I think this simply removes the cursor and hides the gui without disabling scripts
731 //See Interface::SetCutSceneMode
732 void GameScript::SetCursorState(Scriptable
* /*Sender*/, Action
* parameters
)
734 int active
= parameters
->int0Parameter
;
736 Game
*game
= core
->GetGame();
738 game
->ControlStatus
|= CS_HIDEGUI
;
740 game
->ControlStatus
&= ~CS_HIDEGUI
;
742 core
->SetEventFlag(EF_CONTROL
);
743 core
->GetVideoDriver()->SetMouseEnabled(!active
);
746 void GameScript::StartCutSceneMode(Scriptable
* /*Sender*/, Action
* /*parameters*/)
748 core
->SetCutSceneMode( true );
751 void GameScript::EndCutSceneMode(Scriptable
* /*Sender*/, Action
* /*parameters*/)
753 core
->SetCutSceneMode( false );
756 void GameScript::StartCutScene(Scriptable
* Sender
, Action
* parameters
)
758 GameScript
* gs
= new GameScript( parameters
->string0Parameter
, ST_GLOBAL
);
760 gs
->EvaluateAllBlocks();
762 Sender
->ClearCutsceneID();
765 void GameScript::CutSceneID(Scriptable
* Sender
, Action
* parameters
)
767 Sender
->SetCutsceneID( GetActorFromObject( Sender
, parameters
->objects
[1] ) );
768 if (InDebug
&ID_CUTSCENE
) {
769 if (!Sender
->GetCutsceneID()) {
770 printMessage("GameScript","Failed to set CutSceneID!\n",YELLOW
);
771 parameters
->objects
[1]->Dump();
776 void GameScript::Enemy(Scriptable
* Sender
, Action
* /*parameters*/)
778 if (Sender
->Type
!= ST_ACTOR
) {
781 Actor
* actor
= ( Actor
* ) Sender
;
782 actor
->SetBase( IE_EA
, EA_ENEMY
);
785 void GameScript::Ally(Scriptable
* Sender
, Action
* /*parameters*/)
787 if (Sender
->Type
!= ST_ACTOR
) {
790 Actor
* actor
= ( Actor
* ) Sender
;
791 actor
->SetBase( IE_EA
, EA_ALLY
);
794 /** GemRB extension: you can replace baldur.bcs */
795 void GameScript::ChangeAIScript(Scriptable
* Sender
, Action
* parameters
)
797 if (parameters
->int0Parameter
>7) {
800 if (Sender
->Type
!=ST_ACTOR
&& parameters
->int0Parameter
) {
803 Sender
->SetScript( parameters
->string0Parameter
, parameters
->int0Parameter
, false );
806 void GameScript::ForceAIScript(Scriptable
* Sender
, Action
* parameters
)
808 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
809 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
812 Actor
* actor
= ( Actor
* ) tar
;
813 //changeaiscript clears the queue, i believe
814 // actor->ClearActions();
815 actor
->SetScript( parameters
->string0Parameter
, parameters
->int0Parameter
, false );
818 void GameScript::SetPlayerSound(Scriptable
* Sender
, Action
* parameters
)
820 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
821 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
824 Actor
* actor
= ( Actor
* ) tar
;
825 actor
->StrRefs
[parameters
->int0Parameter
]=parameters
->int1Parameter
;
828 //this one works only on real actors, they got constants
829 void GameScript::VerbalConstantHead(Scriptable
* Sender
, Action
* parameters
)
831 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
832 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
835 DisplayStringCore( tar
, parameters
->int0Parameter
, DS_HEAD
|DS_CONSOLE
|DS_CONST
);
838 void GameScript::VerbalConstant(Scriptable
* Sender
, Action
* parameters
)
840 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
841 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
844 DisplayStringCore( tar
, parameters
->int0Parameter
, DS_CONSOLE
|DS_CONST
);
848 void GameScript::SaveLocation(Scriptable
* Sender
, Action
* parameters
)
850 ieDword value
= parameters
->pointParameter
.asDword();
851 if (!parameters
->string0Parameter
[0]) {
852 strcpy(parameters
->string0Parameter
,"LOCALSsavedlocation");
854 printf("SaveLocation: %s\n",parameters
->string0Parameter
);
855 SetVariable(Sender
, parameters
->string0Parameter
, value
);
858 //PST:has parameters, IWD2: no params
859 void GameScript::SetSavedLocation(Scriptable
* Sender
, Action
* parameters
)
861 if (Sender
->Type
!=ST_ACTOR
) {
864 Actor
*actor
= (Actor
*) Sender
;
866 if (parameters
->pointParameter
.isnull()) {
867 actor
->SetBase(IE_SAVEDXPOS
, actor
->Pos
.x
);
868 actor
->SetBase(IE_SAVEDYPOS
, actor
->Pos
.y
);
869 actor
->SetBase(IE_SAVEDFACE
, actor
->GetOrientation());
873 actor
->SetBase(IE_SAVEDXPOS
, parameters
->pointParameter
.x
);
874 actor
->SetBase(IE_SAVEDYPOS
, parameters
->pointParameter
.y
);
875 actor
->SetBase(IE_SAVEDFACE
, parameters
->int0Parameter
);
877 //IWD2, sets the homepoint int0,int1,int2
878 void GameScript::SetSavedLocationPoint(Scriptable
* Sender
, Action
* parameters
)
880 if (Sender
->Type
!=ST_ACTOR
) {
883 Actor
*actor
= (Actor
*) Sender
;
884 actor
->SetBase(IE_SAVEDXPOS
, parameters
->int0Parameter
);
885 actor
->SetBase(IE_SAVEDYPOS
, parameters
->int1Parameter
);
886 actor
->SetBase(IE_SAVEDFACE
, parameters
->int2Parameter
);
888 //IWD2, sets the homepoint P
889 void GameScript::SetStartPos(Scriptable
* Sender
, Action
* parameters
)
891 if (Sender
->Type
!=ST_ACTOR
) {
894 Actor
*actor
= (Actor
*) Sender
;
895 actor
->SetBase(IE_SAVEDXPOS
, parameters
->pointParameter
.x
);
896 actor
->SetBase(IE_SAVEDYPOS
, parameters
->pointParameter
.y
);
897 actor
->SetBase(IE_SAVEDFACE
, parameters
->int0Parameter
);
900 void GameScript::SaveObjectLocation(Scriptable
* Sender
, Action
* parameters
)
902 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
906 ieDword value
= tar
->Pos
.asDword();
907 if (!parameters
->string0Parameter
[0]) {
908 strcpy(parameters
->string0Parameter
,"LOCALSsavedlocation");
910 printf("SaveLocation: %s\n",parameters
->string0Parameter
);
911 SetVariable(Sender
, parameters
->string0Parameter
, value
);
914 /** you may omit the string0Parameter, in this case this will be a */
915 /** CreateCreatureAtSavedLocation */
916 void GameScript::CreateCreatureAtLocation(Scriptable
* Sender
, Action
* parameters
)
918 if (!parameters
->string0Parameter
[0]) {
919 strcpy(parameters
->string0Parameter
,"LOCALSsavedlocation");
921 ieDword value
= CheckVariable(Sender
, parameters
->string0Parameter
);
922 parameters
->pointParameter
.y
= (ieWord
) (value
& 0xffff);
923 parameters
->pointParameter
.x
= (ieWord
) (value
>> 16);
924 CreateCreatureCore(Sender
, parameters
, CC_CHECK_IMPASSABLE
|CC_STRING1
);
927 void GameScript::WaitRandom(Scriptable
* Sender
, Action
* parameters
)
929 if (!Sender
->CurrentActionState
) {
930 int width
= parameters
->int1Parameter
-parameters
->int0Parameter
;
932 width
= parameters
->int0Parameter
;
934 width
= rand() % width
+ parameters
->int0Parameter
;
936 Sender
->CurrentActionState
= width
* AI_UPDATE_TIME
;
938 Sender
->CurrentActionState
--;
941 if (!Sender
->CurrentActionState
) {
942 Sender
->ReleaseCurrentAction();
945 assert(Sender
->CurrentActionState
>= 0);
948 void GameScript::Wait(Scriptable
* Sender
, Action
* parameters
)
950 if (!Sender
->CurrentActionState
) {
951 Sender
->CurrentActionState
= parameters
->int0Parameter
* AI_UPDATE_TIME
;
953 Sender
->CurrentActionState
--;
956 if (!Sender
->CurrentActionState
) {
957 Sender
->ReleaseCurrentAction();
960 assert(Sender
->CurrentActionState
>= 0);
963 void GameScript::SmallWait(Scriptable
* Sender
, Action
* parameters
)
965 if (!Sender
->CurrentActionState
) {
966 Sender
->CurrentActionState
= parameters
->int0Parameter
;
968 Sender
->CurrentActionState
--;
971 if (!Sender
->CurrentActionState
) {
972 Sender
->ReleaseCurrentAction();
975 assert(Sender
->CurrentActionState
>= 0);
978 void GameScript::SmallWaitRandom(Scriptable
* Sender
, Action
* parameters
)
980 if (!Sender
->CurrentActionState
) {
981 int random
= parameters
->int1Parameter
- parameters
->int0Parameter
;
985 Sender
->CurrentActionState
= rand() % random
+ parameters
->int0Parameter
;
987 Sender
->CurrentActionState
--;
990 if (!Sender
->CurrentActionState
) {
991 Sender
->ReleaseCurrentAction();
994 assert(Sender
->CurrentActionState
>= 0);
997 void GameScript::MoveViewPoint(Scriptable
* Sender
, Action
* parameters
)
999 core
->timer
->SetMoveViewPort( parameters
->pointParameter
.x
, parameters
->pointParameter
.y
, parameters
->int0Parameter
<<1, true );
1000 Sender
->SetWait(1); // todo, blocking?
1001 Sender
->ReleaseCurrentAction(); // todo, blocking?
1004 void GameScript::MoveViewObject(Scriptable
* Sender
, Action
* parameters
)
1006 Scriptable
* scr
= GetActorFromObject( Sender
, parameters
->objects
[1]);
1010 core
->timer
->SetMoveViewPort( scr
->Pos
.x
, scr
->Pos
.y
, parameters
->int0Parameter
<<1, true );
1011 Sender
->SetWait(1); // todo, blocking?
1012 Sender
->ReleaseCurrentAction(); // todo, blocking?
1015 void GameScript::AddWayPoint(Scriptable
* Sender
, Action
* parameters
)
1017 if (Sender
->Type
!= ST_ACTOR
) {
1020 Actor
* actor
= ( Actor
* ) Sender
;
1021 actor
->AddWayPoint( parameters
->pointParameter
);
1022 // this is marked as AF_BLOCKING (and indeed AddWayPoint causes moves),
1023 // but this probably needs more thought
1024 Sender
->ReleaseCurrentAction();
1027 void GameScript::MoveToPointNoRecticle(Scriptable
* Sender
, Action
* parameters
)
1029 if (Sender
->Type
!= ST_ACTOR
) {
1030 Sender
->ReleaseCurrentAction();
1033 Actor
*actor
= ( Actor
* ) Sender
;
1034 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1035 actor
->WalkTo( parameters
->pointParameter
, IF_NORECTICLE
, 0 );
1037 if (!actor
->InMove()) {
1038 // we should probably instead keep retrying until we reach dest
1039 Sender
->ReleaseCurrentAction();
1043 void GameScript::MoveToPointNoInterrupt(Scriptable
* Sender
, Action
* parameters
)
1045 if (Sender
->Type
!= ST_ACTOR
) {
1046 Sender
->ReleaseCurrentAction();
1049 Actor
* actor
= ( Actor
* ) Sender
;
1050 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1051 actor
->WalkTo( parameters
->pointParameter
, IF_NOINT
, 0 );
1053 // should we always force IF_NOINT here?
1054 if (!actor
->InMove()) {
1055 // we should probably instead keep retrying until we reach dest
1057 Sender
->ReleaseCurrentAction();
1061 void GameScript::RunToPointNoRecticle(Scriptable
* Sender
, Action
* parameters
)
1063 if (Sender
->Type
!= ST_ACTOR
) {
1064 Sender
->ReleaseCurrentAction();
1067 Actor
* actor
= ( Actor
* ) Sender
;
1068 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1069 actor
->WalkTo( parameters
->pointParameter
, IF_NORECTICLE
|IF_RUNNING
, 0 );
1071 if (!actor
->InMove()) {
1072 // we should probably instead keep retrying until we reach dest
1073 Sender
->ReleaseCurrentAction();
1077 void GameScript::RunToPoint(Scriptable
* Sender
, Action
* parameters
)
1079 if (Sender
->Type
!= ST_ACTOR
) {
1080 Sender
->ReleaseCurrentAction();
1083 Actor
* actor
= ( Actor
* ) Sender
;
1084 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1085 actor
->WalkTo( parameters
->pointParameter
, IF_RUNNING
, 0 );
1087 if (!actor
->InMove()) {
1088 // we should probably instead keep retrying until we reach dest
1089 Sender
->ReleaseCurrentAction();
1093 //movetopoint until timer is down or target reached
1094 void GameScript::TimedMoveToPoint(Scriptable
* Sender
, Action
* parameters
)
1096 if (Sender
->Type
!= ST_ACTOR
) {
1097 Sender
->ReleaseCurrentAction();
1100 if (parameters
->int0Parameter
<=0) {
1101 Sender
->ReleaseCurrentAction();
1104 Actor
*actor
= (Actor
*) Sender
;
1106 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1107 actor
->WalkTo( parameters
->pointParameter
, parameters
->int1Parameter
,0 );
1110 //hopefully this hack will prevent lockups
1111 if (!actor
->InMove()) {
1112 // we should probably instead keep retrying until we reach dest
1113 Sender
->ReleaseCurrentAction();
1117 //repeat movement...
1118 if (parameters
->int0Parameter
>0) {
1119 Action
*newaction
= ParamCopyNoOverride(parameters
);
1120 newaction
->int0Parameter
--;
1121 actor
->AddActionInFront(newaction
);
1125 Sender
->ReleaseCurrentAction();
1128 void GameScript::MoveToPoint(Scriptable
* Sender
, Action
* parameters
)
1130 if (Sender
->Type
!= ST_ACTOR
) {
1131 Sender
->ReleaseCurrentAction();
1134 Actor
* actor
= ( Actor
* ) Sender
;
1135 //WalkTo could release the current action, so we need this
1136 ieDword tmp
= (ieDword
) parameters
->int0Parameter
;
1137 //InMove can clear destination, so we need to save it
1138 Point dest
= actor
->Destination
;
1140 // try the actual move, if we are not already moving there
1141 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1142 actor
->WalkTo( parameters
->pointParameter
, 0, tmp
);
1143 dest
= actor
->Destination
;
1146 // give up if we can't move there (no path was found)
1147 if (!actor
->InMove()) {
1148 // we should probably instead keep retrying until we reach dest
1149 Sender
->ReleaseCurrentAction();
1153 if (!actor
->InMove()) {
1154 //can't reach target, movement failed
1155 //we have to use tmp-1 because the distance required might be 0,
1156 //so in GoNearAndRetry we add 1 to distance
1157 if (Distance(dest
,actor
)>tmp
-1) {
1158 //to prevent deadlocks, we free the action
1159 //which caused MoveToPoint in the first place
1160 Sender
->PopNextAction();
1166 //bg2, jumps to saved location in variable
1167 void GameScript::MoveToSavedLocation(Scriptable
* Sender
, Action
* parameters
)
1169 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1173 if (tar
->Type
!= ST_ACTOR
) {
1174 Sender
->ReleaseCurrentAction();
1179 Actor
* actor
= ( Actor
* ) tar
;
1180 ieDword value
= (ieDword
) CheckVariable( Sender
, parameters
->string0Parameter
);
1182 actor
->SetPosition(p
, true );
1183 Sender
->ReleaseCurrentAction();
1185 /** iwd2 returntosavedlocation (with stats) */
1186 /** pst returntosavedplace */
1187 /** use Sender as default subject */
1188 void GameScript::ReturnToSavedLocation(Scriptable
* Sender
, Action
* parameters
)
1190 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
1194 if (tar
->Type
!= ST_ACTOR
) {
1195 Sender
->ReleaseCurrentAction();
1199 Actor
* actor
= ( Actor
* ) tar
;
1200 Point
p((short) actor
->GetBase(IE_SAVEDXPOS
),(short) actor
->GetBase(IE_SAVEDYPOS
) );
1202 Sender
->ReleaseCurrentAction();
1205 if (!actor
->InMove() || actor
->Destination
!= p
) {
1206 actor
->WalkTo( p
, 0, 0 );
1208 if (!actor
->InMove()) {
1209 // we should probably instead keep retrying until we reach dest
1210 Sender
->ReleaseCurrentAction();
1215 void GameScript::RunToSavedLocation(Scriptable
* Sender
, Action
* parameters
)
1217 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
1221 if (tar
->Type
!= ST_ACTOR
) {
1222 Sender
->ReleaseCurrentAction();
1226 Actor
* actor
= ( Actor
* ) tar
;
1227 Point
p((short) actor
->GetBase(IE_SAVEDXPOS
),(short) actor
->GetBase(IE_SAVEDYPOS
) );
1229 Sender
->ReleaseCurrentAction();
1232 if (!actor
->InMove() || actor
->Destination
!= p
) {
1233 actor
->WalkTo( p
, IF_RUNNING
, 0 );
1235 if (!actor
->InMove()) {
1236 // we should probably instead keep retrying until we reach dest
1237 Sender
->ReleaseCurrentAction();
1242 void GameScript::ReturnToSavedLocationDelete(Scriptable
* Sender
, Action
* parameters
)
1244 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
1248 if (tar
->Type
!= ST_ACTOR
) {
1249 Sender
->ReleaseCurrentAction();
1253 Actor
* actor
= ( Actor
* ) tar
;
1254 Point
p((short) actor
->GetBase(IE_SAVEDXPOS
),(short) actor
->GetBase(IE_SAVEDYPOS
) );
1255 actor
->SetBase(IE_SAVEDXPOS
,0);
1256 actor
->SetBase(IE_SAVEDYPOS
,0);
1258 Sender
->ReleaseCurrentAction();
1261 if (!actor
->InMove() || actor
->Destination
!= p
) {
1262 actor
->WalkTo( p
, 0, 0 );
1265 if (!actor
->InMove()) {
1266 // we should probably instead keep retrying until we reach dest
1267 Sender
->ReleaseCurrentAction();
1271 void GameScript::MoveToObjectNoInterrupt(Scriptable
* Sender
, Action
* parameters
)
1273 MoveToObjectCore(Sender
, parameters
, IF_NOINT
, false);
1276 void GameScript::RunToObject(Scriptable
* Sender
, Action
* parameters
)
1278 MoveToObjectCore(Sender
, parameters
, IF_RUNNING
, false);
1281 void GameScript::MoveToObject(Scriptable
* Sender
, Action
* parameters
)
1283 MoveToObjectCore(Sender
, parameters
, 0, false);
1286 void GameScript::MoveToObjectUntilSee(Scriptable
* Sender
, Action
* parameters
)
1288 MoveToObjectCore(Sender
, parameters
, 0, true);
1291 void GameScript::MoveToObjectFollow(Scriptable
* Sender
, Action
* parameters
)
1293 if (Sender
->Type
!= ST_ACTOR
) {
1294 Sender
->ReleaseCurrentAction();
1297 Scriptable
* target
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
1299 Sender
->ReleaseCurrentAction();
1302 Actor
* actor
= ( Actor
* ) Sender
;
1303 //follow leader from a distance of 5
1304 //could also follow the leader with a point offset
1305 if (target
->Type
==ST_ACTOR
) {
1306 actor
->SetLeader( (Actor
*) target
, 5);
1308 MoveNearerTo(Sender
, target
, MAX_OPERATING_DISTANCE
);
1311 void GameScript::StorePartyLocation(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1313 Game
*game
= core
->GetGame();
1314 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
1315 Actor
* act
= game
->GetPC( i
, false );
1316 GAMLocationEntry
*gle
= game
->GetSavedLocationEntry(i
);
1318 gle
->Pos
= act
->Pos
;
1319 memcpy(gle
->AreaResRef
, act
->Area
, 9);
1324 void GameScript::RestorePartyLocation(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1326 Game
*game
= core
->GetGame();
1327 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
1328 Actor
* act
= game
->GetPC( i
, false );
1330 if (game
->GetSavedLocationCount() <= (unsigned int)i
) {
1331 // what are we meant to do here?
1332 printf("argh, couldn't restore party member %d!", i
+ 1);
1335 GAMLocationEntry
*gle
= game
->GetSavedLocationEntry(i
);
1336 MoveBetweenAreasCore(act
, gle
->AreaResRef
, gle
->Pos
, -1, true);
1340 // presumably this is correct
1341 game
->ClearSavedLocations();
1344 void GameScript::MoveToCenterOfScreen(Scriptable
* Sender
, Action
* /*parameters*/)
1346 if (Sender
->Type
!= ST_ACTOR
) {
1347 Sender
->ReleaseCurrentAction();
1350 Region vp
= core
->GetVideoDriver()->GetViewport();
1351 Actor
* actor
= ( Actor
* ) Sender
;
1352 Point
p((short) (vp
.x
+vp
.w
/2), (short) (vp
.y
+vp
.h
/2) );
1353 if (!actor
->InMove() || actor
->Destination
!= p
) {
1354 actor
->WalkTo( p
, IF_NOINT
, 0 );
1356 if (!actor
->InMove()) {
1357 // we should probably instead keep retrying until we reach dest
1358 Sender
->ReleaseCurrentAction();
1362 void GameScript::MoveToOffset(Scriptable
* Sender
, Action
* parameters
)
1364 if (Sender
->Type
!= ST_ACTOR
) {
1365 Sender
->ReleaseCurrentAction();
1368 Actor
* actor
= ( Actor
* ) Sender
;
1369 Point
p(Sender
->Pos
.x
+parameters
->pointParameter
.x
, Sender
->Pos
.y
+parameters
->pointParameter
.y
);
1370 if (!actor
->InMove() || actor
->Destination
!= p
) {
1371 actor
->WalkTo( p
, 0, 0 );
1373 if (!actor
->InMove()) {
1374 // we should probably instead keep retrying until we reach dest
1375 Sender
->ReleaseCurrentAction();
1379 void GameScript::RunAwayFrom(Scriptable
* Sender
, Action
* parameters
)
1381 if (Sender
->Type
!= ST_ACTOR
) {
1382 Sender
->ReleaseCurrentAction();
1385 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
1386 Sender
->ReleaseCurrentAction();
1389 Actor
* actor
= ( Actor
* ) Sender
;
1390 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
1392 Sender
->ReleaseCurrentAction();
1395 //TODO: actor could use travel areas
1396 // we should be using int0Parameter for the timing here, not distance
1397 if (!actor
->InMove()) {
1398 // we should make sure our existing walk is a 'run away', or fix moving/path code
1399 actor
->RunAwayFrom( tar
->Pos
, parameters
->int0Parameter
, false);
1402 //repeat movement...
1403 if (parameters
->int0Parameter
>0) {
1404 Action
*newaction
= ParamCopyNoOverride(parameters
);
1405 newaction
->int0Parameter
--;
1406 actor
->AddActionInFront(newaction
);
1410 Sender
->ReleaseCurrentAction();
1413 void GameScript::RunAwayFromNoLeaveArea(Scriptable
* Sender
, Action
* parameters
)
1415 if (Sender
->Type
!= ST_ACTOR
) {
1416 Sender
->ReleaseCurrentAction();
1419 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
1420 Sender
->ReleaseCurrentAction();
1423 Actor
* actor
= ( Actor
* ) Sender
;
1424 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
1426 Sender
->ReleaseCurrentAction();
1429 // we should be using int0Parameter for the timing here, not distance
1430 if (!actor
->InMove()) {
1431 // we should make sure our existing walk is a 'run away', or fix moving/path code
1432 actor
->RunAwayFrom( tar
->Pos
, parameters
->int0Parameter
, false);
1435 //repeat movement...
1436 if (parameters
->int0Parameter
>0) {
1437 Action
*newaction
= ParamCopyNoOverride(parameters
);
1438 newaction
->int0Parameter
--;
1439 actor
->AddActionInFront(newaction
);
1443 Sender
->ReleaseCurrentAction();
1446 void GameScript::RunAwayFromNoInterrupt(Scriptable
* Sender
, Action
* parameters
)
1448 if (Sender
->Type
!= ST_ACTOR
) {
1449 Sender
->ReleaseCurrentAction();
1452 //i believe being dead still interrupts this action
1453 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
1454 Sender
->ReleaseCurrentAction();
1457 Actor
* actor
= ( Actor
* ) Sender
;
1458 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
1460 Sender
->ReleaseCurrentAction();
1463 //actor->InternalFlags|=IF_NOINT;
1464 actor
->NoInterrupt();
1465 // we should be using int0Parameter for the timing here, not distance
1466 if (!actor
->InMove()) {
1467 // we should make sure our existing walk is a 'run away', or fix moving/path code
1468 actor
->RunAwayFrom( tar
->Pos
, parameters
->int0Parameter
, false);
1471 //repeat movement...
1472 if (parameters
->int0Parameter
>0) {
1473 Action
*newaction
= ParamCopyNoOverride(parameters
);
1474 newaction
->int0Parameter
--;
1475 actor
->AddActionInFront(newaction
);
1481 Sender
->ReleaseCurrentAction();
1484 void GameScript::RunAwayFromPoint(Scriptable
* Sender
, Action
* parameters
)
1486 if (Sender
->Type
!= ST_ACTOR
) {
1487 Sender
->ReleaseCurrentAction();
1490 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
1491 Sender
->ReleaseCurrentAction();
1494 Actor
* actor
= ( Actor
* ) Sender
;
1495 // we should be using int0Parameter for the timing here, not distance?
1496 if (!actor
->InMove()) {
1497 // we should make sure our existing walk is a 'run away', or fix moving/path code
1498 actor
->RunAwayFrom( parameters
->pointParameter
, parameters
->int0Parameter
, false);
1501 //repeat movement...
1502 if (parameters
->int0Parameter
>0) {
1503 Action
*newaction
= ParamCopyNoOverride(parameters
);
1504 newaction
->int0Parameter
--;
1505 actor
->AddActionInFront(newaction
);
1509 Sender
->ReleaseCurrentAction();
1512 void GameScript::DisplayStringNoName(Scriptable
* Sender
, Action
* parameters
)
1514 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1]);
1518 if (Sender
->Type
==ST_ACTOR
) {
1519 DisplayStringCore( target
, parameters
->int0Parameter
, DS_CONSOLE
|DS_NONAME
);
1521 DisplayStringCore( target
, parameters
->int0Parameter
, DS_AREA
|DS_NONAME
);
1525 void GameScript::DisplayStringNoNameHead(Scriptable
* Sender
, Action
* parameters
)
1527 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1532 DisplayStringCore( target
, parameters
->int0Parameter
, DS_HEAD
|DS_CONSOLE
|DS_NONAME
);
1535 //display message over current script owner
1536 void GameScript::DisplayMessage(Scriptable
* Sender
, Action
* parameters
)
1538 DisplayStringCore(Sender
, parameters
->int0Parameter
, DS_CONSOLE
);
1541 //float message over target
1542 void GameScript::DisplayStringHead(Scriptable
* Sender
, Action
* parameters
)
1544 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1547 printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
1550 DisplayStringCore(target
, parameters
->int0Parameter
, DS_CONSOLE
|DS_HEAD
|DS_SPEECH
);
1553 void GameScript::KillFloatMessage(Scriptable
* Sender
, Action
* parameters
)
1555 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1559 target
->DisplayHeadText(NULL
);
1562 void GameScript::DisplayStringHeadOwner(Scriptable
* /*Sender*/, Action
* parameters
)
1564 Game
*game
=core
->GetGame();
1566 int i
= game
->GetPartySize(true);
1568 Actor
*actor
= game
->GetPC(i
, true);
1569 if (actor
->inventory
.HasItem(parameters
->string0Parameter
,parameters
->int0Parameter
) ) {
1570 DisplayStringCore(actor
, parameters
->int0Parameter
, DS_CONSOLE
|DS_HEAD
);
1575 void GameScript::FloatMessageFixed(Scriptable
* Sender
, Action
* parameters
)
1577 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1580 printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
1583 DisplayStringCore(target
, parameters
->int0Parameter
, DS_CONSOLE
|DS_HEAD
);
1586 void GameScript::FloatMessageFixedRnd(Scriptable
* Sender
, Action
* parameters
)
1588 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1591 printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
1594 SrcVector
*rndstr
=LoadSrc(parameters
->string0Parameter
);
1596 printMessage("GameScript","Cannot display resource!",LIGHT_RED
);
1599 DisplayStringCore(target
, rndstr
->at(rand()%rndstr
->size()), DS_CONSOLE
|DS_HEAD
);
1600 FreeSrc(rndstr
, parameters
->string0Parameter
);
1603 void GameScript::FloatMessageRnd(Scriptable
* Sender
, Action
* parameters
)
1605 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1608 printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
1611 SrcVector
*rndstr
=LoadSrc(parameters
->string0Parameter
);
1613 printMessage("GameScript","Cannot display resource!",LIGHT_RED
);
1616 DisplayStringCore(target
, rndstr
->at(rand()%rndstr
->size()), DS_CONSOLE
|DS_HEAD
);
1617 FreeSrc(rndstr
, parameters
->string0Parameter
);
1620 //apparently this should not display over head (for actors)
1621 void GameScript::DisplayString(Scriptable
* Sender
, Action
* parameters
)
1623 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1]);
1627 if (Sender
->Type
==ST_ACTOR
) {
1628 DisplayStringCore( target
, parameters
->int0Parameter
, DS_CONSOLE
);
1630 DisplayStringCore( target
, parameters
->int0Parameter
, DS_AREA
);
1634 //DisplayStringHead, but wait for previous talk to succeed
1635 void GameScript::DisplayStringWait(Scriptable
* Sender
, Action
* parameters
)
1637 if (core
->GetAudioDrv()->IsSpeaking()) {
1638 //Sender->AddActionInFront( Sender->CurrentAction );
1641 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1]);
1645 DisplayStringCore( target
, parameters
->int0Parameter
, DS_CONSOLE
|DS_WAIT
|DS_SPEECH
|DS_HEAD
);
1646 Sender
->ReleaseCurrentAction();
1649 void GameScript::ForceFacing(Scriptable
* Sender
, Action
* parameters
)
1651 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1652 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
1653 Sender
->ReleaseCurrentAction();
1656 Actor
*actor
= (Actor
*) tar
;
1657 actor
->SetOrientation(parameters
->int0Parameter
, false);
1660 /* A -1 means random facing? */
1661 void GameScript::Face(Scriptable
* Sender
, Action
* parameters
)
1663 if (Sender
->Type
!= ST_ACTOR
) {
1664 Sender
->ReleaseCurrentAction();
1667 Actor
* actor
= ( Actor
* ) Sender
;
1668 if (parameters
->int0Parameter
==-1) {
1669 actor
->SetOrientation(core
->Roll(1,MAX_ORIENT
,-1), false);
1671 actor
->SetOrientation(parameters
->int0Parameter
, false);
1673 actor
->SetWait( 1 );
1674 Sender
->ReleaseCurrentAction(); // todo, blocking?
1677 void GameScript::FaceObject(Scriptable
* Sender
, Action
* parameters
)
1679 if (Sender
->Type
!= ST_ACTOR
) {
1680 Sender
->ReleaseCurrentAction();
1683 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1685 Sender
->ReleaseCurrentAction();
1688 Actor
* actor
= ( Actor
* ) Sender
;
1689 actor
->SetOrientation( GetOrient( target
->Pos
, actor
->Pos
), false);
1690 actor
->SetWait( 1 );
1691 Sender
->ReleaseCurrentAction(); // todo, blocking?
1694 void GameScript::FaceSavedLocation(Scriptable
* Sender
, Action
* parameters
)
1696 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1697 if (!target
|| target
->Type
!=ST_ACTOR
) {
1698 Sender
->ReleaseCurrentAction();
1701 Actor
* actor
= ( Actor
* ) target
;
1703 if (!parameters
->string0Parameter
[0]) {
1704 strcpy(parameters
->string0Parameter
,"LOCALSsavedlocation");
1706 value
= (ieDword
) CheckVariable( target
, parameters
->string0Parameter
);
1710 actor
->SetOrientation ( GetOrient( p
, actor
->Pos
), false);
1711 actor
->SetWait( 1 );
1712 Sender
->ReleaseCurrentAction(); // todo, blocking?
1715 /*pst and bg2 can play a song designated by index*/
1716 /*actually pst has some extra params not currently implemented*/
1717 /*switchplaylist could implement fade */
1718 void GameScript::StartSong(Scriptable
* /*Sender*/, Action
* parameters
)
1720 const char* string
= core
->GetMusicPlaylist( parameters
->int0Parameter
);
1721 if (!string
|| string
[0] == '*') {
1722 core
->GetMusicMgr()->HardEnd();
1724 core
->GetMusicMgr()->SwitchPlayList( string
, true );
1728 void GameScript::StartMusic(Scriptable
* Sender
, Action
* parameters
)
1730 Map
*map
= Sender
->GetCurrentArea();
1731 map
->PlayAreaSong(parameters
->int0Parameter
);
1734 /*iwd2 can set an areasong slot*/
1735 void GameScript::SetMusic(Scriptable
* Sender
, Action
* parameters
)
1737 //iwd2 seems to have 10 slots, dunno if it is important
1738 if (parameters
->int0Parameter
>4) return;
1739 Map
*map
= Sender
->GetCurrentArea();
1740 map
->SongHeader
.SongList
[parameters
->int0Parameter
]=parameters
->int1Parameter
;
1743 //optional integer parameter (isSpeech)
1744 void GameScript::PlaySound(Scriptable
* Sender
, Action
* parameters
)
1746 printf( "PlaySound(%s)\n", parameters
->string0Parameter
);
1747 core
->GetAudioDrv()->Play( parameters
->string0Parameter
, Sender
->Pos
.x
,
1748 Sender
->Pos
.y
, parameters
->int0Parameter
);
1751 void GameScript::PlaySoundPoint(Scriptable
* /*Sender*/, Action
* parameters
)
1753 printf( "PlaySound(%s)\n", parameters
->string0Parameter
);
1754 core
->GetAudioDrv()->Play( parameters
->string0Parameter
, parameters
->pointParameter
.x
, parameters
->pointParameter
.y
);
1757 void GameScript::PlaySoundNotRanged(Scriptable
* /*Sender*/, Action
* parameters
)
1759 printf( "PlaySound(%s)\n", parameters
->string0Parameter
);
1760 core
->GetAudioDrv()->Play( parameters
->string0Parameter
, 0, 0, 0);
1763 void GameScript::Continue(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1767 // creates area vvc at position of object
1768 void GameScript::CreateVisualEffectObject(Scriptable
* Sender
, Action
* parameters
)
1770 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1774 CreateVisualEffectCore(tar
, tar
->Pos
, parameters
->string0Parameter
, parameters
->int0Parameter
);
1777 // creates sticky vvc on actor or normal animation on object
1778 void GameScript::CreateVisualEffectObjectSticky(Scriptable
* Sender
, Action
* parameters
)
1780 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1784 if (tar
->Type
==ST_ACTOR
) {
1785 CreateVisualEffectCore((Actor
*) tar
, parameters
->string0Parameter
, parameters
->int0Parameter
);
1787 CreateVisualEffectCore(tar
, tar
->Pos
, parameters
->string0Parameter
, parameters
->int0Parameter
);
1791 // creates area effect at point
1792 void GameScript::CreateVisualEffect(Scriptable
* Sender
, Action
* parameters
)
1794 CreateVisualEffectCore(Sender
, parameters
->pointParameter
, parameters
->string0Parameter
, parameters
->int0Parameter
);
1797 void GameScript::DestroySelf(Scriptable
* Sender
, Action
* /*parameters*/)
1799 if (Sender
->Type
!= ST_ACTOR
) {
1802 Sender
->ClearActions();
1803 Actor
* actor
= ( Actor
* ) Sender
;
1804 actor
->DestroySelf();
1805 //actor->InternalFlags |= IF_CLEANUP;
1808 void GameScript::ScreenShake(Scriptable
* Sender
, Action
* parameters
)
1810 if (parameters
->int1Parameter
) { //IWD2 has a different profile
1811 core
->timer
->SetScreenShake( parameters
->int1Parameter
,
1812 parameters
->int2Parameter
, parameters
->int0Parameter
);
1814 core
->timer
->SetScreenShake( parameters
->pointParameter
.x
,
1815 parameters
->pointParameter
.y
, parameters
->int0Parameter
);
1817 Sender
->SetWait( parameters
->int0Parameter
);
1818 Sender
->ReleaseCurrentAction(); // todo, blocking?
1821 void GameScript::UnhideGUI(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1823 Game
* game
= core
->GetGame();
1824 game
->SetControlStatus(CS_HIDEGUI
, BM_NAND
);
1827 void GameScript::HideGUI(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1829 Game
* game
= core
->GetGame();
1830 game
->SetControlStatus(CS_HIDEGUI
, BM_OR
);
1833 void GameScript::LockScroll(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1835 GameControl
* gc
= core
->GetGameControl();
1837 gc
->SetScreenFlags(SF_LOCKSCROLL
, BM_OR
);
1841 void GameScript::UnlockScroll(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1843 GameControl
* gc
= core
->GetGameControl();
1845 gc
->SetScreenFlags(SF_LOCKSCROLL
, BM_NAND
);
1849 //no string, increase talkcount, no interrupt
1850 void GameScript::Dialogue(Scriptable
* Sender
, Action
* parameters
)
1852 BeginDialog( Sender
, parameters
, BD_SOURCE
| BD_TALKCOUNT
| BD_CHECKDIST
);
1855 void GameScript::DialogueForceInterrupt(Scriptable
* Sender
, Action
* parameters
)
1857 BeginDialog( Sender
, parameters
, BD_SOURCE
| BD_TALKCOUNT
| BD_INTERRUPT
);
1860 // not in IESDP but this one should affect ambients
1861 void GameScript::SoundActivate(Scriptable
* /*Sender*/, Action
* parameters
)
1863 AmbientMgr
* ambientmgr
= core
->GetAudioDrv()->GetAmbientMgr();
1864 if (parameters
->int0Parameter
) {
1865 ambientmgr
->activate(parameters
->objects
[1]->objectName
);
1867 ambientmgr
->deactivate(parameters
->objects
[1]->objectName
);
1871 // according to IESDP this action is about animations
1872 void GameScript::AmbientActivate(Scriptable
* Sender
, Action
* parameters
)
1874 AreaAnimation
* anim
= Sender
->GetCurrentArea( )->GetAnimation( parameters
->string0Parameter
);
1876 anim
= Sender
->GetCurrentArea( )->GetAnimation( parameters
->objects
[1]->objectName
);
1879 printf( "Script error: No Animation Named \"%s\" or \"%s\"\n",
1880 parameters
->string0Parameter
,parameters
->objects
[1]->objectName
);
1883 if (parameters
->int0Parameter
) {
1884 anim
->Flags
|= A_ANI_ACTIVE
;
1886 anim
->Flags
&= ~A_ANI_ACTIVE
;
1890 void GameScript::ChangeTileState(Scriptable
* Sender
, Action
* parameters
)
1892 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
1896 if (tar
->Type
!= ST_DOOR
) {
1899 Door
* door
= ( Door
* ) tar
;
1900 int state
= parameters
->int0Parameter
;
1902 door
->ToggleTiles(state
); /* default is false for playsound */
1906 void GameScript::StaticStart(Scriptable
* Sender
, Action
* parameters
)
1908 AreaAnimation
*anim
= Sender
->GetCurrentArea()->GetAnimation(parameters
->objects
[1]->objectName
);
1910 printf( "Script error: No Animation Named \"%s\"\n",
1911 parameters
->objects
[1]->objectName
);
1914 anim
->Flags
&=~A_ANI_PLAYONCE
;
1917 void GameScript::StaticStop(Scriptable
* Sender
, Action
* parameters
)
1919 AreaAnimation
*anim
= Sender
->GetCurrentArea()->GetAnimation(parameters
->objects
[1]->objectName
);
1921 printf( "Script error: No Animation Named \"%s\"\n",
1922 parameters
->objects
[1]->objectName
);
1925 anim
->Flags
|= A_ANI_PLAYONCE
;
1928 void GameScript::StaticPalette(Scriptable
* Sender
, Action
* parameters
)
1930 AreaAnimation
*anim
= Sender
->GetCurrentArea()->GetAnimation(parameters
->objects
[1]->objectName
);
1932 printf( "Script error: No Animation Named \"%s\"\n",
1933 parameters
->objects
[1]->objectName
);
1936 anim
->SetPalette( parameters
->string0Parameter
);
1939 //this is a special case of PlaySequence (with wait time, not for area anims)
1940 void GameScript::PlaySequenceTimed(Scriptable
* Sender
, Action
* parameters
)
1943 if (parameters
->objects
[1]) {
1944 tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1948 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
1951 Actor
* actor
= ( Actor
* ) tar
;
1952 actor
->SetStance( parameters
->int0Parameter
);
1953 int delay
= parameters
->int1Parameter
|| 1;
1954 actor
->SetWait( delay
);
1957 //waitanimation: waiting while animation of target is of a certain type
1958 void GameScript::WaitAnimation(Scriptable
* Sender
, Action
* parameters
)
1960 Scriptable
*tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1964 if (tar
->Type
!= ST_ACTOR
) {
1967 Actor
* actor
= ( Actor
* ) tar
;
1968 if (actor
->GetStance()!=parameters
->int0Parameter
) {
1969 Sender
->ReleaseCurrentAction();
1974 // PlaySequence without object parameter defaults to Sender
1975 void GameScript::PlaySequence(Scriptable
* Sender
, Action
* parameters
)
1978 if (parameters
->objects
[1]) {
1979 tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1981 //could be an animation
1982 AreaAnimation
* anim
= Sender
->GetCurrentArea( )->GetAnimation( parameters
->objects
[1]->objectName
);
1984 //set animation's cycle to parameters->int0Parameter;
1985 anim
->sequence
=parameters
->int0Parameter
;
1987 //what else to be done???
1988 anim
->InitAnimation();
1996 if (tar
->Type
!= ST_ACTOR
) {
1999 Actor
* actor
= ( Actor
* ) tar
;
2000 actor
->SetStance( parameters
->int0Parameter
);
2003 void GameScript::SetDialogue(Scriptable
* Sender
, Action
* parameters
)
2005 if (Sender
->Type
!= ST_ACTOR
) {
2008 Actor
* target
= ( Actor
* ) Sender
;
2009 target
->SetDialog( parameters
->string0Parameter
);
2012 void GameScript::ChangeDialogue(Scriptable
* Sender
, Action
* parameters
)
2014 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2018 if (tar
->Type
!= ST_ACTOR
) {
2021 Actor
* target
= ( Actor
* ) tar
;
2022 target
->SetDialog( parameters
->string0Parameter
);
2025 //string0, no interrupt, talkcount increased
2026 void GameScript::StartDialogue(Scriptable
* Sender
, Action
* parameters
)
2028 BeginDialog( Sender
, parameters
, BD_STRING0
| BD_TALKCOUNT
| BD_SETDIALOG
);
2031 //string0, no interrupt, talkcount increased, don't set default
2032 //optionally item name is used
2033 void GameScript::StartDialogueOverride(Scriptable
* Sender
, Action
* parameters
)
2035 int flags
= BD_STRING0
| BD_TALKCOUNT
;
2037 if (parameters
->int2Parameter
) {
2040 BeginDialog( Sender
, parameters
, flags
);
2043 //string0, no interrupt, talkcount increased, don't set default
2044 //optionally item name is used
2045 void GameScript::StartDialogueOverrideInterrupt(Scriptable
* Sender
,
2048 int flags
= BD_STRING0
| BD_TALKCOUNT
| BD_INTERRUPT
;
2050 if (parameters
->int2Parameter
) {
2053 BeginDialog( Sender
, parameters
, flags
);
2056 //start talking to oneself
2057 void GameScript::PlayerDialogue(Scriptable
* Sender
, Action
* parameters
)
2059 BeginDialog( Sender
, parameters
, BD_RESERVED
| BD_OWN
);
2062 //we hijack this action for the player initiated dialogue
2063 void GameScript::NIDSpecial1(Scriptable
* Sender
, Action
* parameters
)
2065 BeginDialog( Sender
, parameters
, BD_INTERRUPT
| BD_TARGET
/*| BD_NUMERIC*/ | BD_TALKCOUNT
| BD_CHECKDIST
);
2068 void GameScript::NIDSpecial2(Scriptable
* Sender
, Action
* /*parameters*/)
2070 if (Sender
->Type
!= ST_ACTOR
) {
2071 Sender
->ReleaseCurrentAction();
2074 Game
*game
=core
->GetGame();
2075 if (!game
->EveryoneStopped() ) {
2077 Sender
->SetWait( 1 * AI_UPDATE_TIME
);
2080 Actor
*actor
= (Actor
*) Sender
;
2081 if (!game
->EveryoneNearPoint(actor
->GetCurrentArea(), actor
->Pos
, true) ) {
2082 //we abort the command, everyone should be here
2083 Sender
->ReleaseCurrentAction();
2086 //travel direction passed to guiscript
2087 int direction
= Sender
->GetCurrentArea()->WhichEdge(actor
->Pos
);
2088 printf("Travel direction returned: %d\n", direction
);
2089 if (direction
==-1) {
2090 Sender
->ReleaseCurrentAction();
2093 core
->GetDictionary()->SetAt("Travel", (ieDword
) direction
);
2094 core
->GetGUIScriptEngine()->RunFunction( "OpenWorldMapWindow" );
2095 //sorry, i have absolutely no idea when i should do this :)
2096 Sender
->ReleaseCurrentAction();
2099 void GameScript::StartDialogueInterrupt(Scriptable
* Sender
, Action
* parameters
)
2101 BeginDialog( Sender
, parameters
,
2102 BD_STRING0
| BD_INTERRUPT
| BD_TALKCOUNT
| BD_SETDIALOG
);
2105 //No string, flags:0
2106 void GameScript::StartDialogueNoSet(Scriptable
* Sender
, Action
* parameters
)
2108 BeginDialog( Sender
, parameters
, BD_TALKCOUNT
| BD_SOURCE
);
2111 void GameScript::StartDialogueNoSetInterrupt(Scriptable
* Sender
,
2114 BeginDialog( Sender
, parameters
, BD_TALKCOUNT
| BD_SOURCE
| BD_INTERRUPT
);
2117 //no talkcount, using banter dialogs
2118 //probably banter dialogs are random, like rumours!
2119 //no, they aren't, but they increase interactcount
2120 void GameScript::Interact(Scriptable
* Sender
, Action
* parameters
)
2122 BeginDialog( Sender
, parameters
, BD_INTERACT
| BD_NOEMPTY
);
2125 static unsigned int FindNearPoint(Scriptable
* Sender
, Point
*&p1
, Point
*&p2
)
2127 unsigned int distance1
= Distance(*p1
, Sender
);
2128 unsigned int distance2
= Distance(*p2
, Sender
);
2129 if (distance1
<= distance2
) {
2139 //this is an immediate action without checking Sender
2140 void GameScript::DetectSecretDoor(Scriptable
* Sender
, Action
* parameters
)
2142 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
2146 if (tar
->Type
!= ST_DOOR
) {
2149 Door
* door
= ( Door
* ) tar
;
2150 if (door
->Flags
& DOOR_SECRET
) {
2151 door
->Flags
|= DOOR_FOUND
;
2155 //this is an immediate action without checking Sender
2156 void GameScript::Lock(Scriptable
* Sender
, Action
* parameters
)
2158 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2162 switch (tar
->Type
) {
2164 ((Door
*)tar
)->SetDoorLocked(true, true);
2167 ((Container
*)tar
)->SetContainerLocked(true);
2174 void GameScript::Unlock(Scriptable
* Sender
, Action
* parameters
)
2176 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2180 switch (tar
->Type
) {
2182 ((Door
*)tar
)->SetDoorLocked(false, true);
2185 ((Container
*)tar
)->SetContainerLocked(false);
2192 void GameScript::SetDoorLocked(Scriptable
* Sender
, Action
* parameters
)
2194 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2198 if (tar
->Type
!= ST_DOOR
) {
2201 Door
* door
= ( Door
* ) tar
;
2202 door
->SetDoorLocked( parameters
->int0Parameter
!=0, false);
2205 void GameScript::SetDoorFlag(Scriptable
* Sender
, Action
* parameters
)
2207 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2211 if (tar
->Type
!= ST_DOOR
) {
2214 Door
* door
= ( Door
* ) tar
;
2215 ieDword flag
= parameters
->int0Parameter
;
2217 //these are special flags
2218 if (flag
&DOOR_LOCKED
) {
2220 door
->SetDoorLocked(parameters
->int1Parameter
!=0, false);
2222 if (flag
&DOOR_OPEN
) {
2224 door
->SetDoorOpen(parameters
->int1Parameter
!=0, false, 0);
2227 if (parameters
->int1Parameter
) {
2234 void GameScript::RemoveTraps(Scriptable
* Sender
, Action
* parameters
)
2236 //only actors may try to pick a lock
2237 if (Sender
->Type
!= ST_ACTOR
) {
2238 Sender
->ReleaseCurrentAction();
2241 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2243 Sender
->ReleaseCurrentAction();
2246 unsigned int distance
;
2249 Container
*container
= NULL
;
2250 InfoPoint
*trigger
= NULL
;
2251 ScriptableType type
= tar
->Type
;
2256 door
= ( Door
* ) tar
;
2257 if (door
->IsOpen()) {
2258 //door is already open
2259 Sender
->ReleaseCurrentAction();
2263 otherp
= door
->toOpen
+1;
2264 distance
= FindNearPoint( Sender
, p
, otherp
);
2265 flags
= door
->Trapped
&& door
->TrapDetected
;
2268 container
= (Container
*) tar
;
2269 p
= &container
->Pos
;
2271 distance
= Distance(*p
, Sender
);
2272 flags
= container
->Trapped
&& container
->TrapDetected
;
2275 trigger
= (InfoPoint
*) tar
;
2276 // this point is incorrect! will cause actor to enter trap
2277 // need to find a point using trigger->outline
2280 distance
= Distance(tar
, Sender
);
2281 flags
= trigger
->Trapped
&& trigger
->TrapDetected
&& trigger
->CanDetectTrap();
2284 Sender
->ReleaseCurrentAction();
2287 Actor
* actor
= (Actor
*) Sender
;
2288 actor
->SetOrientation( GetOrient( *otherp
, actor
->Pos
), false);
2289 if (distance
<= MAX_OPERATING_DISTANCE
) {
2293 door
->TryDisarm(actor
);
2296 container
->TryDisarm(actor
);
2299 trigger
->TryDisarm(actor
);
2307 //core->DisplayString(STR_NOT_TRAPPED);
2310 MoveNearerTo(Sender
, *p
, MAX_OPERATING_DISTANCE
,0);
2314 Sender
->ReleaseCurrentAction();
2317 void GameScript::PickLock(Scriptable
* Sender
, Action
* parameters
)
2319 //only actors may try to pick a lock
2320 if (Sender
->Type
!= ST_ACTOR
) {
2321 Sender
->ReleaseCurrentAction();
2324 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2326 Sender
->ReleaseCurrentAction();
2329 unsigned int distance
;
2332 Container
*container
= NULL
;
2333 ScriptableType type
= tar
->Type
;
2338 door
= ( Door
* ) tar
;
2339 if (door
->IsOpen()) {
2340 //door is already open
2341 Sender
->ReleaseCurrentAction();
2345 otherp
= door
->toOpen
+1;
2346 distance
= FindNearPoint( Sender
, p
, otherp
);
2347 flags
= door
->Flags
&DOOR_LOCKED
;
2350 container
= (Container
*) tar
;
2351 p
= &container
->Pos
;
2353 distance
= Distance(*p
, Sender
);
2354 flags
= container
->Flags
&CONT_LOCKED
;
2357 Sender
->ReleaseCurrentAction();
2360 Actor
* actor
= (Actor
*) Sender
;
2361 actor
->SetOrientation( GetOrient( *otherp
, actor
->Pos
), false);
2362 if (distance
<= MAX_OPERATING_DISTANCE
) {
2364 if (type
==ST_DOOR
) {
2365 door
->TryPickLock(actor
);
2367 container
->TryPickLock(actor
);
2371 //core->DisplayString(STR_NOT_LOCKED);
2374 MoveNearerTo(Sender
, *p
, MAX_OPERATING_DISTANCE
,0);
2378 Sender
->ReleaseCurrentAction();
2381 void GameScript::OpenDoor(Scriptable
* Sender
, Action
* parameters
) {
2382 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2386 if (tar
->Type
!= ST_DOOR
) {
2389 Door
* door
= ( Door
* ) tar
;
2390 // no idea if this is right, or whether OpenDoor/CloseDoor should allow opening
2391 // of all doors, or some doors, or whether it should still check for non-actors
2392 if (Sender
->Type
== ST_ACTOR
) {
2393 Actor
*actor
= (Actor
*)Sender
;
2394 actor
->SetModal(MS_NONE
);
2395 if (!door
->TryUnlock(actor
)) {
2399 //if not an actor opens, it don't play sound
2400 door
->SetDoorOpen( true, (Sender
->Type
== ST_ACTOR
), 0 );
2401 Sender
->ReleaseCurrentAction();
2404 void GameScript::CloseDoor(Scriptable
* Sender
, Action
* parameters
) {
2405 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2409 if (tar
->Type
!= ST_DOOR
) {
2412 Door
* door
= ( Door
* ) tar
;
2413 // see comments in OpenDoor above
2414 if (Sender
->Type
== ST_ACTOR
) {
2415 Actor
*actor
= (Actor
*)Sender
;
2416 if (!door
->TryUnlock(actor
)) {
2420 //if not an actor closes, it don't play sound
2421 door
->SetDoorOpen( false, (Sender
->Type
== ST_ACTOR
), 0 );
2422 Sender
->ReleaseCurrentAction();
2425 void GameScript::ToggleDoor(Scriptable
* Sender
, Action
* /*parameters*/)
2427 if (Sender
->Type
!= ST_ACTOR
) {
2428 Sender
->ReleaseCurrentAction();
2431 Actor
*actor
= (Actor
*) Sender
;
2432 actor
->SetModal(MS_NONE
);
2434 // TargetDoor is set when GameControl makes the action, so should be fine
2435 // unless this action is quietly called by a script (and UseDoor in the
2436 // original engine crashes, so this is surely no worse..), but we should
2437 // maybe have a better solution
2438 Scriptable
* tar
= actor
->TargetDoor
;
2440 Sender
->ReleaseCurrentAction();
2443 if (tar
->Type
!= ST_DOOR
) {
2444 Sender
->ReleaseCurrentAction();
2447 Door
* door
= ( Door
* ) tar
;
2448 unsigned int distance
;
2449 Point
*p
= door
->toOpen
;
2450 Point
*otherp
= door
->toOpen
+1;
2451 distance
= FindNearPoint( Sender
, p
, otherp
);
2452 if (distance
<= MAX_OPERATING_DISTANCE
) {
2453 actor
->SetOrientation( GetOrient( *otherp
, actor
->Pos
), false);
2454 if (!door
->TryUnlock(actor
)) {
2455 core
->DisplayConstantString(STR_DOORLOCKED
,0xd7d7be,door
);
2456 //playsound unsuccessful opening of door
2458 core
->PlaySound(DS_CLOSE_FAIL
);
2460 core
->PlaySound(DS_OPEN_FAIL
);
2461 Sender
->ReleaseCurrentAction();
2462 return; //don't open door
2465 // should we be triggering the trap on close?
2466 door
->TriggerTrap(0, actor
->GetID());
2467 door
->SetDoorOpen( !door
->IsOpen(), true, actor
->GetID() );
2469 MoveNearerTo(Sender
, *p
, MAX_OPERATING_DISTANCE
,0);
2473 Sender
->ReleaseCurrentAction();
2476 void GameScript::ContainerEnable(Scriptable
* Sender
, Action
* parameters
)
2478 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2479 if (!tar
|| tar
->Type
!=ST_CONTAINER
) {
2482 Container
*cnt
= (Container
*) tar
;
2483 if (parameters
->int0Parameter
) {
2484 cnt
->Flags
&=~CONT_DISABLED
;
2486 cnt
->Flags
|=CONT_DISABLED
;
2490 void GameScript::MoveBetweenAreas(Scriptable
* Sender
, Action
* parameters
)
2492 if (Sender
->Type
!= ST_ACTOR
) {
2495 if (parameters
->string1Parameter
[0]) {
2496 CreateVisualEffectCore(Sender
, Sender
->Pos
, parameters
->string1Parameter
, 0);
2498 MoveBetweenAreasCore((Actor
*) Sender
, parameters
->string0Parameter
,
2499 parameters
->pointParameter
, parameters
->int0Parameter
, true);
2502 //spell is depleted, casting time is calculated, interruptible
2503 //FIXME The caster must meet the level requirements as set in the spell file
2504 void GameScript::Spell(Scriptable
* Sender
, Action
* parameters
)
2509 if (!ResolveSpellName( spellres
, parameters
) ) {
2510 Sender
->ReleaseCurrentAction();
2514 //if target was set, fire spell
2515 if (Sender
->LastTarget
) {
2516 Sender
->CastSpellEnd( spellres
);
2517 Sender
->ReleaseCurrentAction();
2521 //the target was converted to a point
2522 if(!Sender
->LastTargetPos
.isempty()) {
2523 Sender
->CastSpellPointEnd( spellres
);
2524 Sender
->ReleaseCurrentAction();
2529 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
2531 Sender
->ReleaseCurrentAction();
2535 if(Sender
->Type
==ST_ACTOR
) {
2536 Actor
*act
= (Actor
*) Sender
;
2538 unsigned int dist
= GetSpellDistance(spellres
, act
);
2540 //move near to target
2541 if (PersonalDistance(tar
, Sender
) > dist
) {
2542 MoveNearerTo(Sender
,tar
,dist
);
2547 if (tar
!= Sender
) {
2548 act
->SetOrientation( GetOrient( tar
->Pos
, act
->Pos
), false );
2551 //stop doing anything else
2552 act
->SetModal(MS_NONE
);
2554 int duration
= Sender
->CastSpell( spellres
, tar
, true );
2555 if (duration
!= -1) Sender
->SetWait(duration
);
2557 //if target was set, feed action back
2558 if (!Sender
->LastTarget
&& Sender
->LastTargetPos
.isempty()) {
2559 Sender
->ReleaseCurrentAction();
2563 //spell is depleted, casting time is calculated, interruptible
2564 //FIXME The caster must meet the level requirements as set in the spell file
2565 void GameScript::SpellPoint(Scriptable
* Sender
, Action
* parameters
)
2570 if (!ResolveSpellName( spellres
, parameters
) ) {
2571 Sender
->ReleaseCurrentAction();
2575 //if target was set, fire spell
2576 if (!Sender
->LastTargetPos
.isempty()) {
2577 Sender
->CastSpellPointEnd( spellres
);
2578 Sender
->ReleaseCurrentAction();
2582 if(Sender
->Type
==ST_ACTOR
) {
2583 Actor
*act
= (Actor
*) Sender
;
2585 unsigned int dist
= GetSpellDistance(spellres
, act
);
2587 //move near to target
2588 if (PersonalDistance(parameters
->pointParameter
, Sender
) > dist
) {
2589 MoveNearerTo(Sender
,parameters
->pointParameter
,dist
, 0);
2594 act
->SetOrientation( GetOrient( parameters
->pointParameter
, act
->Pos
), false );
2595 //stop doing anything else
2596 act
->SetModal(MS_NONE
);
2599 int duration
= Sender
->CastSpellPoint( spellres
, parameters
->pointParameter
, true );
2600 if (duration
!= -1) Sender
->SetWait(duration
);
2602 //if target was set, feed action back
2603 if (!Sender
->LastTarget
&& Sender
->LastTargetPos
.isempty()) {
2604 Sender
->ReleaseCurrentAction();
2608 //spell is not depleted (doesn't need to be memorised or known)
2609 //casting time is calculated, interruptible
2610 //FIXME The caster must meet the level requirements as set in the spell file
2611 void GameScript::SpellNoDec(Scriptable
* Sender
, Action
* parameters
)
2616 if (!ResolveSpellName( spellres
, parameters
) ) {
2617 Sender
->ReleaseCurrentAction();
2621 //if target was set, fire spell
2622 if (Sender
->LastTarget
) {
2623 Sender
->CastSpellEnd( spellres
);
2624 Sender
->ReleaseCurrentAction();
2628 //the target was converted to a point
2629 if(!Sender
->LastTargetPos
.isempty()) {
2630 Sender
->CastSpellPointEnd( spellres
);
2631 Sender
->ReleaseCurrentAction();
2636 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
2638 Sender
->ReleaseCurrentAction();
2643 if (Sender
->Type
==ST_ACTOR
) {
2644 Actor
*act
= (Actor
*) Sender
;
2645 if (tar
!= Sender
) {
2646 act
->SetOrientation( GetOrient( tar
->Pos
, act
->Pos
), false );
2649 //stop doing anything else
2650 act
->SetModal(MS_NONE
);
2652 int duration
= Sender
->CastSpell( spellres
, tar
, false );
2653 if (duration
!= -1) Sender
->SetWait(duration
);
2655 //if target was set, feed action back
2656 if (!Sender
->LastTarget
&& Sender
->LastTargetPos
.isempty()) {
2657 Sender
->ReleaseCurrentAction();
2661 //spell is not depleted (doesn't need to be memorised or known)
2662 //casting time is calculated, interruptible
2663 //FIXME The caster must meet the level requirements as set in the spell file
2664 void GameScript::SpellPointNoDec(Scriptable
* Sender
, Action
* parameters
)
2669 if (!ResolveSpellName( spellres
, parameters
) ) {
2670 Sender
->ReleaseCurrentAction();
2674 //if target was set, fire spell
2675 if (!Sender
->LastTargetPos
.isempty()) {
2676 Sender
->CastSpellPointEnd( spellres
);
2677 Sender
->ReleaseCurrentAction();
2682 if (Sender
->Type
==ST_ACTOR
) {
2683 Actor
*act
= (Actor
*) Sender
;
2684 act
->SetOrientation( GetOrient( parameters
->pointParameter
, act
->Pos
), false );
2686 //stop doing anything else
2687 act
->SetModal(MS_NONE
);
2690 int duration
= Sender
->CastSpellPoint( spellres
, parameters
->pointParameter
, false );
2691 if (duration
!= -1) Sender
->SetWait(duration
);
2693 //if target was set, feed action back
2694 if (Sender
->LastTargetPos
.isempty()) {
2695 Sender
->ReleaseCurrentAction();
2699 //spell is not depleted (doesn't need to be memorised or known)
2700 //casting time is calculated, not interruptable
2701 //FIXME The caster must meet the level requirements as set in the spell file
2702 void GameScript::ForceSpell(Scriptable
* Sender
, Action
* parameters
)
2707 if (!ResolveSpellName( spellres
, parameters
) ) {
2708 Sender
->ReleaseCurrentAction();
2712 //if target was set, fire spell
2713 if (Sender
->LastTarget
) {
2714 Sender
->CastSpellEnd( spellres
);
2715 Sender
->ReleaseCurrentAction();
2719 //the target was converted to a point
2720 if(!Sender
->LastTargetPos
.isempty()) {
2721 Sender
->CastSpellPointEnd( spellres
);
2722 Sender
->ReleaseCurrentAction();
2727 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
2729 Sender
->ReleaseCurrentAction();
2734 if (Sender
->Type
==ST_ACTOR
) {
2735 Actor
*act
= (Actor
*) Sender
;
2736 if (tar
!= Sender
) {
2737 act
->SetOrientation( GetOrient( tar
->Pos
, act
->Pos
), false );
2740 //stop doing anything else
2741 act
->SetModal(MS_NONE
);
2743 int duration
= Sender
->CastSpell (spellres
, tar
, false);
2744 if (duration
!= -1) Sender
->SetWait(duration
);
2746 //if target was set, feed action back
2747 if (!Sender
->LastTarget
&& Sender
->LastTargetPos
.isempty()) {
2748 Sender
->ReleaseCurrentAction();
2752 //spell is not depleted (doesn't need to be memorised or known)
2753 //casting time is calculated, not interruptable
2754 //FIXME The caster must meet the level requirements as set in the spell file
2755 void GameScript::ForceSpellPoint(Scriptable
* Sender
, Action
* parameters
)
2759 if (!ResolveSpellName( spellres
, parameters
) ) {
2760 Sender
->ReleaseCurrentAction();
2764 //if target was set, fire spell
2765 if (!Sender
->LastTargetPos
.isempty()) {
2766 Sender
->CastSpellPointEnd( spellres
);
2767 Sender
->ReleaseCurrentAction();
2772 if (Sender
->Type
==ST_ACTOR
) {
2773 Actor
*act
= (Actor
*) Sender
;
2774 act
->SetOrientation( GetOrient( parameters
->pointParameter
, act
->Pos
), false );
2776 //stop doing anything else
2777 act
->SetModal(MS_NONE
);
2780 int duration
= Sender
->CastSpellPoint (spellres
, parameters
->pointParameter
, false);
2781 if (duration
!= -1) Sender
->SetWait(duration
);
2783 //if target was set, feed action back
2784 if (Sender
->LastTargetPos
.isempty()) {
2785 Sender
->ReleaseCurrentAction();
2789 //ForceSpell with zero casting time
2790 //zero casting time, no depletion, not interruptable
2791 //FIXME The caster must meet the level requirements as set in the spell file
2792 void GameScript::ReallyForceSpell(Scriptable
* Sender
, Action
* parameters
)
2796 if (!ResolveSpellName( spellres
, parameters
) ) {
2797 Sender
->ReleaseCurrentAction();
2801 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2803 Sender
->ReleaseCurrentAction();
2806 if (Sender
->Type
== ST_ACTOR
) {
2807 Actor
*actor
= (Actor
*) Sender
;
2808 if (tar
!= Sender
) {
2809 actor
->SetOrientation( GetOrient( tar
->Pos
, actor
->Pos
), false );
2811 actor
->SetStance (IE_ANI_CONJURE
);
2813 Sender
->CastSpell (spellres
, tar
, false, true);
2814 if (tar
->Type
==ST_ACTOR
) {
2815 Sender
->CastSpellEnd(spellres
);
2817 Sender
->CastSpellPointEnd(spellres
);
2819 Sender
->ReleaseCurrentAction();
2822 //ForceSpellPoint with zero casting time
2823 //zero casting time, no depletion (finish casting at point), not interruptable
2825 //FIXME The caster must meet the level requirements as set in the spell file
2826 void GameScript::ReallyForceSpellPoint(Scriptable
* Sender
, Action
* parameters
)
2830 if (!ResolveSpellName( spellres
, parameters
) ) {
2831 Sender
->ReleaseCurrentAction();
2835 //Sender->LastTargetPos=parameters->pointParameter;
2836 if (Sender
->Type
== ST_ACTOR
) {
2837 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
2838 Sender
->ReleaseCurrentAction();
2841 Actor
*actor
= (Actor
*) Sender
;
2842 actor
->SetOrientation( GetOrient( parameters
->pointParameter
, actor
->Pos
), false );
2843 actor
->SetStance (IE_ANI_CONJURE
);
2845 Sender
->CastSpellPoint (spellres
, parameters
->pointParameter
, false, true);
2846 Sender
->CastSpellPointEnd(spellres
);
2847 Sender
->ReleaseCurrentAction();
2850 // this differs from ReallyForceSpell that this one allows dead Sender casting
2851 // zero casting time, no depletion
2852 void GameScript::ReallyForceSpellDead(Scriptable
* Sender
, Action
* parameters
)
2856 if (!ResolveSpellName( spellres
, parameters
) ) {
2857 Sender
->ReleaseCurrentAction();
2861 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2863 Sender
->ReleaseCurrentAction();
2866 Sender
->LastTargetPos
=parameters
->pointParameter
;
2868 if (Sender->Type == ST_ACTOR) {
2869 Actor *actor = (Actor *) Sender;
2870 //the dead don't wiggle their fingers
2871 //actor->SetStance (IE_ANI_CONJURE);
2874 Sender
->CastSpell (spellres
, tar
, false, true);
2875 if (tar
->Type
==ST_ACTOR
) {
2876 Sender
->CastSpellEnd(spellres
);
2878 Sender
->CastSpellPointEnd(spellres
);
2880 Sender
->ReleaseCurrentAction();
2883 void GameScript::Deactivate(Scriptable
* Sender
, Action
* parameters
)
2885 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2889 if (tar
->Type
!= ST_ACTOR
) {
2895 void GameScript::MakeGlobal(Scriptable
* Sender
, Action
* /*parameters*/)
2897 if (Sender
->Type
!= ST_ACTOR
) {
2900 Actor
* act
= ( Actor
* ) Sender
;
2901 core
->GetGame()->AddNPC( act
);
2904 void GameScript::UnMakeGlobal(Scriptable
* Sender
, Action
* /*parameters*/)
2906 if (Sender
->Type
!= ST_ACTOR
) {
2909 Actor
* act
= ( Actor
* ) Sender
;
2911 slot
= core
->GetGame()->InStore( act
);
2913 core
->GetGame()->DelNPC( slot
);
2917 //this apparently doesn't check the gold, thus could be used from non actors
2918 void GameScript::GivePartyGoldGlobal(Scriptable
* Sender
, Action
* parameters
)
2920 ieDword gold
= (ieDword
) CheckVariable( Sender
, parameters
->string0Parameter
, parameters
->string1Parameter
);
2921 if (Sender
->Type
== ST_ACTOR
) {
2922 Actor
* act
= ( Actor
* ) Sender
;
2923 ieDword mygold
= act
->GetStat(IE_GOLD
);
2924 if (mygold
< gold
) {
2927 //will get saved, not adjusted
2928 act
->SetBase(IE_GOLD
, act
->GetBase(IE_GOLD
)-gold
);
2930 core
->GetGame()->AddGold(gold
);
2933 void GameScript::CreatePartyGold(Scriptable
* /*Sender*/, Action
* parameters
)
2935 core
->GetGame()->AddGold(parameters
->int0Parameter
);
2938 void GameScript::GivePartyGold(Scriptable
* Sender
, Action
* parameters
)
2940 ieDword gold
= (ieDword
) parameters
->int0Parameter
;
2941 if (Sender
->Type
== ST_ACTOR
) {
2942 Actor
* act
= ( Actor
* ) Sender
;
2943 ieDword mygold
= act
->GetStat(IE_GOLD
);
2944 if (mygold
< gold
) {
2947 //will get saved, not adjusted
2948 act
->SetBase(IE_GOLD
, act
->GetBase(IE_GOLD
)-gold
);
2950 core
->GetGame()->AddGold(gold
);
2953 void GameScript::DestroyPartyGold(Scriptable
* /*Sender*/, Action
* parameters
)
2955 int gold
= core
->GetGame()->PartyGold
;
2956 if (gold
>parameters
->int0Parameter
) {
2957 gold
=parameters
->int0Parameter
;
2959 core
->GetGame()->AddGold(-gold
);
2962 void GameScript::TakePartyGold(Scriptable
* Sender
, Action
* parameters
)
2964 ieDword gold
= core
->GetGame()->PartyGold
;
2965 if (gold
>(ieDword
) parameters
->int0Parameter
) {
2966 gold
=(ieDword
) parameters
->int0Parameter
;
2968 core
->GetGame()->AddGold((ieDword
) -(int) gold
);
2969 if (Sender
->Type
== ST_ACTOR
) {
2970 Actor
* act
= ( Actor
* ) Sender
;
2971 act
->SetBase(IE_GOLD
, act
->GetBase(IE_GOLD
)+gold
);
2975 void GameScript::AddXPObject(Scriptable
* Sender
, Action
* parameters
)
2977 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2981 if (tar
->Type
!= ST_ACTOR
) {
2984 Actor
* actor
= ( Actor
* ) tar
;
2985 int xp
= parameters
->int0Parameter
;
2986 if (core
->GetStringReference(STR_GOTQUESTXP
) == (ieStrRef
) -1) {
2987 core
->DisplayConstantStringValue(STR_GOTXP
, 0xbcefbc, (ieDword
)xp
);
2990 sprintf(tmpstr
, "%d", xp
);
2991 core
->GetTokenDictionary()->SetAtCopy( "EXPERIENCEAMOUNT", tmpstr
);
2992 core
->DisplayConstantStringName(STR_GOTQUESTXP
, 0xbcefbc, actor
);
2994 actor
->AddExperience(xp
);
2997 void GameScript::AddXP2DA(Scriptable
* /*Sender*/, Action
* parameters
)
3001 if (core
->HasFeature(GF_HAS_EXPTABLE
) ) {
3002 xptable
.load("exptable");
3004 xptable
.load("xplist");
3007 if (parameters
->int0Parameter
>0) {
3008 core
->DisplayString(parameters
->int0Parameter
, 0x40f0f000,IE_STR_SOUND
);
3011 printMessage("GameScript","Can't perform ADDXP2DA",LIGHT_RED
);
3014 const char * xpvalue
= xptable
->QueryField( parameters
->string0Parameter
, "0" ); //level is unused
3016 if ( xpvalue
[0]=='P' && xpvalue
[1]=='_') {
3018 core
->GetGame()->ShareXP(atoi(xpvalue
+2), SX_DIVIDE
);
3021 core
->GetGame()->ShareXP(atoi(xpvalue
), 0 );
3025 void GameScript::AddExperienceParty(Scriptable
* /*Sender*/, Action
* parameters
)
3027 core
->GetGame()->ShareXP(parameters
->int0Parameter
, SX_DIVIDE
);
3030 //this needs moncrate.2da, but otherwise independent from GF_CHALLENGERATING
3031 void GameScript::AddExperiencePartyCR(Scriptable
* /*Sender*/, Action
* parameters
)
3033 core
->GetGame()->ShareXP(parameters
->int0Parameter
, SX_DIVIDE
|SX_CR
);
3036 void GameScript::AddExperiencePartyGlobal(Scriptable
* Sender
, Action
* parameters
)
3038 ieDword xp
= CheckVariable( Sender
, parameters
->string0Parameter
, parameters
->string1Parameter
);
3039 core
->GetGame()->ShareXP(xp
, SX_DIVIDE
);
3042 void GameScript::SetMoraleAI(Scriptable
* Sender
, Action
* parameters
)
3044 if (Sender
->Type
!= ST_ACTOR
) {
3047 Actor
* act
= ( Actor
* ) Sender
;
3048 act
->SetBase(IE_MORALE
, parameters
->int0Parameter
);
3051 void GameScript::IncMoraleAI(Scriptable
* Sender
, Action
* parameters
)
3053 if (Sender
->Type
!= ST_ACTOR
) {
3056 Actor
* act
= ( Actor
* ) Sender
;
3057 act
->SetBase(IE_MORALE
, parameters
->int0Parameter
+act
->GetBase(IE_MORALE
) );
3060 void GameScript::MoraleSet(Scriptable
* Sender
, Action
* parameters
)
3062 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3066 if (tar
->Type
!= ST_ACTOR
) {
3069 Actor
* act
= ( Actor
* ) tar
;
3070 act
->SetBase(IE_MORALEBREAK
, parameters
->int0Parameter
);
3073 void GameScript::MoraleInc(Scriptable
* Sender
, Action
* parameters
)
3075 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3079 if (tar
->Type
!= ST_ACTOR
) {
3082 Actor
* act
= ( Actor
* ) tar
;
3083 act
->SetBase(IE_MORALEBREAK
, act
->GetBase(IE_MORALEBREAK
)+parameters
->int0Parameter
);
3086 void GameScript::MoraleDec(Scriptable
* Sender
, Action
* parameters
)
3088 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3092 if (tar
->Type
!= ST_ACTOR
) {
3095 Actor
* act
= ( Actor
* ) tar
;
3096 act
->SetBase(IE_MORALEBREAK
, act
->GetBase(IE_MORALEBREAK
)-parameters
->int0Parameter
);
3099 void GameScript::JoinParty(Scriptable
* Sender
, Action
* parameters
)
3101 if (Sender
->Type
!= ST_ACTOR
) {
3104 /* calling this, so it is simpler to change */
3105 /* i'm not sure this is required here at all */
3106 SetBeenInPartyFlags(Sender
, parameters
);
3107 Actor
* act
= ( Actor
* ) Sender
;
3108 act
->SetBase( IE_EA
, EA_PC
);
3109 if (core
->HasFeature( GF_HAS_DPLAYER
)) {
3110 /* we must reset various existing scripts */
3111 act
->SetScript( "DEFAULT", AI_SCRIPT_LEVEL
, true );
3112 act
->SetScript( "", SCR_RACE
, true );
3113 act
->SetScript( "", SCR_GENERAL
, true );
3114 act
->SetScript( "DPLAYER2", SCR_DEFAULT
, false );
3116 AutoTable
pdtable("pdialog");
3118 const char* scriptname
= act
->GetScriptName();
3120 //set dialog only if we got a row
3121 if (pdtable
->GetRowIndex( scriptname
) != -1) {
3122 strnlwrcpy(resref
, pdtable
->QueryField( scriptname
, "JOIN_DIALOG_FILE"),8);
3123 act
->SetDialog( resref
);
3126 core
->GetGame()->JoinParty( act
, JP_JOIN
);
3127 core
->GetGUIScriptEngine()->RunFunction( "UpdatePortraitWindow" );
3130 void GameScript::LeaveParty(Scriptable
* Sender
, Action
* /*parameters*/)
3132 if (Sender
->Type
!= ST_ACTOR
) {
3135 Actor
* act
= ( Actor
* ) Sender
;
3136 core
->GetGame()->LeaveParty( act
);
3137 core
->GetGUIScriptEngine()->RunFunction( "UpdatePortraitWindow" );
3140 //HideCreature hides only the visuals of a creature
3141 //(feet circle and avatar)
3142 //the scripts of the creature are still running
3143 //iwd2 stores this flag in the MC field
3144 void GameScript::HideCreature(Scriptable
* Sender
, Action
* parameters
)
3146 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3147 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3150 Actor
* actor
= ( Actor
* ) tar
;
3151 actor
->BaseStats
[IE_AVATARREMOVAL
]=parameters
->int0Parameter
;
3154 //i have absolutely no idea why this is needed when we have HideCreature
3155 void GameScript::ForceHide(Scriptable
* Sender
, Action
* parameters
)
3157 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3161 if (tar
->Type
!= ST_ACTOR
) {
3164 Actor
* actor
= ( Actor
* ) tar
;
3165 actor
->BaseStats
[IE_AVATARREMOVAL
]=1;
3168 void GameScript::Activate(Scriptable
* Sender
, Action
* parameters
)
3170 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3171 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3174 // Deactivate hides, so this should unhide..
3179 void GameScript::ForceLeaveAreaLUA(Scriptable
* Sender
, Action
* parameters
)
3181 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3182 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3185 Actor
* actor
= ( Actor
* ) tar
;
3186 //the LoadMos ResRef may be empty
3187 strncpy(core
->GetGame()->LoadMos
, parameters
->string1Parameter
,8);
3188 MoveBetweenAreasCore( actor
, parameters
->string0Parameter
, parameters
->pointParameter
, parameters
->int0Parameter
, true);
3191 void GameScript::LeaveAreaLUA(Scriptable
* Sender
, Action
* parameters
)
3193 if (Sender
->Type
!= ST_ACTOR
) {
3196 Actor
* actor
= ( Actor
* ) Sender
;
3197 //the LoadMos ResRef may be empty
3198 strncpy(core
->GetGame()->LoadMos
, parameters
->string1Parameter
,8);
3199 MoveBetweenAreasCore( actor
, parameters
->string0Parameter
, parameters
->pointParameter
, parameters
->int0Parameter
, true);
3202 //this is a blocking action, because we have to move to the Entry
3203 void GameScript::LeaveAreaLUAEntry(Scriptable
* Sender
, Action
* parameters
)
3205 if (Sender
->Type
!= ST_ACTOR
) {
3206 Sender
->ReleaseCurrentAction();
3209 Actor
*actor
= (Actor
*) Sender
;
3210 Game
*game
= core
->GetGame();
3211 strncpy(game
->LoadMos
, parameters
->string1Parameter
,8);
3212 Point p
= GetEntryPoint(actor
->Area
, parameters
->string1Parameter
);
3214 Sender
->ReleaseCurrentAction();
3217 parameters
->pointParameter
=p
;
3218 LeaveAreaLUA(Sender
, parameters
);
3219 Sender
->ReleaseCurrentAction();
3222 void GameScript::LeaveAreaLUAPanic(Scriptable
* Sender
, Action
* parameters
)
3224 if (Sender
->Type
!= ST_ACTOR
) {
3227 Actor
* actor
= ( Actor
* ) Sender
;
3228 strncpy(core
->GetGame()->LoadMos
, parameters
->string1Parameter
,8);
3229 MoveBetweenAreasCore( actor
, parameters
->string0Parameter
, parameters
->pointParameter
, parameters
->int0Parameter
, true);
3232 //this is a blocking action, because we have to move to the Entry
3233 void GameScript::LeaveAreaLUAPanicEntry(Scriptable
* Sender
, Action
* parameters
)
3235 if (Sender
->Type
!= ST_ACTOR
) {
3236 Sender
->ReleaseCurrentAction();
3239 Actor
*actor
= (Actor
*) Sender
;
3240 Game
*game
= core
->GetGame();
3241 strncpy(game
->LoadMos
, parameters
->string1Parameter
,8);
3242 Point p
= GetEntryPoint(actor
->Area
, parameters
->string1Parameter
);
3244 Sender
->ReleaseCurrentAction();
3247 parameters
->pointParameter
=p
;
3248 LeaveAreaLUAPanic(Sender
, parameters
);
3249 Sender
->ReleaseCurrentAction();
3252 void GameScript::SetToken(Scriptable
* /*Sender*/, Action
* parameters
)
3254 //SetAt takes a newly created reference (no need of free/copy)
3255 char * str
= core
->GetString( parameters
->int0Parameter
);
3256 core
->GetTokenDictionary()->SetAt( parameters
->string1Parameter
, str
);
3259 //Assigns a numeric variable to the token
3260 void GameScript::SetTokenGlobal(Scriptable
* Sender
, Action
* parameters
)
3262 ieDword value
= CheckVariable( Sender
, parameters
->string0Parameter
);
3263 //using SetAtCopy because we need a copy of the value
3265 sprintf( tmpstr
, "%d", value
);
3266 core
->GetTokenDictionary()->SetAtCopy( parameters
->string1Parameter
, tmpstr
);
3269 //Assigns the target object's name (not scriptname) to the token
3270 void GameScript::SetTokenObject(Scriptable
* Sender
, Action
* parameters
)
3272 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3273 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3276 Actor
* actor
= ( Actor
* ) tar
;
3277 core
->GetTokenDictionary()->SetAtCopy( parameters
->string0Parameter
, actor
->GetName(0) );
3280 void GameScript::PlayDead(Scriptable
* Sender
, Action
* parameters
)
3282 if (Sender
->Type
!= ST_ACTOR
) {
3283 Sender
->ReleaseCurrentAction();
3286 Actor
* actor
= ( Actor
* ) Sender
;
3287 if (Sender
->CurrentActionState
== 0) {
3288 Sender
->CurrentActionState
= 1;
3289 actor
->SetStance( IE_ANI_DIE
);
3290 actor
->playDeadCounter
= parameters
->int0Parameter
;
3291 actor
->NoInterrupt();
3293 if (actor
->playDeadCounter
== 0) {
3294 Sender
->ReleaseCurrentAction();
3298 /** no difference at this moment, but this action should be interruptable */
3299 /** probably that means, we don't have to issue the SetWait, but this needs */
3300 /** further research */
3301 void GameScript::PlayDeadInterruptable(Scriptable
* Sender
, Action
* parameters
)
3303 if (Sender
->Type
!= ST_ACTOR
) {
3306 Actor
* actor
= ( Actor
* ) Sender
;
3307 actor
->SetStance( IE_ANI_DIE
);
3308 //also set time for playdead!
3309 actor
->playDeadCounter
= parameters
->int0Parameter
;
3310 actor
->SetWait( 1 );
3311 Sender
->ReleaseCurrentAction(); // todo, blocking?
3314 /* this may not be correct, just a placeholder you can fix */
3315 void GameScript::Swing(Scriptable
* Sender
, Action
* /*parameters*/)
3317 if (Sender
->Type
!= ST_ACTOR
) {
3320 Actor
* actor
= ( Actor
* ) Sender
;
3321 actor
->SetStance( IE_ANI_ATTACK
);
3322 actor
->SetWait( 1 );
3325 /* this may not be correct, just a placeholder you can fix */
3326 void GameScript::SwingOnce(Scriptable
* Sender
, Action
* /*parameters*/)
3328 if (Sender
->Type
!= ST_ACTOR
) {
3331 Actor
* actor
= ( Actor
* ) Sender
;
3332 actor
->SetStance( IE_ANI_ATTACK
);
3333 actor
->SetWait( 1 );
3336 void GameScript::Recoil(Scriptable
* Sender
, Action
* /*parameters*/)
3338 if (Sender
->Type
!= ST_ACTOR
) {
3341 Actor
* actor
= ( Actor
* ) Sender
;
3342 actor
->SetStance( IE_ANI_DAMAGE
);
3343 actor
->SetWait( 1 );
3346 void GameScript::GlobalSetGlobal(Scriptable
* Sender
, Action
* parameters
)
3348 ieDword value
= CheckVariable( Sender
, parameters
->string0Parameter
);
3349 SetVariable( Sender
, parameters
->string1Parameter
, value
);
3352 /* adding the second variable to the first, they must be GLOBAL */
3353 void GameScript::AddGlobals(Scriptable
* Sender
, Action
* parameters
)
3355 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
, "GLOBAL");
3356 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
, "GLOBAL");
3357 SetVariable( Sender
, parameters
->string0Parameter
, "GLOBAL", value1
+ value2
);
3360 /* adding the second variable to the first, they could be area or locals */
3361 void GameScript::GlobalAddGlobal(Scriptable
* Sender
, Action
* parameters
)
3363 ieDword value1
= CheckVariable( Sender
,
3364 parameters
->string0Parameter
);
3365 ieDword value2
= CheckVariable( Sender
,
3366 parameters
->string1Parameter
);
3367 SetVariable( Sender
, parameters
->string0Parameter
, value1
+ value2
);
3370 /* adding the number to the global, they could be area or locals */
3371 void GameScript::IncrementGlobal(Scriptable
* Sender
, Action
* parameters
)
3373 ieDword value
= CheckVariable( Sender
, parameters
->string0Parameter
);
3374 SetVariable( Sender
, parameters
->string0Parameter
,
3375 value
+ parameters
->int0Parameter
);
3378 /* adding the number to the global ONLY if the first global is zero */
3379 void GameScript::IncrementGlobalOnce(Scriptable
* Sender
, Action
* parameters
)
3381 ieDword value
= CheckVariable( Sender
, parameters
->string0Parameter
);
3385 value
= CheckVariable( Sender
, parameters
->string1Parameter
);
3386 SetVariable( Sender
, parameters
->string1Parameter
,
3387 value
+ parameters
->int0Parameter
);
3390 void GameScript::GlobalSubGlobal(Scriptable
* Sender
, Action
* parameters
)
3392 ieDword value1
= CheckVariable( Sender
,
3393 parameters
->string0Parameter
);
3394 ieDword value2
= CheckVariable( Sender
,
3395 parameters
->string1Parameter
);
3396 SetVariable( Sender
, parameters
->string0Parameter
, value1
- value2
);
3399 void GameScript::GlobalAndGlobal(Scriptable
* Sender
, Action
* parameters
)
3401 ieDword value1
= CheckVariable( Sender
,
3402 parameters
->string0Parameter
);
3403 ieDword value2
= CheckVariable( Sender
,
3404 parameters
->string1Parameter
);
3405 SetVariable( Sender
, parameters
->string0Parameter
, value1
&& value2
);
3408 void GameScript::GlobalOrGlobal(Scriptable
* Sender
, Action
* parameters
)
3410 ieDword value1
= CheckVariable( Sender
,
3411 parameters
->string0Parameter
);
3412 ieDword value2
= CheckVariable( Sender
,
3413 parameters
->string1Parameter
);
3414 SetVariable( Sender
, parameters
->string0Parameter
, value1
|| value2
);
3417 void GameScript::GlobalBOrGlobal(Scriptable
* Sender
, Action
* parameters
)
3419 ieDword value1
= CheckVariable( Sender
,
3420 parameters
->string0Parameter
);
3421 ieDword value2
= CheckVariable( Sender
,
3422 parameters
->string1Parameter
);
3423 SetVariable( Sender
, parameters
->string0Parameter
, value1
| value2
);
3426 void GameScript::GlobalBAndGlobal(Scriptable
* Sender
, Action
* parameters
)
3428 ieDword value1
= CheckVariable( Sender
,
3429 parameters
->string0Parameter
);
3430 ieDword value2
= CheckVariable( Sender
,
3431 parameters
->string1Parameter
);
3432 SetVariable( Sender
, parameters
->string0Parameter
, value1
& value2
);
3435 void GameScript::GlobalXorGlobal(Scriptable
* Sender
, Action
* parameters
)
3437 ieDword value1
= CheckVariable( Sender
,
3438 parameters
->string0Parameter
);
3439 ieDword value2
= CheckVariable( Sender
,
3440 parameters
->string1Parameter
);
3441 SetVariable( Sender
, parameters
->string0Parameter
, value1
^ value2
);
3444 void GameScript::GlobalBOr(Scriptable
* Sender
, Action
* parameters
)
3446 ieDword value1
= CheckVariable( Sender
,
3447 parameters
->string0Parameter
);
3448 SetVariable( Sender
, parameters
->string0Parameter
,
3449 value1
| parameters
->int0Parameter
);
3452 void GameScript::GlobalBAnd(Scriptable
* Sender
, Action
* parameters
)
3454 ieDword value1
= CheckVariable( Sender
,
3455 parameters
->string0Parameter
);
3456 SetVariable( Sender
, parameters
->string0Parameter
,
3457 value1
& parameters
->int0Parameter
);
3460 void GameScript::GlobalXor(Scriptable
* Sender
, Action
* parameters
)
3462 ieDword value1
= CheckVariable( Sender
,
3463 parameters
->string0Parameter
);
3464 SetVariable( Sender
, parameters
->string0Parameter
,
3465 value1
^ parameters
->int0Parameter
);
3468 void GameScript::GlobalMax(Scriptable
* Sender
, Action
* parameters
)
3470 long value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3471 if (value1
> parameters
->int0Parameter
) {
3472 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3476 void GameScript::GlobalMin(Scriptable
* Sender
, Action
* parameters
)
3478 long value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3479 if (value1
< parameters
->int0Parameter
) {
3480 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3484 void GameScript::BitClear(Scriptable
* Sender
, Action
* parameters
)
3486 ieDword value1
= CheckVariable( Sender
,
3487 parameters
->string0Parameter
);
3488 SetVariable( Sender
, parameters
->string0Parameter
,
3489 value1
& ~parameters
->int0Parameter
);
3492 void GameScript::GlobalShL(Scriptable
* Sender
, Action
* parameters
)
3494 ieDword value1
= CheckVariable( Sender
,
3495 parameters
->string0Parameter
);
3496 ieDword value2
= parameters
->int0Parameter
;
3502 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3505 void GameScript::GlobalShR(Scriptable
* Sender
, Action
* parameters
)
3507 ieDword value1
= CheckVariable( Sender
,
3508 parameters
->string0Parameter
);
3509 ieDword value2
= parameters
->int0Parameter
;
3515 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3518 void GameScript::GlobalMaxGlobal(Scriptable
* Sender
, Action
* parameters
)
3520 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3521 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
);
3522 if (value1
< value2
) {
3523 SetVariable( Sender
, parameters
->string0Parameter
, value2
);
3527 void GameScript::GlobalMinGlobal(Scriptable
* Sender
, Action
* parameters
)
3529 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3530 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
);
3531 if (value1
> value2
) {
3532 SetVariable( Sender
, parameters
->string0Parameter
, value2
);
3536 void GameScript::GlobalShLGlobal(Scriptable
* Sender
, Action
* parameters
)
3538 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3539 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
);
3545 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3547 void GameScript::GlobalShRGlobal(Scriptable
* Sender
, Action
* parameters
)
3549 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3550 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
);
3556 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3559 void GameScript::ClearAllActions(Scriptable
* Sender
, Action
* /*parameters*/)
3561 Actor
*except
= NULL
;
3562 if (Sender
->Type
==ST_ACTOR
) {
3563 except
= (Actor
*) Sender
;
3565 Map
*map
= Sender
->GetCurrentArea();
3566 ieDword gametime
= core
->GetGame()->GameTime
;
3567 int i
= map
->GetActorCount(true);
3569 Actor
* act
= map
->GetActor(i
,true);
3570 if (act
&& act
!=except
) {
3571 if (!act
->ValidTarget(GA_NO_DEAD
) ) {
3574 //Do we need this???
3575 if (!act
->Schedule(gametime
, false) ) {
3578 act
->ClearActions();
3580 act
->SetModal(MS_NONE
);
3585 void GameScript::ClearActions(Scriptable
* Sender
, Action
* parameters
)
3587 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3591 tar
->ClearActions();
3592 if (tar
->Type
==ST_ACTOR
) {
3593 Actor
* act
= (Actor
*) tar
;
3595 //not sure about this
3596 //act->SetModal(MS_NONE);
3600 void GameScript::SetNumTimesTalkedTo(Scriptable
* Sender
, Action
* parameters
)
3602 if (Sender
->Type
!= ST_ACTOR
) {
3605 Actor
* actor
= ( Actor
* ) Sender
;
3606 actor
->TalkCount
= parameters
->int0Parameter
;
3609 void GameScript::StartMovie(Scriptable
* Sender
, Action
* parameters
)
3611 core
->PlayMovie( parameters
->string0Parameter
);
3612 Sender
->ReleaseCurrentAction(); // should this be blocking?
3615 void GameScript::SetLeavePartyDialogFile(Scriptable
* Sender
, Action
* /*parameters*/)
3617 if (Sender
->Type
!= ST_ACTOR
) {
3620 AutoTable
pdtable("pdialog");
3621 Actor
* act
= ( Actor
* ) Sender
;
3622 const char* scriptingname
= act
->GetScriptName();
3623 act
->SetDialog( pdtable
->QueryField( scriptingname
, "POST_DIALOG_FILE" ) );
3626 void GameScript::TextScreen(Scriptable
* Sender
, Action
* parameters
)
3628 strnlwrcpy(core
->GetGame()->LoadMos
, parameters
->string0Parameter
,8);
3629 core
->GetGUIScriptEngine()->RunFunction( "StartTextScreen" );
3630 core
->GetVideoDriver()->SetMouseEnabled(true);
3632 Sender
->ReleaseCurrentAction(); // should this be blocking?
3635 void GameScript::IncrementChapter(Scriptable
* Sender
, Action
* parameters
)
3637 TextScreen(Sender
, parameters
); // textscreen will release blocking for us
3638 core
->GetGame()->IncrementChapter();
3641 void GameScript::SetCriticalPathObject(Scriptable
* Sender
, Action
* parameters
)
3643 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3644 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3647 Actor
* actor
= ( Actor
* ) tar
;
3648 if (parameters
->int0Parameter
) {
3649 actor
->SetMCFlag(MC_PLOT_CRITICAL
, BM_OR
);
3651 actor
->SetMCFlag(MC_PLOT_CRITICAL
, BM_NAND
);
3655 void GameScript::SetBeenInPartyFlags(Scriptable
* Sender
, Action
* /*parameters*/)
3657 if (Sender
->Type
!= ST_ACTOR
) {
3660 Actor
* actor
= ( Actor
* ) Sender
;
3661 //it is bit 15 of the multi-class flags (confirmed)
3662 actor
->SetMCFlag(MC_BEENINPARTY
, BM_OR
);
3665 /*iwd2 sets the high MC bits this way*/
3666 void GameScript::SetCreatureAreaFlag(Scriptable
* Sender
, Action
* parameters
)
3668 if (Sender
->Type
!= ST_ACTOR
) {
3671 Actor
* actor
= ( Actor
* ) Sender
;
3672 actor
->SetMCFlag(parameters
->int0Parameter
, parameters
->int1Parameter
);
3675 //this will be a global change, fixme if it should be local
3676 void GameScript::SetTextColor(Scriptable
* /*Sender*/, Action
* parameters
)
3679 memcpy(&c
,¶meters
->int0Parameter
,4);
3680 core
->SetInfoTextColor(c
);
3683 void GameScript::BitGlobal(Scriptable
* Sender
, Action
* parameters
)
3685 ieDword value
= CheckVariable(Sender
, parameters
->string0Parameter
);
3686 HandleBitMod( value
, parameters
->int0Parameter
, parameters
->int1Parameter
);
3687 SetVariable(Sender
, parameters
->string0Parameter
, value
);
3690 void GameScript::GlobalBitGlobal(Scriptable
* Sender
, Action
* parameters
)
3692 ieDword value1
= CheckVariable(Sender
, parameters
->string0Parameter
);
3693 ieDword value2
= CheckVariable(Sender
, parameters
->string1Parameter
);
3694 HandleBitMod( value1
, value2
, parameters
->int1Parameter
);
3695 SetVariable(Sender
, parameters
->string0Parameter
, value1
);
3698 void GameScript::SetVisualRange(Scriptable
* Sender
, Action
* parameters
)
3700 if (Sender
->Type
!= ST_ACTOR
) {
3703 Actor
* actor
= ( Actor
* ) Sender
;
3704 actor
->SetBase(IE_VISUALRANGE
,parameters
->int0Parameter
);
3707 void GameScript::MakeUnselectable(Scriptable
* Sender
, Action
* parameters
)
3709 Sender
->UnselectableTimer
=parameters
->int0Parameter
;
3712 if (Sender
->Type
!= ST_ACTOR
) {
3715 Actor
* actor
= ( Actor
* ) Sender
;
3716 if (parameters
->int0Parameter
) {
3717 // flags may be wrong
3718 core
->GetGame()->SelectActor(actor
, false, SELECT_QUIET
);
3721 actor
->SetCircleSize();
3724 void GameScript::Debug(Scriptable
* /*Sender*/, Action
* parameters
)
3726 InDebug
=parameters
->int0Parameter
;
3727 printMessage("GameScript",parameters
->string0Parameter
,YELLOW
);
3730 void GameScript::IncrementProficiency(Scriptable
* Sender
, Action
* parameters
)
3732 unsigned int idx
= parameters
->int0Parameter
;
3736 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3740 if (tar
->Type
!= ST_ACTOR
) {
3743 Actor
* target
= ( Actor
* ) tar
;
3744 //start of the proficiency stats
3745 target
->SetBase(IE_PROFICIENCYBASTARDSWORD
+idx
,
3746 target
->GetBase(IE_PROFICIENCYBASTARDSWORD
+idx
)+parameters
->int1Parameter
);
3749 void GameScript::IncrementExtraProficiency(Scriptable
* Sender
, Action
* parameters
)
3751 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3755 if (tar
->Type
!= ST_ACTOR
) {
3758 Actor
* target
= ( Actor
* ) tar
;
3759 target
->SetBase(IE_FREESLOTS
, target
->GetBase(IE_FREESLOTS
)+parameters
->int0Parameter
);
3762 //the third parameter is a GemRB extension
3763 void GameScript::AddJournalEntry(Scriptable
* /*Sender*/, Action
* parameters
)
3765 core
->GetGame()->AddJournalEntry(parameters
->int0Parameter
, parameters
->int1Parameter
, parameters
->int2Parameter
);
3768 void GameScript::SetQuestDone(Scriptable
* /*Sender*/, Action
* parameters
)
3770 Game
*game
= core
->GetGame();
3771 game
->DeleteJournalEntry(parameters
->int0Parameter
);
3772 game
->AddJournalEntry(parameters
->int0Parameter
, IE_GAM_QUEST_DONE
, parameters
->int2Parameter
);
3776 void GameScript::RemoveJournalEntry(Scriptable
* /*Sender*/, Action
* parameters
)
3778 core
->GetGame()->DeleteJournalEntry(parameters
->int0Parameter
);
3781 void GameScript::SetInternal(Scriptable
* Sender
, Action
* parameters
)
3783 unsigned int idx
= parameters
->int0Parameter
;
3787 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3791 if (tar
->Type
!= ST_ACTOR
) {
3794 Actor
* target
= ( Actor
* ) tar
;
3795 //start of the internal stats
3796 target
->SetBase(IE_INTERNAL_0
+idx
, parameters
->int1Parameter
);
3799 void GameScript::IncInternal(Scriptable
* Sender
, Action
* parameters
)
3801 unsigned int idx
= parameters
->int0Parameter
;
3805 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3806 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3809 Actor
* target
= ( Actor
* ) tar
;
3810 //start of the internal stats
3811 target
->SetBase(IE_INTERNAL_0
+idx
,
3812 target
->GetBase(IE_INTERNAL_0
+idx
)+parameters
->int1Parameter
);
3815 void GameScript::DestroyAllEquipment(Scriptable
* Sender
, Action
* /*parameters*/)
3817 Inventory
*inv
=NULL
;
3819 switch (Sender
->Type
) {
3821 inv
= &(((Actor
*) Sender
)->inventory
);
3824 inv
= &(((Container
*) Sender
)->inventory
);
3829 inv
->DestroyItem("",0,(ieDword
) ~0); //destroy any and all
3833 void GameScript::DestroyItem(Scriptable
* Sender
, Action
* parameters
)
3835 Inventory
*inv
=NULL
;
3837 switch (Sender
->Type
) {
3839 inv
= &(((Actor
*) Sender
)->inventory
);
3842 inv
= &(((Container
*) Sender
)->inventory
);
3847 inv
->DestroyItem(parameters
->string0Parameter
,0,1); //destroy one (even indestructible?)
3851 //negative destroygold creates gold
3852 void GameScript::DestroyGold(Scriptable
* Sender
, Action
* parameters
)
3854 if (Sender
->Type
!=ST_ACTOR
)
3856 Actor
*act
=(Actor
*) Sender
;
3857 int max
=(int) act
->GetStat(IE_GOLD
);
3858 if (max
>parameters
->int0Parameter
) {
3859 max
=parameters
->int0Parameter
;
3861 act
->SetBase(IE_GOLD
, act
->GetBase(IE_GOLD
)-max
);
3864 void GameScript::DestroyPartyItem(Scriptable
* /*Sender*/, Action
* parameters
)
3866 Game
*game
= core
->GetGame();
3867 int i
= game
->GetPartySize(false);
3869 if (parameters
->int0Parameter
) {
3875 Inventory
*inv
= &(game
->GetPC( i
,false )->inventory
);
3876 int res
=inv
->DestroyItem(parameters
->string0Parameter
,0,count
);
3877 if ( (count
== 1) && res
) {
3883 /* this is a gemrb extension */
3884 void GameScript::DestroyPartyItemNum(Scriptable
* /*Sender*/, Action
* parameters
)
3886 Game
*game
= core
->GetGame();
3887 int i
= game
->GetPartySize(false);
3889 count
= parameters
->int0Parameter
;
3891 Inventory
*inv
= &(game
->GetPC( i
,false )->inventory
);
3892 count
-= inv
->DestroyItem(parameters
->string0Parameter
,0,count
);
3899 void GameScript::DestroyAllDestructableEquipment(Scriptable
* Sender
, Action
* /*parameters*/)
3901 Inventory
*inv
=NULL
;
3903 switch (Sender
->Type
) {
3905 inv
= &(((Actor
*) Sender
)->inventory
);
3908 inv
= &(((Container
*) Sender
)->inventory
);
3913 inv
->DestroyItem("", IE_INV_ITEM_DESTRUCTIBLE
, (ieDword
) ~0);
3917 void GameScript::SetApparentName(Scriptable
* Sender
, Action
* parameters
)
3919 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3920 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3923 Actor
* target
= ( Actor
* ) tar
;
3924 target
->SetName(parameters
->int0Parameter
,1);
3927 void GameScript::SetRegularName(Scriptable
* Sender
, Action
* parameters
)
3929 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3930 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3933 Actor
* target
= ( Actor
* ) tar
;
3934 target
->SetName(parameters
->int0Parameter
,2);
3937 /** this is a gemrb extension */
3938 void GameScript::UnloadArea(Scriptable
* /*Sender*/, Action
* parameters
)
3940 int map
=core
->GetGame()->FindMap(parameters
->string0Parameter
);
3942 core
->GetGame()->DelMap(map
, parameters
->int0Parameter
);
3946 void GameScript::Kill(Scriptable
* Sender
, Action
* parameters
)
3948 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3949 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3952 Actor
* target
= ( Actor
* ) tar
;
3953 target
->SetBase(IE_HITPOINTS
,(ieDword
) -100);
3956 void GameScript::SetGabber(Scriptable
* Sender
, Action
* parameters
)
3958 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3959 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3962 GameControl
* gc
= core
->GetGameControl();
3963 if (gc
->GetDialogueFlags()&DF_IN_DIALOG
) {
3964 gc
->speakerID
= ((Actor
*) tar
)->globalID
;
3966 printMessage("GameScript","Can't set gabber!",YELLOW
);
3970 void GameScript::ReputationSet(Scriptable
* /*Sender*/, Action
* parameters
)
3972 core
->GetGame()->SetReputation(parameters
->int0Parameter
*10);
3975 void GameScript::ReputationInc(Scriptable
* /*Sender*/, Action
* parameters
)
3977 Game
*game
= core
->GetGame();
3978 game
->SetReputation( (int) game
->Reputation
+ parameters
->int0Parameter
*10);
3981 void GameScript::FullHeal(Scriptable
* Sender
, Action
* parameters
)
3983 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3984 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3987 Actor
*scr
= (Actor
*) tar
;
3988 //0 means full healing
3989 //Heal() might contain curing of some conditions
3990 //if FullHeal doesn't do that, replace this with a SetBase
3991 //fullhealex might still be the curing action
3995 void GameScript::RemovePaladinHood(Scriptable
* Sender
, Action
* /*parameters*/)
3997 if (Sender
->Type
!=ST_ACTOR
) {
4000 Actor
*act
= (Actor
*) Sender
;
4001 act
->SetMCFlag(MC_FALLEN_PALADIN
, BM_OR
);
4004 void GameScript::RemoveRangerHood(Scriptable
* Sender
, Action
* /*parameters*/)
4006 if (Sender
->Type
!=ST_ACTOR
) {
4009 Actor
*act
= (Actor
*) Sender
;
4010 act
->SetMCFlag(MC_FALLEN_RANGER
, BM_OR
);
4013 void GameScript::RegainPaladinHood(Scriptable
* Sender
, Action
* /*parameters*/)
4015 if (Sender
->Type
!=ST_ACTOR
) {
4018 Actor
*act
= (Actor
*) Sender
;
4019 act
->SetMCFlag(MC_FALLEN_PALADIN
, BM_NAND
);
4022 void GameScript::RegainRangerHood(Scriptable
* Sender
, Action
* /*parameters*/)
4024 if (Sender
->Type
!=ST_ACTOR
) {
4027 Actor
*act
= (Actor
*) Sender
;
4028 act
->SetMCFlag(MC_FALLEN_RANGER
, BM_NAND
);
4031 //transfering item from Sender to target, target must be an actor
4032 //if target can't get it, it will be dropped at its feet
4033 //a container or an actor can take an item from someone
4034 void GameScript::GetItem(Scriptable
* Sender
, Action
* parameters
)
4036 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4037 MoveItemCore(tar
, Sender
, parameters
->string0Parameter
,0,0);
4040 //getting one single item
4041 void GameScript::TakePartyItem(Scriptable
* Sender
, Action
* parameters
)
4043 Game
*game
=core
->GetGame();
4044 int i
=game
->GetPartySize(false);
4046 int res
=MoveItemCore(game
->GetPC(i
,false), Sender
, parameters
->string0Parameter
,0,IE_INV_ITEM_UNSTEALABLE
);
4047 if (res
!=MIC_NOITEM
) return;
4051 //getting x single item
4052 void GameScript::TakePartyItemNum(Scriptable
* Sender
, Action
* parameters
)
4054 int count
= parameters
->int0Parameter
;
4055 Game
*game
=core
->GetGame();
4056 int i
=game
->GetPartySize(false);
4058 int res
=MoveItemCore(game
->GetPC(i
,false), Sender
, parameters
->string0Parameter
,0, IE_INV_ITEM_UNSTEALABLE
);
4059 if (res
== MIC_GOTITEM
) {
4067 void GameScript::TakePartyItemRange(Scriptable
* Sender
, Action
* parameters
)
4069 Game
*game
=core
->GetGame();
4070 int i
=game
->GetPartySize(false);
4072 Actor
*ac
= game
->GetPC(i
,false);
4073 if (Distance(Sender
, ac
)<MAX_OPERATING_DISTANCE
) {
4074 while (MoveItemCore(ac
, Sender
, parameters
->string0Parameter
,0,IE_INV_ITEM_UNSTEALABLE
)==MIC_GOTITEM
) { }
4079 void GameScript::TakePartyItemAll(Scriptable
* Sender
, Action
* parameters
)
4081 Game
*game
=core
->GetGame();
4082 int i
=game
->GetPartySize(false);
4084 while (MoveItemCore(game
->GetPC(i
,false), Sender
, parameters
->string0Parameter
,0, IE_INV_ITEM_UNSTEALABLE
)==MIC_GOTITEM
) { }
4088 //an actor can 'give' an item to a container or another actor
4089 void GameScript::GiveItem(Scriptable
*Sender
, Action
* parameters
)
4091 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4092 MoveItemCore(Sender
, tar
, parameters
->string0Parameter
,0,0);
4095 //this action creates an item in a container or a creature
4096 //if there is an object it works as GiveItemCreate
4097 //otherwise it creates the item on the Sender
4098 void GameScript::CreateItem(Scriptable
*Sender
, Action
* parameters
)
4101 if (parameters
->objects
[1]) {
4102 tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4112 myinv
= &((Actor
*) tar
)->inventory
;
4115 myinv
= &((Container
*) tar
)->inventory
;
4121 CREItem
*item
= new CREItem();
4122 CreateItemCore(item
, parameters
->string0Parameter
, parameters
->int0Parameter
, parameters
->int1Parameter
, parameters
->int2Parameter
);
4123 if (tar
->Type
==ST_CONTAINER
) {
4124 myinv
->AddItem(item
);
4126 if ( ASI_SUCCESS
!= myinv
->AddSlotItem(item
, SLOT_ONLYINVENTORY
)) {
4127 Map
*map
=tar
->GetCurrentArea();
4128 // drop it at my feet
4129 map
->AddItemToLocation(tar
->Pos
, item
);
4130 if (((Actor
*)tar
)->InParty
) core
->DisplayConstantString(STR_INVFULL_ITEMDROP
, 0xbcefbc);
4132 if (((Actor
*)tar
)->InParty
) core
->DisplayConstantString(STR_GOTITEM
, 0xbcefbc);
4137 void GameScript::CreateItemNumGlobal(Scriptable
*Sender
, Action
* parameters
)
4141 switch(Sender
->Type
) {
4143 myinv
= &((Actor
*) Sender
)->inventory
;
4146 myinv
= &((Container
*) Sender
)->inventory
;
4151 int value
= CheckVariable( Sender
, parameters
->string0Parameter
);
4152 CREItem
*item
= new CREItem();
4153 CreateItemCore(item
, parameters
->string1Parameter
, value
, 0, 0);
4154 if (Sender
->Type
==ST_CONTAINER
) {
4155 myinv
->AddItem(item
);
4157 if ( ASI_SUCCESS
!= myinv
->AddSlotItem(item
, SLOT_ONLYINVENTORY
)) {
4158 Map
*map
=Sender
->GetCurrentArea();
4159 // drop it at my feet
4160 map
->AddItemToLocation(Sender
->Pos
, item
);
4161 if (((Actor
*)Sender
)->InParty
) core
->DisplayConstantString(STR_INVFULL_ITEMDROP
, 0xbcefbc);
4163 if (((Actor
*)Sender
)->InParty
) core
->DisplayConstantString(STR_GOTITEM
, 0xbcefbc);
4168 void GameScript::TakeItemReplace(Scriptable
*Sender
, Action
* parameters
)
4170 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4171 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
4175 Actor
*scr
= (Actor
*) tar
;
4177 int slot
= scr
->inventory
.RemoveItem(parameters
->string1Parameter
, 0, &item
);
4179 item
= new CREItem();
4181 CreateItemCore(item
, parameters
->string0Parameter
, -1, 0, 0);
4182 if (ASI_SUCCESS
!= scr
->inventory
.AddSlotItem(item
,slot
)) {
4183 Map
*map
= scr
->GetCurrentArea();
4184 map
->AddItemToLocation(Sender
->Pos
, item
);
4188 //same as equipitem, but with additional slots parameter, and object to perform action
4189 void GameScript::XEquipItem(Scriptable
*Sender
, Action
* parameters
)
4191 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4193 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4196 Actor
*actor
= (Actor
*) tar
;
4197 int slot
= actor
->inventory
.FindItem(parameters
->string0Parameter
, 0);
4201 actor
->inventory
.EquipItem(slot
);
4202 actor
->ReinitQuickSlots();
4205 //iwd2 also has a flag for unequip (it might collide with original!)
4206 void GameScript::EquipItem(Scriptable
*Sender
, Action
* parameters
)
4208 if (Sender
->Type
!=ST_ACTOR
) {
4211 Actor
*actor
= (Actor
*) Sender
;
4212 int slot
= actor
->inventory
.FindItem(parameters
->string0Parameter
, IE_INV_ITEM_UNDROPPABLE
);
4219 if (parameters
->int0Parameter
) {
4220 //unequip item, and move it to the inventory
4221 slot2
= SLOT_ONLYINVENTORY
;
4223 //equip item if possible
4224 slot2
= SLOT_AUTOEQUIP
;
4226 CREItem
*si
= actor
->inventory
.RemoveItem(slot
);
4228 if (actor
->inventory
.AddSlotItem(si
, slot2
)==ASI_FAILED
) {
4229 Map
*map
= Sender
->GetCurrentArea();
4231 //drop item at the feet of the character instead of destroying it
4232 map
->AddItemToLocation(Sender
->Pos
, si
);
4238 actor
->ReinitQuickSlots();
4241 void GameScript::DropItem(Scriptable
*Sender
, Action
* parameters
)
4243 if (Sender
->Type
!=ST_ACTOR
) {
4244 Sender
->ReleaseCurrentAction();
4247 if (Distance(parameters
->pointParameter
, Sender
) > 10) {
4248 MoveNearerTo(Sender
, parameters
->pointParameter
, 10,0);
4251 Actor
*scr
= (Actor
*) Sender
;
4252 Map
*map
= Sender
->GetCurrentArea();
4254 if (parameters
->string0Parameter
[0]) {
4255 //dropping location isn't exactly our place, this is why i didn't use a simple DropItem
4256 scr
->inventory
.DropItemAtLocation(parameters
->string0Parameter
,
4257 0, map
, parameters
->pointParameter
);
4259 //this should be converted from scripting slot to physical slot
4260 scr
->inventory
.DropItemAtLocation(parameters
->int0Parameter
, 0, map
, parameters
->pointParameter
);
4263 Sender
->ReleaseCurrentAction();
4266 void GameScript::DropInventory(Scriptable
*Sender
, Action
* /*parameters*/)
4268 if (Sender
->Type
!=ST_ACTOR
) {
4271 Actor
*scr
= (Actor
*) Sender
;
4272 scr
->DropItem("",0);
4275 //this should work on containers!
4276 //using the same code for DropInventoryEXExclude
4277 void GameScript::DropInventoryEX(Scriptable
*Sender
, Action
* parameters
)
4279 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4283 Inventory
*inv
= NULL
;
4284 switch (Sender
->Type
) {
4286 inv
= &(((Actor
*) tar
)->inventory
);
4289 inv
= &(((Container
*) tar
)->inventory
);
4294 int x
= inv
->GetSlotCount();
4295 Map
*area
= tar
->GetCurrentArea();
4297 if (parameters
->string0Parameter
[0]) {
4298 const char *resref
= inv
->GetSlotItem(x
)->ItemResRef
;
4299 if (!strnicmp(parameters
->string0Parameter
, resref
, 8)) {
4303 inv
->DropItemAtLocation(x
, 0, area
, tar
->Pos
);
4308 void GameScript::GivePartyAllEquipment(Scriptable
*Sender
, Action
* /*parameters*/)
4310 if (Sender
->Type
!=ST_ACTOR
) {
4313 Game
*game
= core
->GetGame();
4314 // pick the first actor first
4315 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
4316 Actor
*tar
= game
->GetPC(i
,false);
4317 //don't try to give self, it would be an infinite loop
4318 if (tar
==(Actor
*) Sender
)
4320 while(MoveItemCore(Sender
, tar
, "",0,0)!=MIC_NOITEM
) { }
4324 //This is unsure, Plunder could be just handling ground piles and not dead actors
4325 void GameScript::Plunder(Scriptable
*Sender
, Action
* parameters
)
4327 if (Sender
->Type
!=ST_ACTOR
) {
4328 Sender
->ReleaseCurrentAction();
4331 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
4333 Sender
->ReleaseCurrentAction();
4337 //you must be joking
4339 Sender
->ReleaseCurrentAction();
4343 if (tar
->Type
== ST_ACTOR
) {
4344 Actor
*scr
= (Actor
*) tar
;
4345 //can plunder only dead actors
4346 if (! (scr
->BaseStats
[IE_STATE_ID
]&STATE_DEAD
) ) {
4347 Sender
->ReleaseCurrentAction();
4351 if (PersonalDistance(Sender
, tar
)>MAX_OPERATING_DISTANCE
) {
4352 MoveNearerTo(Sender
, tar
->Pos
, MAX_OPERATING_DISTANCE
,0);
4355 //move all movable item from the target to the Sender
4356 //the rest will be dropped at the feet of Sender
4357 while(MoveItemCore(tar
, Sender
, "",0,0)!=MIC_NOITEM
) { }
4358 Sender
->ReleaseCurrentAction();
4361 void GameScript::MoveInventory(Scriptable
*Sender
, Action
* parameters
)
4363 Scriptable
* src
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4364 if (!src
|| src
->Type
!=ST_ACTOR
) {
4367 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[2] );
4368 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4371 //don't try to move to self, it would create infinite loop
4374 //move all movable item from the target to the Sender
4375 //the rest will be dropped at the feet of Sender
4376 while(MoveItemCore(src
, tar
, "",0,0)!=MIC_NOITEM
) { }
4379 void GameScript::PickPockets(Scriptable
*Sender
, Action
* parameters
)
4381 if (Sender
->Type
!=ST_ACTOR
) {
4382 Sender
->ReleaseCurrentAction();
4385 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
4386 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4387 Sender
->ReleaseCurrentAction();
4390 Actor
*snd
= (Actor
*) Sender
;
4391 Actor
*scr
= (Actor
*) tar
;
4392 //for PP one must go REALLY close
4394 if (PersonalDistance(Sender
, tar
)>10 ) {
4395 MoveNearerTo(Sender
, tar
, 10);
4399 if (scr
->LastTarget
) {
4400 core
->DisplayConstantString(STR_PICKPOCKET_EVIL
,0xffffff);
4401 Sender
->ReleaseCurrentAction();
4405 int skill
= snd
->GetStat(IE_PICKPOCKET
) - scr
->GetStat(IE_PICKPOCKET
);
4406 skill
+=core
->Roll(1,100,1);
4409 core
->DisplayConstantString(STR_PICKPOCKET_FAIL
,0xffffff);
4410 tar
->LastOpenFailed
=snd
->GetID();
4411 Sender
->ReleaseCurrentAction();
4415 //find a candidate item for stealing (unstealable items are noticed)
4416 int ret
= MoveItemCore(tar
, Sender
, "", IE_INV_ITEM_UNSTEALABLE
, IE_INV_ITEM_STOLEN
);
4417 if (ret
==MIC_NOITEM
) {
4420 if (scr
->GetStat(IE_GOLD
)>0) {
4421 money
=RandomNumValue
%(scr
->GetStat(IE_GOLD
)+1);
4425 core
->DisplayConstantString(STR_PICKPOCKET_NONE
,0xffffff);
4426 Sender
->ReleaseCurrentAction();
4429 CREItem
*item
= new CREItem();
4430 CreateItemCore(item
, core
->GoldResRef
, money
, 0, 0);
4431 if ( ASI_SUCCESS
== snd
->inventory
.AddSlotItem(item
, SLOT_ONLYINVENTORY
)) {
4432 scr
->SetBase(IE_GOLD
,scr
->GetBase(IE_GOLD
)-money
);
4434 Map
*map
=Sender
->GetCurrentArea();
4435 // drop it at my feet
4436 map
->AddItemToLocation(Sender
->Pos
, item
);
4437 if (((Actor
*)Sender
)->InParty
) core
->DisplayConstantString(STR_INVFULL_ITEMDROP
, 0xbcefbc);
4438 Sender
->ReleaseCurrentAction();
4443 core
->DisplayConstantString(STR_PICKPOCKET_DONE
,0xffffff);
4444 DisplayStringCore(snd
, VB_PP_SUCC
, DS_CONSOLE
|DS_CONST
);
4445 Sender
->ReleaseCurrentAction();
4448 void GameScript::TakeItemList(Scriptable
* Sender
, Action
* parameters
)
4450 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4451 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4454 AutoTable
tab(parameters
->string0Parameter
);
4459 int rows
= tab
->GetRowCount();
4460 for (int i
=0;i
<rows
;i
++) {
4461 MoveItemCore(tar
, Sender
, tab
->QueryField(i
,0), 0, IE_INV_ITEM_UNSTEALABLE
);
4465 void GameScript::TakeItemListParty(Scriptable
* Sender
, Action
* parameters
)
4467 AutoTable
tab(parameters
->string0Parameter
);
4471 Game
*game
= core
->GetGame();
4472 int rows
= tab
->GetRowCount();
4473 for (int i
=0;i
<rows
;i
++) {
4474 int j
= game
->GetPartySize(false);
4476 Actor
*tar
= game
->GetPC(j
, false);
4477 MoveItemCore(tar
, Sender
, tab
->QueryField(i
,0), 0, IE_INV_ITEM_UNSTEALABLE
);
4482 void GameScript::TakeItemListPartyNum(Scriptable
* Sender
, Action
* parameters
)
4484 AutoTable
tab(parameters
->string0Parameter
);
4488 Game
*game
= core
->GetGame();
4489 int rows
= tab
->GetRowCount();
4490 for (int i
=0;i
<rows
;i
++) {
4491 int count
= parameters
->int0Parameter
;
4492 int j
= game
->GetPartySize(false);
4494 Actor
*tar
= game
->GetPC(j
, false);
4495 int res
=MoveItemCore(tar
, Sender
, tab
->QueryField(i
,0), 0, IE_INV_ITEM_UNSTEALABLE
);
4496 if (res
==MIC_GOTITEM
) {
4506 void GameScript::SetRestEncounterProbabilityDay(Scriptable
* Sender
, Action
* parameters
)
4508 Map
*map
=Sender
->GetCurrentArea();
4509 map
->RestHeader
.DayChance
= (ieWord
) parameters
->int0Parameter
;
4512 void GameScript::SetRestEncounterProbabilityNight(Scriptable
* Sender
, Action
* parameters
)
4514 Map
*map
=Sender
->GetCurrentArea();
4515 map
->RestHeader
.NightChance
= (ieWord
) parameters
->int0Parameter
;
4519 void GameScript::SetRestEncounterChance(Scriptable
* Sender
, Action
* parameters
)
4521 Map
*map
=Sender
->GetCurrentArea();
4522 map
->RestHeader
.DayChance
= (ieWord
) parameters
->int0Parameter
;
4523 map
->RestHeader
.NightChance
= (ieWord
) parameters
->int1Parameter
;
4526 //easily hardcoded end sequence
4527 void GameScript::EndCredits(Scriptable
* /*Sender*/, Action
* /*parameters*/)
4529 core
->PlayMovie("credits");
4532 //easily hardcoded end sequence
4533 void GameScript::ExpansionEndCredits(Scriptable
* /*Sender*/, Action
* /*parameters*/)
4535 core
->PlayMovie("ecredit");
4538 //always quits game, but based on game it can play end animation, or display
4541 //QuitGame (play two of 3 movies in PST, display death screen with strref)
4542 //EndGame (display death screen with strref)
4543 void GameScript::QuitGame(Scriptable
* Sender
, Action
* parameters
)
4545 ClearAllActions(Sender
, parameters
);
4546 core
->GetDictionary()->SetAt("QuitGame1", (ieDword
) parameters
->int0Parameter
);
4547 core
->GetDictionary()->SetAt("QuitGame2", (ieDword
) parameters
->int1Parameter
);
4548 core
->GetDictionary()->SetAt("QuitGame3", (ieDword
) parameters
->int2Parameter
);
4549 core
->SetNextScript("QuitGame");
4552 void GameScript::StopMoving(Scriptable
* Sender
, Action
* /*parameters*/)
4554 if (Sender
->Type
!=ST_ACTOR
) {
4557 Actor
*actor
= (Actor
*) Sender
;
4561 void GameScript::ApplyDamage(Scriptable
* Sender
, Action
* parameters
)
4565 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4566 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4569 damagee
= (Actor
*) tar
;
4570 if (Sender
->Type
==ST_ACTOR
) {
4571 damager
=(Actor
*) Sender
;
4575 damagee
->Damage(parameters
->int0Parameter
, parameters
->int1Parameter
, damager
);
4578 void GameScript::ApplyDamagePercent(Scriptable
* Sender
, Action
* parameters
)
4582 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4583 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4586 damagee
= (Actor
*) tar
;
4587 if (Sender
->Type
==ST_ACTOR
) {
4588 damager
=(Actor
*) Sender
;
4592 damagee
->Damage(damagee
->GetBase(IE_HITPOINTS
)*parameters
->int0Parameter
/100, parameters
->int1Parameter
, damager
);
4595 void GameScript::Damage(Scriptable
* Sender
, Action
* parameters
)
4599 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4600 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4603 damagee
= (Actor
*) tar
;
4604 if (Sender
->Type
==ST_ACTOR
) {
4605 damager
=(Actor
*) Sender
;
4609 int damage
= damagee
->LuckyRoll( (parameters
->int1Parameter
>>12)&15, (parameters
->int1Parameter
>>4)&255, parameters
->int1Parameter
&15, 0, 1, damager
);
4610 int type
=MOD_ADDITIVE
;
4611 switch(parameters
->int0Parameter
) {
4622 damagee
->Damage( damage
, type
, damager
);
4625 void GameScript::SetHomeLocation(Scriptable* Sender, Action* parameters)
4627 Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] );
4628 if (!tar || tar->Type!=ST_ACTOR) {
4631 Movable *movable = (Movable *) tar; //not actor, though it is the only moveable
4632 movable->Destination = parameters->pointParameter;
4633 //no movement should be started here, i think
4637 void GameScript::SetMasterArea(Scriptable
* /*Sender*/, Action
* parameters
)
4639 core
->GetGame()->SetMasterArea(parameters
->string0Parameter
);
4642 void GameScript::Berserk(Scriptable
* Sender
, Action
* /*parameters*/)
4644 if (Sender
->Type
!=ST_ACTOR
) {
4647 Actor
*act
= (Actor
*) Sender
;
4648 act
->SetBaseBit(IE_STATE_ID
, STATE_BERSERK
, true);
4651 void GameScript::Panic(Scriptable
* Sender
, Action
* /*parameters*/)
4653 if (Sender
->Type
!=ST_ACTOR
) {
4656 Actor
*act
= (Actor
*) Sender
;
4660 /* as of now: removes panic and berserk */
4661 void GameScript::Calm(Scriptable
* Sender
, Action
* /*parameters*/)
4663 if (Sender
->Type
!=ST_ACTOR
) {
4666 Actor
*act
= (Actor
*) Sender
;
4667 act
->SetBaseBit(IE_STATE_ID
, STATE_BERSERK
|STATE_PANIC
, false);
4670 void GameScript::RevealAreaOnMap(Scriptable
* /*Sender*/, Action
* parameters
)
4672 WorldMap
*worldmap
= core
->GetWorldMap();
4674 printf("Can't find worldmap!\n");
4677 // WMP_ENTRY_ADJACENT because otherwise revealed bg2 areas are unreachable from city gates
4678 worldmap
->SetAreaStatus(parameters
->string0Parameter
, WMP_ENTRY_VISIBLE
|WMP_ENTRY_ADJACENT
, BM_OR
);
4679 core
->DisplayConstantString(STR_WORLDMAPCHANGE
, 0xc8ffc8);
4682 void GameScript::HideAreaOnMap( Scriptable
* /*Sender*/, Action
* parameters
)
4684 WorldMap
*worldmap
= core
->GetWorldMap();
4686 printf("Can't find worldmap!\n");
4689 // WMP_ENTRY_ADJACENT because otherwise revealed bg2 areas are unreachable from city gates
4690 worldmap
->SetAreaStatus(parameters
->string0Parameter
, WMP_ENTRY_VISIBLE
|WMP_ENTRY_ADJACENT
, BM_NAND
);
4693 void GameScript::SendTrigger(Scriptable
* Sender
, Action
* parameters
)
4695 Scriptable
*tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4699 tar
->TriggerID
=parameters
->int0Parameter
;
4702 void GameScript::Shout( Scriptable
* Sender
, Action
* parameters
)
4704 if (Sender
->Type
!=ST_ACTOR
) {
4707 //according to IESDP silenced creatures cannot use shout
4708 Actor
*actor
= (Actor
*) Sender
;
4709 if (actor
->GetStat( IE_STATE_ID
) & STATE_SILENCED
) {
4712 Map
*map
=Sender
->GetCurrentArea();
4713 //max. shouting distance, please adjust it if you know better
4714 map
->Shout(actor
, parameters
->int0Parameter
, MAX_TRAVELING_DISTANCE
);
4717 void GameScript::GlobalShout( Scriptable
* Sender
, Action
* parameters
)
4719 if (Sender
->Type
!=ST_ACTOR
) {
4722 //according to IESDP silenced creatures cannot use shout
4723 Actor
*actor
= (Actor
*) Sender
;
4724 if (actor
->GetStat( IE_STATE_ID
) & STATE_SILENCED
) {
4727 Map
*map
=Sender
->GetCurrentArea();
4728 // 0 means unlimited shout distance
4729 map
->Shout(actor
, parameters
->int0Parameter
, 0);
4732 void GameScript::Help( Scriptable
* Sender
, Action
* /*parameters*/)
4734 if (Sender
->Type
!=ST_ACTOR
) {
4737 Map
*map
=Sender
->GetCurrentArea();
4738 map
->Shout((Actor
*) Sender
, 0, 40);
4741 void GameScript::GiveOrder(Scriptable
* Sender
, Action
* parameters
)
4743 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4745 tar
->LastOrderer
= Sender
->GetGlobalID();
4746 tar
->LastOrder
= parameters
->int0Parameter
;
4750 void GameScript::AddMapnote( Scriptable
* Sender
, Action
* parameters
)
4752 Map
*map
=Sender
->GetCurrentArea();
4753 char *str
= core
->GetString( parameters
->int0Parameter
, 0);
4754 map
->AddMapNote(parameters
->pointParameter
, parameters
->int1Parameter
, str
, parameters
->int0Parameter
);
4757 void GameScript::RemoveMapnote( Scriptable
* Sender
, Action
* parameters
)
4759 Map
*map
=Sender
->GetCurrentArea();
4760 map
->RemoveMapNote(parameters
->pointParameter
);
4763 void GameScript::AttackOneRound( Scriptable
* Sender
, Action
* parameters
)
4765 if (Sender
->Type
!= ST_ACTOR
) {
4766 Sender
->ReleaseCurrentAction();
4769 //using auto target!
4771 if (!parameters
->objects
[1]) {
4772 GameControl
*gc
= core
->GetGameControl();
4773 tar
= gc
->GetTarget();
4775 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4777 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4778 Sender
->ReleaseCurrentAction();
4782 //actor is already incapable of attack
4783 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4784 Sender
->ReleaseCurrentAction();
4788 if (!Sender
->CurrentActionState
) {
4789 Sender
->CurrentActionState
= ROUND_SIZE
;
4792 AttackCore(Sender
, tar
, 0);
4794 if (Sender
->CurrentActionState
== 1) {
4795 //this is the LastDisarmFailed field, but this is an actor
4796 //Sender->LastTarget = 0;
4797 Sender
->ReleaseCurrentAction();
4799 Sender
->CurrentActionState
--;
4803 void GameScript::RunningAttackNoSound( Scriptable
* Sender
, Action
* parameters
)
4805 if (Sender
->Type
!= ST_ACTOR
) {
4806 Sender
->ReleaseCurrentAction();
4809 //using auto target!
4811 if (!parameters
->objects
[1]) {
4812 GameControl
*gc
= core
->GetGameControl();
4813 tar
= gc
->GetTarget();
4815 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4817 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4818 Sender
->ReleaseCurrentAction();
4822 //actor is already incapable of attack
4823 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4824 Sender
->ReleaseCurrentAction();
4828 AttackCore(Sender
, tar
, AC_NO_SOUND
|AC_RUNNING
);
4831 void GameScript::AttackNoSound( Scriptable
* Sender
, Action
* parameters
)
4833 if (Sender
->Type
!= ST_ACTOR
) {
4834 Sender
->ReleaseCurrentAction();
4837 //using auto target!
4839 if (!parameters
->objects
[1]) {
4840 GameControl
*gc
= core
->GetGameControl();
4841 tar
= gc
->GetTarget();
4843 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4845 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4846 Sender
->ReleaseCurrentAction();
4850 //actor is already incapable of attack
4851 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4852 Sender
->ReleaseCurrentAction();
4856 AttackCore(Sender
, tar
, AC_NO_SOUND
);
4859 void GameScript::RunningAttack( Scriptable
* Sender
, Action
* parameters
)
4861 if (Sender
->Type
!= ST_ACTOR
) {
4862 Sender
->ReleaseCurrentAction();
4865 //using auto target!
4867 if (!parameters
->objects
[1]) {
4868 GameControl
*gc
= core
->GetGameControl();
4869 tar
= gc
->GetTarget();
4871 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4873 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4874 Sender
->ReleaseCurrentAction();
4878 //actor is already incapable of attack
4879 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4880 Sender
->ReleaseCurrentAction();
4884 AttackCore(Sender
, tar
, AC_RUNNING
);
4887 void GameScript::Attack( Scriptable
* Sender
, Action
* parameters
)
4889 if (Sender
->Type
!= ST_ACTOR
) {
4890 Sender
->ReleaseCurrentAction();
4893 //using auto target!
4895 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4897 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) || tar
== Sender
) {
4898 Sender
->ReleaseCurrentAction();
4902 //actor is already incapable of attack
4903 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4904 Sender
->ReleaseCurrentAction();
4908 AttackCore(Sender
, tar
, 0);
4911 void GameScript::ForceAttack( Scriptable
* Sender
, Action
* parameters
)
4913 Scriptable
* scr
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4914 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
4917 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[2], GA_NO_DEAD
);
4918 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4921 //this is a hack, we use a gui variable for our own hideous reasons?
4922 if (tar
->Type
==ST_ACTOR
) {
4923 GameControl
*gc
= core
->GetGameControl();
4925 //saving the target object ID from the gui variable
4927 strncpy(Tmp
,"NIDSpecial3()",sizeof(Tmp
) );
4928 scr
->AddAction( GenerateActionDirect(Tmp
, (Actor
*) tar
) );
4932 snprintf(Tmp
, sizeof(Tmp
), "BashDoor(%s)", tar
->GetScriptName());
4933 scr
->AddAction ( GenerateAction(Tmp
) );
4937 void GameScript::AttackReevaluate( Scriptable
* Sender
, Action
* parameters
)
4939 if (Sender
->Type
!= ST_ACTOR
) {
4940 Sender
->ReleaseCurrentAction();
4944 if (!Sender
->CurrentActionState
) {
4945 Sender
->CurrentActionState
= parameters
->int0Parameter
;
4946 // TODO: reevaluate target (set CurrentActionTarget to 0) if we are not actively in combat
4950 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4951 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4952 Sender
->ReleaseCurrentAction();
4956 //actor is already incapable of attack
4957 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4958 Sender
->ReleaseCurrentAction();
4962 AttackCore(Sender
, tar
, 0);
4964 Sender
->CurrentActionState
--;
4967 void GameScript::Explore( Scriptable
* Sender
, Action
* /*parameters*/)
4969 Sender
->GetCurrentArea( )->Explore(-1);
4972 void GameScript::UndoExplore( Scriptable
* Sender
, Action
* /*parameters*/)
4974 Sender
->GetCurrentArea( )->Explore(0);
4977 void GameScript::ExploreMapChunk( Scriptable
* Sender
, Action
* parameters
)
4979 Map
*map
= Sender
->GetCurrentArea();
4981 There is a mode flag in int1Parameter, but i don't know what is it,
4982 our implementation uses it for LOS=1, or no LOS=0
4983 ExploreMapChunk will reveal both visibility/explored map, but the
4984 visibility will fade in the next update cycle (which is quite frequent)
4986 map
->ExploreMapChunk(parameters
->pointParameter
, parameters
->int0Parameter
, parameters
->int1Parameter
);
4989 void GameScript::StartStore( Scriptable
* Sender
, Action
* parameters
)
4991 if (core
->GetCurrentStore() ) {
4994 core
->SetCurrentStore( parameters
->string0Parameter
, Sender
->GetScriptName());
4995 //core->GetGUIScriptEngine()->RunFunction( "OpenStoreWindow" );
4996 core
->SetEventFlag(EF_OPENSTORE
);
4997 //sorry, i have absolutely no idea when i should do this :)
4998 Sender
->ReleaseCurrentAction();
5001 //The integer parameter is a GemRB extension, if set to 1, the player
5002 //gains experience for learning the spell
5003 void GameScript::AddSpecialAbility( Scriptable
* Sender
, Action
* parameters
)
5005 if (Sender
->Type
!= ST_ACTOR
) {
5008 Actor
*actor
= (Actor
*) Sender
;
5009 actor
->LearnSpell (parameters
->string0Parameter
, parameters
->int0Parameter
|LS_MEMO
|LS_LEARN
);
5010 core
->SetEventFlag(EF_ACTION
);
5013 void GameScript::RemoveSpell( Scriptable
* Sender
, Action
* parameters
)
5015 if (Sender
->Type
!=ST_ACTOR
) {
5018 Actor
*actor
= (Actor
*) Sender
;
5019 if (parameters
->string0Parameter
[0]) {
5020 actor
->spellbook
.RemoveSpell(parameters
->string0Parameter
);
5023 actor
->spellbook
.RemoveSpell(parameters
->int0Parameter
);
5026 void GameScript::SetScriptName( Scriptable
* Sender
, Action
* parameters
)
5028 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5029 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5032 tar
->SetScriptName(parameters
->string0Parameter
);
5036 //advance time with a constant
5037 //This is in seconds according to IESDP
5038 void GameScript::AdvanceTime(Scriptable
* /*Sender*/, Action
* parameters
)
5040 core
->GetGame()->AdvanceTime(parameters
->int0Parameter
*1000/AI_UPDATE_TIME
);
5043 //advance at least one day, then stop at next day/dusk/night/morning
5044 //oops, not TimeODay is used but Time (this means we got hours)
5045 //i'm not sure if we should add a whole day either, needs more research
5046 void GameScript::DayNight(Scriptable
* /*Sender*/, Action
* parameters
)
5048 // first, calculate the current number of hours.
5049 int padding
= ((core
->GetGame()->GameTime
/ AI_UPDATE_TIME
) % 7200) / 300;
5050 // then, calculate the offset (in hours) required to take us to the desired hour.
5051 padding
= (24 + parameters
->int0Parameter
- padding
) % 24;
5052 // then, advance one day (7200), plus the desired number of hours.
5053 core
->GetGame()->AdvanceTime(AI_UPDATE_TIME
*(7200 + padding
*300));
5056 //implement pst style parameters:
5057 //suggested dream - unused
5058 //if suggested dream is 0, then area flags determine the 'movie'
5059 //hp - number of hps healed
5060 //renting - crashes pst, we simply ignore it
5061 void GameScript::RestParty(Scriptable
* Sender
, Action
* parameters
)
5063 Game
*game
= core
->GetGame();
5064 game
->RestParty(REST_NOAREA
|REST_NOMOVE
|REST_NOCRITTER
, parameters
->int0Parameter
, parameters
->int1Parameter
);
5065 Sender
->ReleaseCurrentAction();
5068 //doesn't advance game time, just refreshes spells of target
5069 //this is a non-blocking action
5070 void GameScript::Rest(Scriptable
* Sender
, Action
* /*parameters*/)
5072 if (Sender
->Type
!=ST_ACTOR
) {
5075 Actor
*actor
= (Actor
*) Sender
;
5076 actor
->spellbook
.ChargeAllSpells();
5077 //check if this should be a full heal
5079 actor
->fxqueue
.RemoveExpiredEffects(0xffffffff);
5082 //doesn't advance game time (unsure), just refreshes spells of target
5083 void GameScript::RestNoSpells(Scriptable
* Sender
, Action
* /*parameters*/)
5085 if (Sender
->Type
!=ST_ACTOR
) {
5088 Actor
*actor
= (Actor
*) Sender
;
5089 //check if this should be a full heal
5091 actor
->fxqueue
.RemoveExpiredEffects(0xffffffff);
5094 //this is most likely advances time
5095 void GameScript::RestUntilHealed(Scriptable
* Sender
, Action
* /*parameters*/)
5097 if (Sender
->Type
!=ST_ACTOR
) {
5100 Actor
*actor
= (Actor
*) Sender
;
5102 //not sure if this should remove timed effects
5103 //more like execute them hour by hour :>
5107 //removes all delayed/duration/semi permanent effects (like a ctrl-r)
5108 void GameScript::ClearPartyEffects(Scriptable
* /*Sender*/, Action
* /*parameters*/)
5110 Game
*game
= core
->GetGame();
5111 int i
= game
->GetPartySize(false);
5113 Actor
*tar
= game
->GetPC(i
, false);
5114 tar
->fxqueue
.RemoveExpiredEffects(0xffffffff);
5118 //iwd2 removes effects from a single sprite
5119 void GameScript::ClearSpriteEffects(Scriptable
* Sender
, Action
* parameters
)
5121 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5122 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5125 Actor
*actor
= (Actor
*) tar
;
5126 actor
->fxqueue
.RemoveExpiredEffects(0xffffffff);
5129 //IWD2 special, can mark only actors, hope it is enough
5130 void GameScript::MarkObject(Scriptable
* Sender
, Action
* parameters
)
5132 if (Sender
->Type
!= ST_ACTOR
) {
5135 //unsure, could mark dead objects?
5136 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
5137 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5140 Actor
*actor
= (Actor
*) Sender
;
5141 actor
->LastMarked
= ((Actor
*) tar
)->GetID();
5142 //if this doesn't modify LastSeen, then remove this line
5143 actor
->LastSeen
= actor
->LastMarked
;
5146 void GameScript::SetDialogueRange(Scriptable
* Sender
, Action
* parameters
)
5148 if (Sender
->Type
!= ST_ACTOR
) {
5151 Actor
*actor
= (Actor
*) Sender
;
5152 actor
->SetBase( IE_DIALOGRANGE
, parameters
->int0Parameter
);
5155 void GameScript::SetGlobalTint(Scriptable
* /*Sender*/, Action
* parameters
)
5157 core
->GetVideoDriver()->SetFadeColor(parameters
->int0Parameter
, parameters
->int1Parameter
, parameters
->int2Parameter
);
5160 void GameScript::SetArmourLevel(Scriptable
* Sender
, Action
* parameters
)
5162 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5163 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5166 Actor
*actor
= (Actor
*) Sender
;
5167 actor
->SetBase( IE_ARMOR_TYPE
, parameters
->int0Parameter
);
5170 void GameScript::RandomWalk(Scriptable
* Sender
, Action
* /*parameters*/)
5172 if (Sender
->Type
!= ST_ACTOR
) {
5173 Sender
->ReleaseCurrentAction();
5176 Actor
* actor
= ( Actor
* ) Sender
;
5177 actor
->RandomWalk( true, false );
5178 Sender
->ReleaseCurrentAction();
5181 void GameScript::RandomRun(Scriptable
* Sender
, Action
* /*parameters*/)
5183 if (Sender
->Type
!= ST_ACTOR
) {
5184 Sender
->ReleaseCurrentAction();
5187 Actor
* actor
= ( Actor
* ) Sender
;
5188 actor
->RandomWalk( true, true );
5189 Sender
->ReleaseCurrentAction();
5192 void GameScript::RandomWalkContinuous(Scriptable
* Sender
, Action
* /*parameters*/)
5194 if (Sender
->Type
!= ST_ACTOR
) {
5195 Sender
->ReleaseCurrentAction();
5198 Actor
* actor
= ( Actor
* ) Sender
;
5199 actor
->RandomWalk( false, false );
5202 void GameScript::RandomFly(Scriptable
* Sender
, Action
* /*parameters*/)
5204 if (Sender
->Type
!= ST_ACTOR
) {
5205 Sender
->ReleaseCurrentAction();
5208 Actor
* actor
= ( Actor
* ) Sender
;
5211 actor
->SetOrientation(actor
->GetOrientation()-1, false);
5213 actor
->SetOrientation(actor
->GetOrientation()+1, false);
5215 //fly in this direction for 5 steps
5216 actor
->MoveLine(5, GL_PASS
, actor
->GetOrientation() );
5217 //readding the action to the end of the queue
5218 //Sender->AddAction( parameters );
5219 //Sender->ReleaseCurrentAction();
5222 //UseContainer uses the predefined target (like Nidspecial1 dialog hack)
5223 void GameScript::UseContainer(Scriptable
* Sender
, Action
* /*parameters*/)
5225 if (Sender
->Type
!= ST_ACTOR
) {
5226 Sender
->ReleaseCurrentAction();
5229 Actor
*actor
= (Actor
*)Sender
;
5230 Container
*container
= core
->GetCurrentContainer();
5232 printMessage("GameScript","No container selected!", YELLOW
);
5233 Sender
->ReleaseCurrentAction();
5237 ieDword distance
= PersonalDistance(Sender
, container
);
5238 ieDword needed
= MAX_OPERATING_DISTANCE
;
5239 if (container
->Type
==IE_CONTAINER_PILE
) {
5240 needed
= 0; // less than a search square (width)
5242 if (distance
<=needed
)
5244 //check if the container is unlocked
5245 if (!container
->TryUnlock(actor
)) {
5246 //playsound can't open container
5247 //display string, etc
5248 core
->DisplayConstantString(STR_CONTLOCKED
,0xd7d7be,container
);
5249 Sender
->ReleaseCurrentAction();
5252 Actor
*actor
= (Actor
*)Sender
;
5253 actor
->SetModal(MS_NONE
);
5254 container
->TriggerTrap(0, actor
->GetID());
5255 core
->SetCurrentContainer(actor
, container
, true);
5256 Sender
->ReleaseCurrentAction();
5259 MoveNearerTo(Sender
, container
, needed
);
5262 //call the usecontainer action in target (not used)
5263 void GameScript::ForceUseContainer(Scriptable
* Sender
, Action
* parameters
)
5265 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5266 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
5267 Sender
->ReleaseCurrentAction(); //why blocking???
5271 sprintf( Tmp
, "UseContainer()");
5272 Action
*newaction
= GenerateAction(Tmp
);
5273 tar
->AddActionInFront(newaction
);
5274 Sender
->ReleaseCurrentAction(); //why blocking???
5277 //these actions directly manipulate a game variable (as the original engine)
5278 void GameScript::SetMazeEasier(Scriptable
* Sender
, Action
* /*parameters*/)
5280 int value
= CheckVariable( Sender
, "MAZEDIFFICULTY","GLOBAL");
5282 SetVariable(Sender
, "MAZEDIFFICULTY", "GLOBAL", value
-1);
5286 void GameScript::SetMazeHarder(Scriptable
* Sender
, Action
* /*parameters*/)
5288 int value
= CheckVariable( Sender
, "MAZEDIFFICULTY","GLOBAL");
5290 SetVariable(Sender
, "MAZEDIFFICULTY", "GLOBAL", value
+1);
5294 void GameScript::StartRainNow(Scriptable
* /*Sender*/, Action
* /*parameters*/)
5296 core
->GetGame()->StartRainOrSnow( false, WB_RAIN
|WB_LIGHTNING
);
5299 void GameScript::Weather(Scriptable
* /*Sender*/, Action
* parameters
)
5301 Game
*game
= core
->GetGame();
5302 switch(parameters
->int0Parameter
& WB_FOG
) {
5304 game
->StartRainOrSnow( false, 0);
5307 game
->StartRainOrSnow( true, WB_RAIN
|WB_LIGHTNING
);
5310 game
->StartRainOrSnow( true, WB_SNOW
);
5313 game
->StartRainOrSnow( true, WB_FOG
);
5318 void GameScript::CopyGroundPilesTo(Scriptable
* Sender
, Action
* parameters
)
5320 Map
*map
= Sender
->GetCurrentArea();
5321 Map
*othermap
= core
->GetGame()->GetMap( parameters
->string0Parameter
, false );
5325 map
->CopyGroundPiles( othermap
, parameters
->pointParameter
);
5329 void GameScript::PlayBardSong(Scriptable
* Sender
, Action
* /*parameters*/)
5331 if (Sender
->Type
!=ST_ACTOR
) {
5334 //actually this one must use int0Parameter to set a bardsong
5335 Actor
*actor
= (Actor
*) Sender
;
5336 actor
->SetModal( MS_BATTLESONG
);
5339 void GameScript::BattleSong(Scriptable
* Sender
, Action
* /*parameters*/)
5341 if (Sender
->Type
!=ST_ACTOR
) {
5344 Actor
*actor
= (Actor
*) Sender
;
5345 actor
->SetModal( MS_BATTLESONG
);
5348 void GameScript::FindTraps(Scriptable
* Sender
, Action
* /*parameters*/)
5350 if (Sender
->Type
!=ST_ACTOR
) {
5353 Actor
*actor
= (Actor
*) Sender
;
5354 actor
->SetModal( MS_DETECTTRAPS
);
5357 static EffectRef fx_disable_button_ref
={ "DisableButton", NULL
, -1 };
5359 inline void HideFailed(Actor
* actor
)
5361 core
->DisplayConstantStringName(STR_HIDEFAILED
, 0xffffff, actor
);
5362 actor
->SetModal(MS_NONE
);
5365 newfx
= EffectQueue::CreateEffect(fx_disable_button_ref
, 0, ACT_STEALTH
, FX_DURATION_INSTANT_LIMITED
);
5366 newfx
->Duration
= 6; // 90 ticks, 1 round
5367 core
->ApplyEffect(newfx
, actor
, actor
);
5371 void GameScript::Hide(Scriptable
* Sender
, Action
* /*parameters*/)
5373 if (Sender
->Type
!=ST_ACTOR
) {
5376 Actor
*actor
= (Actor
*) Sender
;
5378 ieDword roll
= actor
->LuckyRoll(1, 100, 0);
5384 // check for disabled dualclassed thieves (not sure if we need it)
5386 if (actor
->Modified
[IE_DISABLEDBUTTON
] & (1<<ACT_STEALTH
)) {
5391 // check if the pc is in combat (seen / heard)
5392 Game
*game
= core
->GetGame();
5393 if (game
->PCInCombat(actor
)) {
5399 if (core
->HasFeature(GF_HAS_HIDE_IN_SHADOWS
)) {
5400 skill
= (actor
->GetStat(IE_HIDEINSHADOWS
) + actor
->GetStat(IE_STEALTH
))/2;
5402 skill
= actor
->GetStat(IE_STEALTH
);
5405 // check how bright our spot is
5406 ieDword lightness
= game
->GetCurrentArea()->GetLightLevel(actor
->Pos
);
5407 // seems to be the color overlay at midnight; lightness of a point with rgb (200, 100, 100)
5408 // TODO: but our NightTint computes to a higher value, which one is bad?
5409 ieDword ref_lightness
= 43;
5410 ieDword light_diff
= int((lightness
- ref_lightness
) * 100 / (100 - ref_lightness
)) / 2;
5411 ieDword chance
= (100 - light_diff
) * skill
/100;
5413 if (roll
> chance
) {
5418 actor
->SetModal( MS_STEALTH
);
5419 core
->DisplayConstantStringName(STR_HIDEDONE
, 0xffffff, actor
);
5421 //TODO: show STR_HIDENOMORE on expiry/abort
5422 //TODO: expiry isn't instant (skill based transition?)
5426 void GameScript::Turn(Scriptable
* Sender
, Action
* /*parameters*/)
5428 if (Sender
->Type
!=ST_ACTOR
) {
5431 Actor
*actor
= (Actor
*) Sender
;
5432 actor
->SetModal( MS_TURNUNDEAD
);
5435 void GameScript::TurnAMT(Scriptable
* Sender
, Action
* parameters
)
5437 if (Sender
->Type
!=ST_ACTOR
) {
5438 Sender
->ReleaseCurrentAction();
5441 Actor
*actor
= (Actor
*) Sender
;
5442 actor
->SetOrientation(actor
->GetOrientation()+parameters
->int0Parameter
, true);
5443 actor
->SetWait( 1 );
5444 Sender
->ReleaseCurrentAction(); // todo, blocking?
5447 void GameScript::RandomTurn(Scriptable
* Sender
, Action
* /*parameters*/)
5449 if (Sender
->Type
!=ST_ACTOR
) {
5450 Sender
->ReleaseCurrentAction();
5453 Actor
*actor
= (Actor
*) Sender
;
5454 actor
->SetOrientation(rand() % MAX_ORIENT
, true);
5455 actor
->SetWait( 1 );
5456 Sender
->ReleaseCurrentAction(); // todo, blocking?
5459 void GameScript::AttachTransitionToDoor(Scriptable
* Sender
, Action
* parameters
)
5461 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5462 if (!tar
|| tar
->Type
!= ST_DOOR
) {
5465 Door
* door
= ( Door
* ) tar
;
5466 strnspccpy(door
->LinkedInfo
, parameters
->string0Parameter
, 32);
5469 /*getting a handle of a temporary actor resource to copy its selected attributes*/
5470 void GameScript::ChangeAnimation(Scriptable
* Sender
, Action
* parameters
)
5472 if (Sender
->Type
!=ST_ACTOR
) {
5475 ChangeAnimationCore((Actor
*) Sender
, parameters
->string0Parameter
,1);
5478 void GameScript::ChangeAnimationNoEffect(Scriptable
* Sender
, Action
* parameters
)
5480 if (Sender
->Type
!=ST_ACTOR
) {
5483 ChangeAnimationCore((Actor
*) Sender
, parameters
->string0Parameter
,0);
5486 void GameScript::Polymorph(Scriptable
* Sender
, Action
* parameters
)
5488 if (Sender
->Type
!=ST_ACTOR
) {
5491 Actor
*act
= (Actor
*) Sender
;
5492 act
->SetBase(IE_ANIMATION_ID
, parameters
->int0Parameter
);
5495 void GameScript::PolymorphCopy(Scriptable
* Sender
, Action
* parameters
)
5497 if (Sender
->Type
!=ST_ACTOR
) {
5500 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5501 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5504 PolymorphCopyCore((Actor
*) Sender
, (Actor
*) tar
, false);
5507 /* according to IESDP this only copies the animation ID */
5508 void GameScript::PolymorphCopyBase(Scriptable
* Sender
, Action
* parameters
)
5510 if (Sender
->Type
!=ST_ACTOR
) {
5513 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5514 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5517 Actor
*act
= (Actor
*) Sender
;
5518 Actor
*actor
= (Actor
*) tar
;
5519 act
->SetBase(IE_ANIMATION_ID
, actor
->GetBase(IE_ANIMATION_ID
) );
5522 void GameScript::SaveGame(Scriptable
* /*Sender*/, Action
* parameters
)
5525 char FolderName
[_MAX_PATH
];
5526 const char *folder
= "";
5528 AutoTable
tab("savegame");
5530 type
= atoi(tab
->QueryField((unsigned int) -1));
5532 char * str
= core
->GetString( parameters
->int0Parameter
, IE_STR_STRREFOFF
);
5533 snprintf (FolderName
, sizeof(FolderName
), "%s - %s", tab
->QueryField(0), str
);
5534 core
->FreeString( str
);
5535 folder
= FolderName
;
5537 folder
= tab
->QueryField(parameters
->int0Parameter
);
5540 core
->GetSaveGameIterator()->CreateSaveGame(parameters
->int0Parameter
, folder
);
5543 /*EscapeAreaMove(S:Area*,I:X*,I:Y*,I:Face*)*/
5544 void GameScript::EscapeArea(Scriptable
* Sender
, Action
* parameters
)
5546 printf("EscapeArea/EscapeAreaMove\n");
5547 if (Sender
->Type
!=ST_ACTOR
) {
5548 Sender
->ReleaseCurrentAction();
5551 Map
*map
= Sender
->GetCurrentArea();
5553 Sender
->ReleaseCurrentAction();
5557 Point p
= Sender
->Pos
;
5558 map
->TMap
->AdjustNearestTravel(p
);
5560 if (parameters
->string0Parameter
[0]) {
5561 Point
q((short) parameters
->int0Parameter
, (short) parameters
->int1Parameter
);
5562 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, q
, 0, parameters
->int2Parameter
);
5564 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, p
, EA_DESTROY
, parameters
->int0Parameter
);
5566 //EscapeAreaCore will do its ReleaseCurrentAction
5567 //Sender->ReleaseCurrentAction();
5570 void GameScript::EscapeAreaDestroy(Scriptable
* Sender
, Action
* parameters
)
5572 printf("EscapeAreaDestroy\n");
5573 if (Sender
->Type
!=ST_ACTOR
) {
5574 Sender
->ReleaseCurrentAction();
5577 Map
*map
= Sender
->GetCurrentArea();
5579 Sender
->ReleaseCurrentAction();
5584 Point p
= Sender
->Pos
;
5585 map
->TMap
->AdjustNearestTravel(p
);
5586 //EscapeAreaCore will do its ReleaseCurrentAction
5587 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, p
, EA_DESTROY
, parameters
->int0Parameter
);
5590 /*EscapeAreaObjectMove(S:Area*,I:X*,I:Y*,I:Face*)*/
5591 void GameScript::EscapeAreaObject(Scriptable
* Sender
, Action
* parameters
)
5593 printf("EscapeAreaObject\n");
5594 if (Sender
->Type
!=ST_ACTOR
) {
5595 Sender
->ReleaseCurrentAction();
5598 Map
*map
= Sender
->GetCurrentArea();
5600 Sender
->ReleaseCurrentAction();
5604 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5606 Sender
->ReleaseCurrentAction();
5610 if (parameters
->string0Parameter
[0]) {
5611 Point
q((short) parameters
->int0Parameter
, (short) parameters
->int1Parameter
);
5612 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, q
, 0, parameters
->int2Parameter
);
5614 EscapeAreaCore( Sender
, p
, 0, p
, EA_DESTROY
, parameters
->int0Parameter
);
5616 //EscapeAreaCore will do its ReleaseCurrentAction
5619 //This one doesn't require the object to be seen?
5620 //We don't have that feature yet, so this is the same as EscapeAreaObject
5621 void GameScript::EscapeAreaObjectNoSee(Scriptable
* Sender
, Action
* parameters
)
5623 printf("EscapeAreaObjectNoSee\n");
5624 if (Sender
->Type
!=ST_ACTOR
) {
5625 Sender
->ReleaseCurrentAction();
5628 Map
*map
= Sender
->GetCurrentArea();
5630 Sender
->ReleaseCurrentAction();
5634 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5636 Sender
->ReleaseCurrentAction();
5640 Sender
->SetWait(parameters
->int0Parameter
);
5641 if (parameters
->string0Parameter
[0]) {
5642 Point
q((short) parameters
->int0Parameter
, (short) parameters
->int1Parameter
);
5643 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, q
, 0, parameters
->int2Parameter
);
5645 EscapeAreaCore( Sender
, p
, 0, p
, EA_DESTROY
|EA_NOSEE
, parameters
->int0Parameter
);
5647 //EscapeAreaCore will do its ReleaseCurrentAction
5650 //takes first fitting item from container at feet, doesn't seem to be working in the original engines
5651 void GameScript::PickUpItem(Scriptable
* Sender
, Action
* parameters
)
5653 if (Sender
->Type
!=ST_ACTOR
) {
5656 Actor
*scr
= (Actor
*) Sender
;
5657 Map
*map
= scr
->GetCurrentArea();
5658 Container
*c
= map
->GetPile(scr
->Pos
);
5659 if (!c
) { //this shouldn't happen, but lets prepare for the worst
5663 //the following part is coming from GUISCript.cpp with trivial changes
5664 int Slot
= c
->inventory
.FindItem(parameters
->string0Parameter
, 0);
5668 int res
= core
->CanMoveItem(c
->inventory
.GetSlotItem(Slot
) );
5669 if (!res
) { //cannot move
5672 CREItem
*item
= c
->RemoveItem(Slot
,0);
5676 if (res
!=-1 && scr
->InParty
) { //it is gold and we got the party pool!
5679 res
= scr
->inventory
.AddSlotItem(item
, SLOT_ONLYINVENTORY
);
5680 if (res
!=ASI_SUCCESS
) { //putting it back
5684 item_is_gold
: //we take gold!
5686 core
->GetGame()->PartyGold
+= res
;
5687 //if you want message here then use
5688 //core->GetGame()->AddGold(res);
5690 scr
->SetBase( IE_GOLD
, scr
->GetBase(IE_GOLD
) + res
);
5695 void GameScript::ChangeStoreMarkup(Scriptable
* /*Sender*/, Action
* parameters
)
5697 bool has_current
= false;
5701 Store
*store
= core
->GetCurrentStore();
5703 store
= core
->SetCurrentStore(parameters
->string0Parameter
,NULL
);
5705 if (strnicmp(store
->Name
, parameters
->string0Parameter
, 8) ) {
5706 //not the current store, we need some dirty hack
5708 strnlwrcpy(current
, store
->Name
, 8);
5709 strnuprcpy(owner
, store
->GetOwner(), 32);
5712 store
->BuyMarkup
= parameters
->int0Parameter
;
5713 store
->SellMarkup
= parameters
->int1Parameter
;
5714 //additional markup, is this depreciation???
5715 store
->DepreciationRate
= parameters
->int2Parameter
;
5717 //setting back old store (this will save our current store)
5718 core
->SetCurrentStore(current
, owner
);
5722 void GameScript::SetEncounterProbability(Scriptable
* /*Sender*/, Action
* parameters
)
5724 WorldMap
*wmap
= core
->GetWorldMap(parameters
->string0Parameter
);
5726 //no such starting area
5729 WMPAreaLink
*link
= wmap
->GetLink(parameters
->string0Parameter
, parameters
->string1Parameter
);
5733 link
->EncounterChance
= parameters
->int0Parameter
;
5736 void GameScript::SpawnPtActivate(Scriptable
* Sender
, Action
* parameters
)
5738 if (parameters
->objects
[1]) {
5739 Map
*map
= Sender
->GetCurrentArea();
5740 Spawn
*spawn
= map
->GetSpawn(parameters
->objects
[1]->objectName
);
5747 void GameScript::SpawnPtDeactivate(Scriptable
* Sender
, Action
* parameters
)
5749 if (parameters
->objects
[1]) {
5750 Map
*map
= Sender
->GetCurrentArea();
5751 Spawn
*spawn
= map
->GetSpawn(parameters
->objects
[1]->objectName
);
5758 void GameScript::SpawnPtSpawn(Scriptable
* Sender
, Action
* parameters
)
5760 if (parameters
->objects
[1]) {
5761 Map
*map
= Sender
->GetCurrentArea();
5762 Spawn
*spawn
= map
->GetSpawn(parameters
->objects
[1]->objectName
);
5764 spawn
->Enabled
= 1; //??? maybe use an unconditionality flag
5765 map
->TriggerSpawn(spawn
);
5770 void GameScript::ApplySpell(Scriptable
* Sender
, Action
* parameters
)
5774 if (!ResolveSpellName( spellres
, parameters
) ) {
5778 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5782 if (tar
->Type
==ST_ACTOR
) {
5783 //apply spell on target
5787 if (Sender->Type==ST_ACTOR) {
5788 owner = (Actor *) Sender;
5790 owner = (Actor *) tar;
5793 //core->ApplySpell(spellres, (Actor *) tar, owner, parameters->int1Parameter);
5794 core
->ApplySpell(spellres
, (Actor
*) tar
, Sender
, parameters
->int1Parameter
);
5796 //no idea about this one
5800 if (Sender->Type==ST_ACTOR) {
5801 owner = (Actor *) Sender;
5806 //apply spell on point
5808 GetPositionFromScriptable(tar
, d
, false);
5809 //core->ApplySpellPoint(spellres, tar->GetCurrentArea(), d, owner, parameters->int1Parameter);
5810 core
->ApplySpellPoint(spellres
, tar
->GetCurrentArea(), d
, Sender
, parameters
->int1Parameter
);
5814 void GameScript::ApplySpellPoint(Scriptable
* Sender
, Action
* parameters
)
5819 if (!ResolveSpellName( spellres
, parameters
) ) {
5823 if (Sender
->Type
==ST_ACTOR
) {
5824 owner
= (Actor
*) Sender
;
5828 core
->ApplySpellPoint(spellres
, Sender
->GetCurrentArea(), parameters
->pointParameter
, owner
, parameters
->int1Parameter
);
5831 //this is a gemrb extension
5832 //sets a variable to the stat value
5833 void GameScript::GetStat(Scriptable
* Sender
, Action
* parameters
)
5837 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5838 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5841 Actor
* actor
= ( Actor
* ) tar
;
5842 value
= actor
->GetStat( parameters
->int0Parameter
);
5844 SetVariable( Sender
, parameters
->string0Parameter
, value
);
5847 void GameScript::BreakInstants(Scriptable
* Sender
, Action
* /*parameters*/)
5849 //don't do anything, apparently the point of this action is to
5850 //delay the execution of further actions to the next AI cycle
5852 Sender
->ReleaseCurrentAction(); // this doesn't really need to block
5855 //an interesting improvement would be to pause game for a given duration
5856 void GameScript::PauseGame(Scriptable
* Sender
, Action
* /*parameters*/)
5858 GameControl
*gc
= core
->GetGameControl();
5860 gc
->SetDialogueFlags(DF_FREEZE_SCRIPTS
, BM_OR
);
5861 core
->DisplayConstantString(STR_SCRIPTPAUSED
,0xff0000);
5863 // releasing this action allows actions to continue executing,
5864 // so we force a wait
5866 Sender
->ReleaseCurrentAction(); // does this need to block?
5869 void GameScript::SetNoOneOnTrigger(Scriptable
* Sender
, Action
* parameters
)
5873 if (!parameters
->objects
[1]) {
5876 ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
5878 if (!ip
|| (ip
->Type
!=ST_TRIGGER
&& ip
->Type
!=ST_TRAVEL
&& ip
->Type
!=ST_PROXIMITY
)) {
5879 printf("Script error: No Trigger Named \"%s\"\n", parameters
->objects
[1]->objectName
);
5882 ip
->LastEntered
= 0;
5883 ip
->LastTrigger
= 0;
5884 ip
->LastTriggerObject
= 0;
5887 void GameScript::UseDoor(Scriptable
* Sender
, Action
* parameters
)
5889 GameControl
*gc
= core
->GetGameControl();
5891 Sender
->ReleaseCurrentAction();
5895 gc
->target_mode
= TARGET_MODE_NONE
;
5896 OpenDoor(Sender
, parameters
);
5898 Sender
->ReleaseCurrentAction(); // this is blocking, OpenDoor is not
5901 //this will force bashing the door
5902 void GameScript::BashDoor(Scriptable
* Sender
, Action
* parameters
)
5904 GameControl
*gc
= core
->GetGameControl();
5906 Sender
->ReleaseCurrentAction();
5910 gc
->target_mode
= TARGET_MODE_ATTACK
; //for bashing doors too
5911 OpenDoor(Sender
, parameters
);
5913 Sender
->ReleaseCurrentAction(); // this is blocking, OpenDoor is not
5917 void GameScript::ActivatePortalCursor(Scriptable
* Sender
, Action
* parameters
)
5921 if (!parameters
->objects
[1]) {
5924 ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
5929 if (ip
->Type
!=ST_PROXIMITY
&& ip
->Type
!=ST_TRAVEL
) {
5932 InfoPoint
*tar
= (InfoPoint
*) ip
;
5933 if (parameters
->int0Parameter
) {
5934 tar
->Trapped
|=PORTAL_CURSOR
;
5936 tar
->Trapped
&=~PORTAL_CURSOR
;
5941 void GameScript::EnablePortalTravel(Scriptable
* Sender
, Action
* parameters
)
5945 if (!parameters
->objects
[1]) {
5948 ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
5953 if (ip
->Type
!=ST_PROXIMITY
&& ip
->Type
!=ST_TRAVEL
) {
5956 InfoPoint
*tar
= (InfoPoint
*) ip
;
5957 if (parameters
->int0Parameter
) {
5958 tar
->Trapped
|=PORTAL_TRAVEL
;
5960 tar
->Trapped
&=~PORTAL_TRAVEL
;
5964 //unhardcoded iwd action (for the forge entrance change)
5965 void GameScript::ChangeDestination(Scriptable
* Sender
, Action
* parameters
)
5967 InfoPoint
*ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
5968 if (ip
&& (ip
->Type
==ST_TRAVEL
) ) {
5969 strnlwrcpy(ip
->Destination
, parameters
->string0Parameter
, 32);
5973 void GameScript::MoveCursorPoint(Scriptable
* /*Sender*/, Action
* parameters
)
5975 core
->GetVideoDriver()->MoveMouse(parameters
->pointParameter
.x
, parameters
->pointParameter
.y
);
5978 //false means, no talk
5979 void GameScript::DialogueInterrupt(Scriptable
* Sender
, Action
* parameters
)
5981 if (Sender
->Type
!=ST_ACTOR
) {
5984 Actor
* actor
= ( Actor
* ) Sender
;
5985 if ( parameters
->int0Parameter
!= 0 ) {
5986 actor
->SetMCFlag(MC_NO_TALK
, BM_NAND
);
5988 actor
->SetMCFlag(MC_NO_TALK
, BM_OR
);
5992 void GameScript::EquipMostDamagingMelee(Scriptable
* Sender
, Action
* /*parameters*/)
5994 if (Sender
->Type
!=ST_ACTOR
) {
5997 Actor
* actor
= ( Actor
* ) Sender
;
5998 actor
->inventory
.EquipBestWeapon(EQUIP_MELEE
);
6001 void GameScript::EquipRanged(Scriptable
* Sender
, Action
* /*parameters*/)
6003 if (Sender
->Type
!=ST_ACTOR
) {
6006 Actor
* actor
= ( Actor
* ) Sender
;
6007 actor
->inventory
.EquipBestWeapon(EQUIP_RANGED
);
6010 //will equip best weapon regardless of range considerations
6011 void GameScript::EquipWeapon(Scriptable
* Sender
, Action
* /*parameters*/)
6013 if (Sender
->Type
!=ST_ACTOR
) {
6016 Actor
* actor
= ( Actor
* ) Sender
;
6017 actor
->inventory
.EquipBestWeapon(EQUIP_MELEE
|EQUIP_RANGED
);
6020 void GameScript::SetBestWeapon(Scriptable
* Sender
, Action
* parameters
)
6022 if (Sender
->Type
!=ST_ACTOR
) {
6026 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6027 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6030 Actor
* actor
= ( Actor
* ) Sender
;
6032 Actor
*target
= (Actor
*) tar
;
6033 if (PersonalDistance(actor
,target
)>(unsigned int) parameters
->int0Parameter
) {
6034 actor
->inventory
.EquipBestWeapon(EQUIP_RANGED
);
6036 actor
->inventory
.EquipBestWeapon(EQUIP_MELEE
);
6040 void GameScript::FakeEffectExpiryCheck(Scriptable
* Sender
, Action
* parameters
)
6042 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6043 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6046 Actor
*target
= (Actor
*) tar
;
6047 target
->fxqueue
.RemoveExpiredEffects(parameters
->int0Parameter
);
6050 void GameScript::SetInterrupt(Scriptable
* Sender
, Action
* parameters
)
6052 if (parameters
->int0Parameter
) {
6053 Sender
->Interrupt();
6055 Sender
->NoInterrupt();
6059 void GameScript::SelectWeaponAbility(Scriptable
* Sender
, Action
* parameters
)
6061 if (Sender
->Type
!=ST_ACTOR
) {
6064 Actor
*scr
= (Actor
*) Sender
;
6065 int slot
= parameters
->int0Parameter
;
6066 int wslot
= scr
->inventory
.GetWeaponSlot();
6068 if (core
->QuerySlotType(slot
)&SLOT_WEAPON
) {
6070 if (slot
<0 || slot
>=MAX_QUICKWEAPONSLOT
) {
6073 scr
->SetEquippedQuickSlot(slot
, parameters
->int1Parameter
);
6077 wslot
= scr
->inventory
.GetQuickSlot();
6078 if (core
->QuerySlotType(slot
)&SLOT_ITEM
) {
6080 if (slot
<0 || slot
>=MAX_QUICKITEMSLOT
) {
6084 scr
->PCStats
->QuickItemHeaders
[slot
]=(ieWord
) parameters
->int1Parameter
;
6089 void GameScript::UseItem(Scriptable
* Sender
, Action
* parameters
)
6091 if (Sender
->Type
!=ST_ACTOR
) {
6092 Sender
->ReleaseCurrentAction();
6095 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6097 Sender
->ReleaseCurrentAction();
6100 Actor
*act
= (Actor
*) Sender
;
6102 ieDword header
, flags
;
6105 if (parameters
->string0Parameter
[0]) {
6106 Slot
= act
->inventory
.FindItem(parameters
->string0Parameter
, 0);
6107 //this IS in the original game code (ability)
6108 header
= parameters
->int0Parameter
;
6109 flags
= parameters
->int1Parameter
;
6111 Slot
= parameters
->int0Parameter
;
6112 //this is actually not in the original game code
6113 header
= parameters
->int1Parameter
;
6114 flags
= parameters
->int2Parameter
;
6118 Sender
->ReleaseCurrentAction();
6122 if (!ResolveItemName( itemres
, act
, Slot
) ) {
6123 Sender
->ReleaseCurrentAction();
6127 unsigned int dist
= GetItemDistance(itemres
, header
);
6129 if (PersonalDistance(tar
->Pos
, Sender
) > dist
) {
6130 MoveNearerTo(Sender
, tar
, dist
);
6134 act
->UseItem(Slot
, header
, tar
, flags
);
6135 Sender
->ReleaseCurrentAction();
6138 void GameScript::UseItemPoint(Scriptable
* Sender
, Action
* parameters
)
6140 if (Sender
->Type
!=ST_ACTOR
) {
6141 Sender
->ReleaseCurrentAction();
6145 Actor
*act
= (Actor
*) Sender
;
6151 if (parameters
->string0Parameter
[0]) {
6152 Slot
= act
->inventory
.FindItem(parameters
->string0Parameter
, 0);
6153 //this IS in the original game code (ability)
6154 header
= parameters
->int0Parameter
;
6155 flags
= parameters
->int1Parameter
;
6157 Slot
= parameters
->int0Parameter
;
6158 //this is actually not in the original game code
6159 header
= parameters
->int1Parameter
;
6160 flags
= parameters
->int2Parameter
;
6164 Sender
->ReleaseCurrentAction();
6168 if (!ResolveItemName( itemres
, act
, Slot
) ) {
6169 Sender
->ReleaseCurrentAction();
6173 unsigned int dist
= GetItemDistance(itemres
, header
);
6175 if (PersonalDistance(parameters
->pointParameter
, Sender
) > dist
) {
6176 MoveNearerTo(Sender
, parameters
->pointParameter
, dist
, 0);
6180 act
->UseItemPoint(Slot
, header
, parameters
->pointParameter
, flags
);
6181 Sender
->ReleaseCurrentAction();
6184 //addfeat will be able to remove feats too
6185 //(the second int parameter is a bitmode)
6186 void GameScript::AddFeat(Scriptable
* Sender
, Action
* parameters
)
6188 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6189 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6192 Actor
*actor
= (Actor
*)tar
;
6193 actor
->SetFeat(parameters
->int0Parameter
, parameters
->int1Parameter
);
6196 void GameScript::MatchHP(Scriptable
* Sender
, Action
* parameters
)
6198 if (Sender
->Type
!=ST_ACTOR
) {
6201 Actor
*scr
= (Actor
*) Sender
;
6202 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6203 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6206 Actor
*actor
= (Actor
*)tar
;
6207 switch (parameters
->int0Parameter
) {
6208 case 1: //sadly the hpflags are not the same as stats
6209 actor
->SetBase(IE_HITPOINTS
,scr
->GetBase(IE_HITPOINTS
));
6212 actor
->SetBase(IE_MAXHITPOINTS
, scr
->GetBase(IE_MAXHITPOINTS
));
6214 default: //this is gemrb extension
6215 actor
->SetBase(parameters
->int0Parameter
, scr
->GetBase(parameters
->int0Parameter
));
6220 void GameScript::ChangeColor(Scriptable
* Sender
, Action
* parameters
)
6222 if (Sender
->Type
!=ST_ACTOR
) {
6225 Actor
*scr
= (Actor
*) Sender
;
6226 ieDword stat
= parameters
->int0Parameter
;
6227 if (stat
<9 || stat
>14) {
6230 stat
+= IE_COLORS
- 9;
6231 scr
->SetBase(stat
, (scr
->GetBase(stat
)&~255)|(parameters
->int1Parameter
&255));
6234 void GameScript::AddKit(Scriptable
* Sender
, Action
* parameters
)
6236 if (Sender
->Type
!=ST_ACTOR
) {
6239 Actor
*scr
= (Actor
*) Sender
;
6240 //remove previous kit stuff
6241 scr
->SetBase(IE_KIT
, parameters
->int0Parameter
);
6244 void GameScript::AddSuperKit(Scriptable
* Sender
, Action
* parameters
)
6246 if (Sender
->Type
!=ST_ACTOR
) {
6249 Actor
*scr
= (Actor
*) Sender
;
6250 scr
->SetBase(IE_KIT
, parameters
->int0Parameter
);
6253 void GameScript::SetSelection(Scriptable
* /*Sender*/, Action
* parameters
)
6255 GameControl
*gc
= core
->GetGameControl();
6259 gc
->SelectActor(parameters
->int0Parameter
, parameters
->int1Parameter
);
6262 //this action is weird in the original game, because it overwrites ALL
6264 //in this version, if a stat is set to 0, it won't change
6265 //it will alter only the main IDS stats
6266 void GameScript::ChangeAIType(Scriptable
* Sender
, Action
* parameters
)
6268 if (Sender
->Type
!=ST_ACTOR
) {
6271 Object
*ob
= parameters
->objects
[1];
6275 Actor
*scr
= (Actor
*) Sender
;
6276 for (int i
=0;i
<MAX_OBJECT_FIELDS
;i
++) {
6277 int val
= ob
->objectFields
[i
];
6279 if (!strnicmp(ObjectIDSTableNames
[i
],"ea",8)) {
6280 scr
->SetBase(IE_EA
, val
);
6283 if (!strnicmp(ObjectIDSTableNames
[i
],"general",8)) {
6284 scr
->SetBase(IE_GENERAL
, val
);
6287 if (!strnicmp(ObjectIDSTableNames
[i
],"race",8)) {
6288 scr
->SetBase(IE_RACE
, val
);
6291 if (!strnicmp(ObjectIDSTableNames
[i
],"class",8)) {
6292 scr
->SetBase(IE_CLASS
, val
);
6295 if (!strnicmp(ObjectIDSTableNames
[i
],"gender",8)) {
6296 scr
->SetBase(IE_SEX
, val
);
6299 if (!strnicmp(ObjectIDSTableNames
[i
],"specific",8)) {
6300 scr
->SetBase(IE_SPECIFIC
, val
);
6303 if (!strnicmp(ObjectIDSTableNames
[i
],"align",8)) {
6304 scr
->SetBase(IE_ALIGNMENT
, val
);
6310 void GameScript::Follow(Scriptable
* Sender
, Action
* parameters
)
6312 if (Sender
->Type
!=ST_ACTOR
) {
6316 Actor
*scr
= (Actor
*)Sender
;
6317 scr
->FollowOffset
= parameters
->pointParameter
;
6320 void GameScript::FollowCreature(Scriptable
* Sender
, Action
* parameters
)
6322 if (Sender
->Type
!=ST_ACTOR
) {
6323 Sender
->ReleaseCurrentAction();
6327 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6328 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6329 Sender
->ReleaseCurrentAction();
6332 Actor
*scr
= (Actor
*)Sender
;
6333 Actor
*actor
= (Actor
*)tar
;
6334 scr
->LastFollowed
= actor
->GetID();
6335 scr
->FollowOffset
.empty();
6336 if (!scr
->InMove() || scr
->Destination
!= actor
->Pos
) {
6337 scr
->WalkTo(actor
->Pos
, 0, 1);
6341 void GameScript::RunFollow(Scriptable
* Sender
, Action
* parameters
)
6343 if (Sender
->Type
!=ST_ACTOR
) {
6344 Sender
->ReleaseCurrentAction();
6348 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6349 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6350 Sender
->ReleaseCurrentAction();
6353 Actor
*scr
= (Actor
*)Sender
;
6354 Actor
*actor
= (Actor
*)tar
;
6355 scr
->LastFollowed
= actor
->GetID();
6356 scr
->FollowOffset
.empty();
6357 if (!scr
->InMove() || scr
->Destination
!= actor
->Pos
) {
6358 scr
->WalkTo(actor
->Pos
, IF_RUNNING
, 1);
6362 void GameScript::ProtectPoint(Scriptable
* Sender
, Action
* parameters
)
6364 if (Sender
->Type
!=ST_ACTOR
) {
6365 Sender
->ReleaseCurrentAction();
6368 Actor
*scr
= (Actor
*)Sender
;
6369 if (!scr
->InMove() || scr
->Destination
!= parameters
->pointParameter
) {
6370 scr
->WalkTo( parameters
->pointParameter
, 0, 1 );
6372 // we should handle 'Protect' here rather than just unblocking
6373 Sender
->ReleaseCurrentAction();
6376 void GameScript::ProtectObject(Scriptable
* Sender
, Action
* parameters
)
6378 if (Sender
->Type
!=ST_ACTOR
) {
6379 Sender
->ReleaseCurrentAction();
6383 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6384 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6385 Sender
->ReleaseCurrentAction();
6388 Actor
*scr
= (Actor
*)Sender
;
6389 Actor
*actor
= (Actor
*)tar
;
6390 scr
->LastFollowed
= actor
->GetID();
6391 scr
->LastProtected
= actor
->GetID();
6393 scr
->FollowOffset
.x
= parameters
->int0Parameter
;
6394 scr
->FollowOffset
.y
= parameters
->int0Parameter
;
6395 if (!scr
->InMove() || scr
->Destination
!= tar
->Pos
) {
6396 scr
->WalkTo( tar
->Pos
, 0, MAX_OPERATING_DISTANCE
);
6398 // we should handle 'Protect' here rather than just unblocking
6399 Sender
->ReleaseCurrentAction();
6402 //keeps following the object in formation
6403 void GameScript::FollowObjectFormation(Scriptable
* Sender
, Action
* parameters
)
6405 GameControl
*gc
= core
->GetGameControl();
6407 Sender
->ReleaseCurrentAction();
6410 if (Sender
->Type
!=ST_ACTOR
) {
6411 Sender
->ReleaseCurrentAction();
6415 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6416 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6417 Sender
->ReleaseCurrentAction();
6420 Actor
*scr
= (Actor
*)Sender
;
6421 Actor
*actor
= (Actor
*)tar
;
6422 scr
->LastFollowed
= actor
->GetID();
6423 ieDword formation
= parameters
->int0Parameter
;
6424 ieDword pos
= parameters
->int1Parameter
;
6425 scr
->FollowOffset
= gc
->GetFormationOffset(formation
, pos
);
6426 if (!scr
->InMove() || scr
->Destination
!= tar
->Pos
) {
6427 scr
->WalkTo( tar
->Pos
, 0, 1 );
6429 Sender
->ReleaseCurrentAction();
6432 //walks to a specific offset of target (quite like movetoobject)
6433 void GameScript::Formation(Scriptable
* Sender
, Action
* parameters
)
6435 GameControl
*gc
= core
->GetGameControl();
6437 Sender
->ReleaseCurrentAction();
6440 if (Sender
->Type
!=ST_ACTOR
) {
6441 Sender
->ReleaseCurrentAction();
6444 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6446 Sender
->ReleaseCurrentAction();
6449 Actor
*scr
= (Actor
*)Sender
;
6450 ieDword formation
= parameters
->int0Parameter
;
6451 ieDword pos
= parameters
->int1Parameter
;
6452 Point FollowOffset
= gc
->GetFormationOffset(formation
, pos
);
6453 FollowOffset
.x
+=tar
->Pos
.x
;
6454 FollowOffset
.y
+=tar
->Pos
.y
;
6455 if (!scr
->InMove() || scr
->Destination
!= FollowOffset
) {
6456 scr
->WalkTo( FollowOffset
, 0, 1 );
6460 void GameScript::TransformItem(Scriptable
* Sender
, Action
* parameters
)
6462 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6463 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6466 TransformItemCore((Actor
*)tar
, parameters
, true);
6469 void GameScript::TransformPartyItem(Scriptable
* /*Sender*/, Action
* parameters
)
6471 Game
*game
= core
->GetGame();
6472 int i
= game
->GetPartySize(false);
6474 Actor
*tar
= game
->GetPC(i
, false);
6475 TransformItemCore(tar
, parameters
, true);
6479 void GameScript::TransformItemAll(Scriptable
* Sender
, Action
* parameters
)
6481 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6482 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6485 TransformItemCore((Actor
*)tar
, parameters
, false);
6488 void GameScript::TransformPartyItemAll(Scriptable
* /*Sender*/, Action
* parameters
)
6490 Game
*game
= core
->GetGame();
6491 int i
= game
->GetPartySize(false);
6493 Actor
*tar
= game
->GetPC(i
, false);
6494 TransformItemCore(tar
, parameters
, false);
6498 void GameScript::GeneratePartyMember(Scriptable
* /*Sender*/, Action
* parameters
)
6500 AutoTable
pcs("bios");
6504 const char* string
= pcs
->QueryField( parameters
->int0Parameter
, 0 );
6505 int pos
= gamedata
->LoadCreature(string
,0,false);
6509 Actor
*actor
= core
->GetGame()->GetNPC(pos
);
6513 actor
->SetOrientation(parameters
->int1Parameter
, false);
6514 actor
->MoveTo(parameters
->pointParameter
);
6517 void GameScript::EnableFogDither(Scriptable
* /*Sender*/, Action
* /*parameters*/)
6519 core
->FogOfWar
|=FOG_DRAWFOG
;
6522 void GameScript::DisableFogDither(Scriptable
* /*Sender*/, Action
* /*parameters*/)
6524 core
->FogOfWar
&=~FOG_DRAWFOG
;
6527 void DeleteAllSpriteCovers()
6529 Game
*game
= core
->GetGame();
6530 int i
= game
->GetPartySize(false);
6532 Selectable
*tar
= (Selectable
*) game
->GetPC(i
, false);
6533 tar
->SetSpriteCover(NULL
);
6537 void GameScript::EnableSpriteDither(Scriptable
* /*Sender*/, Action
* /*parameters*/)
6539 core
->FogOfWar
&=~FOG_DITHERSPRITES
;
6540 DeleteAllSpriteCovers();
6543 void GameScript::DisableSpriteDither(Scriptable
* /*Sender*/, Action
* /*parameters*/)
6545 core
->FogOfWar
|=~FOG_DITHERSPRITES
;
6546 DeleteAllSpriteCovers();
6549 //the PST crew apparently loved hardcoding stuff
6550 ieResRef RebusResRef
={"DABUS1"};
6552 void GameScript::FloatRebus(Scriptable
* Sender
, Action
* parameters
)
6554 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6555 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6558 Actor
*actor
= (Actor
*)tar
;
6559 RebusResRef
[5]=(char) core
->Roll(1,5,'0');
6560 ScriptedAnimation
*vvc
= gamedata
->GetScriptedAnimation(RebusResRef
, 0);
6562 //setting the height
6563 vvc
->ZPos
=actor
->size
*20;
6565 //maybe this needs setting up some time
6566 vvc
->SetDefaultDuration(20);
6567 actor
->AddVVCell(vvc
);
6571 void GameScript::IncrementKillStat(Scriptable
* Sender
, Action
* parameters
)
6573 DataFileMgr
* ini
= core
->GetBeastsINI();
6578 sprintf(key
,"%d", parameters
->int0Parameter
);
6579 const char *variable
= ini
->GetKeyAsString( key
, "killvar", NULL
);
6583 ieDword value
= CheckVariable( Sender
, variable
, "GLOBAL" ) + 1;
6584 SetVariable( Sender
, variable
, "GLOBAL", value
);
6587 //this action plays a vvc animation over target
6588 //we simply apply the appropriate opcode on the target (see iwdopcodes)
6589 //the list of vvcs is in iwdshtab.2da
6590 EffectRef fx_iwd_visual_spell_hit_ref
={"IWDVisualSpellHit",NULL
,-1};
6592 void GameScript::SpellHitEffectSprite(Scriptable
* Sender
, Action
* parameters
)
6594 Scriptable
* src
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6598 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[2] );
6599 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6602 int opcode
= EffectQueue::ResolveEffect(fx_iwd_visual_spell_hit_ref
);
6603 Effect
*fx
= core
->GetEffect(opcode
);
6605 //invalid effect name didn't resolve to opcode
6610 fx
->Parameter2
= parameters
->int0Parameter
;
6611 //height (not sure if this is in the opcode, but seems acceptable)
6612 fx
->Parameter1
= parameters
->int1Parameter
;
6613 fx
->Probability1
=100;
6614 fx
->TimingMode
=FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES
;
6615 core
->ApplyEffect(fx
, (Actor
*) tar
, src
);
6618 void GameScript::SpellHitEffectPoint(Scriptable
* Sender
, Action
* parameters
)
6620 Scriptable
* src
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6625 int opcode
= EffectQueue::ResolveEffect(fx_iwd_visual_spell_hit_ref
);
6626 Effect
*fx
= core
->GetEffect(opcode
);
6628 //invalid effect name didn't resolve to opcode
6633 fx
->Parameter2
= parameters
->int0Parameter
;
6634 //height (not sure if this is in the opcode, but seems acceptable)
6635 fx
->Parameter1
= parameters
->int1Parameter
;
6636 fx
->Probability1
=100;
6637 fx
->TimingMode
=FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES
;
6638 fx
->PosX
=parameters
->pointParameter
.x
;
6639 fx
->PosY
=parameters
->pointParameter
.y
;
6640 core
->ApplyEffect(fx
, NULL
, src
);
6644 void GameScript::ClickLButtonObject(Scriptable
* Sender
, Action
* parameters
)
6646 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6648 Sender
->ReleaseCurrentAction(); // this is blocking for some reason?
6651 ClickCore(Sender
, tar
->Pos
, GEM_MB_ACTION
, parameters
->int0Parameter
);
6654 void GameScript::ClickLButtonPoint(Scriptable
* Sender
, Action
* parameters
)
6656 ClickCore(Sender
, parameters
->pointParameter
, GEM_MB_ACTION
, parameters
->int0Parameter
);
6659 void GameScript::ClickRButtonObject(Scriptable
* Sender
, Action
* parameters
)
6661 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6663 Sender
->ReleaseCurrentAction(); // this is blocking for some reason?
6666 ClickCore(Sender
, tar
->Pos
, GEM_MB_MENU
, parameters
->int0Parameter
);
6669 void GameScript::ClickRButtonPoint(Scriptable
* Sender
, Action
* parameters
)
6671 ClickCore(Sender
, parameters
->pointParameter
, GEM_MB_MENU
, parameters
->int0Parameter
);
6674 void GameScript::DoubleClickLButtonObject(Scriptable
* Sender
, Action
* parameters
)
6676 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6678 Sender
->ReleaseCurrentAction(); // this is blocking for some reason?
6681 ClickCore(Sender
, tar
->Pos
, GEM_MB_ACTION
|GEM_MB_DOUBLECLICK
, parameters
->int0Parameter
);
6684 void GameScript::DoubleClickLButtonPoint(Scriptable
* Sender
, Action
* parameters
)
6686 ClickCore(Sender
, parameters
->pointParameter
, GEM_MB_ACTION
|GEM_MB_DOUBLECLICK
, parameters
->int0Parameter
);
6689 void GameScript::DoubleClickRButtonObject(Scriptable
* Sender
, Action
* parameters
)
6691 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6693 Sender
->ReleaseCurrentAction(); // this is blocking for some reason?
6696 ClickCore(Sender
, tar
->Pos
, GEM_MB_MENU
|GEM_MB_DOUBLECLICK
, parameters
->int0Parameter
);
6699 void GameScript::DoubleClickRButtonPoint(Scriptable
* Sender
, Action
* parameters
)
6701 ClickCore(Sender
, parameters
->pointParameter
, GEM_MB_MENU
|GEM_MB_DOUBLECLICK
, parameters
->int0Parameter
);
6704 //Picks 5 lines from wish.2da
6705 //Gets the 5 values (column is int0parameter) from the table.
6706 //Sets the five wishpowerNN to 1, while resets the rest to 0.
6707 //TODO: investigate what happens with * values
6708 void GameScript::SetupWish(Scriptable
* Sender
, Action
* parameters
)
6710 SetupWishCore(Sender
, parameters
->int0Parameter
, parameters
->int1Parameter
);
6713 //The same as the previous action, except that the column parameter comes from
6714 //the target object's wisdom directly (this action is not used in the original)
6715 void GameScript::SetupWishObject(Scriptable
* Sender
, Action
* parameters
)
6717 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6718 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6721 SetupWishCore(Sender
, ((Actor
*)tar
)->GetStat(IE_WIS
), parameters
->int0Parameter
);
6724 //GemRB specific action
6725 //Sets up multiple tokens randomly (one per 2da row)
6726 //the row label column sets the token names
6727 void GameScript::SetToken2DA(Scriptable
* /*Sender*/, Action
* parameters
)
6731 ieVariable tokenname
;
6733 AutoTable
tm(parameters
->string0Parameter
);
6735 printStatus( "ERROR", LIGHT_RED
);
6736 printf( "Cannot find %s.2da.\n", parameters
->string0Parameter
);
6740 count
= tm
->GetRowCount();
6741 for(i
=0;i
<count
;i
++) {
6742 //roll a random number between 0 and column #
6743 j
= core
->Roll(1,tm
->GetColumnCount(i
),-1);
6744 strnuprcpy(tokenname
, tm
->GetRowName(i
), 32);
6745 core
->GetTokenDictionary()->SetAtCopy( tokenname
, tm
->QueryField(i
, j
) );
6749 //this is a gemrb extension for scriptable tracks
6750 void GameScript::SetTrackString(Scriptable
* Sender
, Action
* parameters
)
6752 Map
*map
= Sender
->GetCurrentArea();
6754 map
->SetTrackString(parameters
->int0Parameter
, parameters
->int1Parameter
, parameters
->int2Parameter
);
6757 void GameScript::StateOverrideFlag(Scriptable
* /*Sender*/, Action
* parameters
)
6759 core
->GetGame()->StateOverrideFlag
= parameters
->int0Parameter
;
6762 void GameScript::StateOverrideTime(Scriptable
* /*Sender*/, Action
* parameters
)
6764 core
->GetGame()->StateOverrideTime
= parameters
->int0Parameter
;
6767 void GameScript::BanterBlockFlag(Scriptable
* /*Sender*/, Action
* parameters
)
6769 core
->GetGame()->BanterBlockFlag
= parameters
->int0Parameter
;
6772 void GameScript::BanterBlockTime(Scriptable
* /*Sender*/, Action
* parameters
)
6774 core
->GetGame()->BanterBlockTime
= parameters
->int0Parameter
;