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.
21 #include "GameScript.h"
25 #include "AmbientMgr.h"
27 #include "DataFileMgr.h"
30 #include "GameControl.h"
35 #include "SaveGameIterator.h"
36 #include "ScriptEngine.h"
41 //------------------------------------------------------------
43 //-------------------------------------------------------------
45 void GameScript::SetExtendedNight(Scriptable
* Sender
, Action
* parameters
)
47 Map
*map
=Sender
->GetCurrentArea();
48 //sets the 'can rest other' bit
49 if (parameters
->int0Parameter
) {
50 map
->AreaType
|=AT_EXTENDED_NIGHT
;
52 map
->AreaType
&=~AT_EXTENDED_NIGHT
;
56 void GameScript::SetAreaRestFlag(Scriptable
* Sender
, Action
* parameters
)
58 Map
*map
=Sender
->GetCurrentArea();
59 //sets the 'can rest other' bit
60 if (parameters
->int0Parameter
) {
61 map
->AreaType
|=AT_CAN_REST
;
63 map
->AreaType
&=~AT_CAN_REST
;
67 void GameScript::AddAreaFlag(Scriptable
* Sender
, Action
* parameters
)
69 Map
*map
=Sender
->GetCurrentArea();
70 map
->AreaFlags
|=parameters
->int0Parameter
;
73 void GameScript::RemoveAreaFlag(Scriptable
* Sender
, Action
* parameters
)
75 Map
*map
=Sender
->GetCurrentArea();
76 map
->AreaFlags
&=~parameters
->int0Parameter
;
79 void GameScript::SetAreaFlags(Scriptable
* Sender
, Action
* parameters
)
81 Map
*map
=Sender
->GetCurrentArea();
82 ieDword value
= map
->AreaFlags
;
83 HandleBitMod( value
, parameters
->int0Parameter
, parameters
->int1Parameter
);
87 void GameScript::AddAreaType(Scriptable
* Sender
, Action
* parameters
)
89 Map
*map
=Sender
->GetCurrentArea();
90 map
->AreaType
|=parameters
->int0Parameter
;
93 void GameScript::RemoveAreaType(Scriptable
* Sender
, Action
* parameters
)
95 Map
*map
=Sender
->GetCurrentArea();
96 map
->AreaType
&=~parameters
->int0Parameter
;
99 void GameScript::NoActionAtAll(Scriptable
* /*Sender*/, Action
* /*parameters*/)
104 // this action stops modal actions, so...
105 void GameScript::NoAction(Scriptable
* Sender
, Action
* /*parameters*/)
107 if (Sender
->Type
!=ST_ACTOR
) {
110 Actor
*actor
= (Actor
*) Sender
;
111 actor
->SetModal( MS_NONE
);
114 void GameScript::SG(Scriptable
* Sender
, Action
* parameters
)
116 SetVariable( Sender
, parameters
->string0Parameter
, "GLOBAL", parameters
->int0Parameter
);
119 void GameScript::SetGlobal(Scriptable
* Sender
, Action
* parameters
)
121 SetVariable( Sender
, parameters
->string0Parameter
, parameters
->int0Parameter
);
124 void GameScript::SetGlobalRandom(Scriptable
* Sender
, Action
* parameters
)
126 int max
=parameters
->int1Parameter
-parameters
->int0Parameter
+1;
128 SetVariable( Sender
, parameters
->string0Parameter
, RandomNumValue
%max
+parameters
->int0Parameter
);
130 SetVariable( Sender
, parameters
->string0Parameter
, 0);
134 void GameScript::StartTimer(Scriptable
* Sender
, Action
* parameters
)
136 Sender
->StartTimer(parameters
->int0Parameter
, parameters
->int1Parameter
);
139 void GameScript::StartRandomTimer(Scriptable
* Sender
, Action
* parameters
)
141 ieDword value
= core
->Roll(1, parameters
->int2Parameter
-parameters
->int1Parameter
, parameters
->int2Parameter
-1);
142 Sender
->StartTimer(parameters
->int0Parameter
, value
);
145 void GameScript::SetGlobalTimer(Scriptable
* Sender
, Action
* parameters
)
149 mytime
=core
->GetGame()->GameTime
; //gametime (should increase it)
150 SetVariable( Sender
, parameters
->string0Parameter
,
151 parameters
->int0Parameter
*AI_UPDATE_TIME
+ mytime
);
154 void GameScript::SetGlobalTimerRandom(Scriptable
* Sender
, Action
* parameters
)
158 int random
=parameters
->int1Parameter
-parameters
->int0Parameter
+1;
160 random
= RandomNumValue
% random
+ parameters
->int0Parameter
;
164 mytime
=core
->GetGame()->GameTime
; //gametime (should increase it)
165 SetVariable( Sender
, parameters
->string0Parameter
, random
*AI_UPDATE_TIME
+ mytime
);
168 void GameScript::SetGlobalTimerOnce(Scriptable
* Sender
, Action
* parameters
)
170 ieDword mytime
= CheckVariable( Sender
, parameters
->string0Parameter
);
174 mytime
=core
->GetGame()->GameTime
; //gametime (should increase it)
175 SetVariable( Sender
, parameters
->string0Parameter
,
176 parameters
->int0Parameter
*AI_UPDATE_TIME
+ mytime
);
179 void GameScript::RealSetGlobalTimer(Scriptable
* Sender
, Action
* parameters
)
181 ieDword mytime
=core
->GetGame()->RealTime
;
183 SetVariable( Sender
, parameters
->string0Parameter
,
184 parameters
->int0Parameter
+ mytime
);
187 void GameScript::ChangeAllegiance(Scriptable
* Sender
, Action
* parameters
)
189 Scriptable
*scr
= Sender
;
190 if (parameters
->objects
[1]) {
191 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
193 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
196 Actor
* actor
= ( Actor
* ) scr
;
197 actor
->SetBase( IE_EA
, parameters
->int0Parameter
);
200 void GameScript::ChangeGeneral(Scriptable
* Sender
, Action
* parameters
)
202 Scriptable
*scr
= Sender
;
203 if (parameters
->objects
[1]) {
204 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
206 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
209 Actor
* actor
= ( Actor
* ) scr
;
210 actor
->SetBase( IE_GENERAL
, parameters
->int0Parameter
);
213 void GameScript::ChangeRace(Scriptable
* Sender
, Action
* parameters
)
215 Scriptable
*scr
= Sender
;
216 if (parameters
->objects
[1]) {
217 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
219 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
222 Actor
* actor
= ( Actor
* ) scr
;
223 actor
->SetBase( IE_RACE
, parameters
->int0Parameter
);
226 void GameScript::ChangeClass(Scriptable
* Sender
, Action
* parameters
)
228 Scriptable
*scr
= Sender
;
229 if (parameters
->objects
[1]) {
230 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
232 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
235 Actor
* actor
= ( Actor
* ) scr
;
236 actor
->SetBase( IE_CLASS
, parameters
->int0Parameter
);
239 void GameScript::SetNamelessClass(Scriptable
* /*Sender*/, Action
* parameters
)
241 //same as Protagonist
242 Actor
* actor
= core
->GetGame()->GetPC(0, false);
243 actor
->SetBase( IE_CLASS
, parameters
->int0Parameter
);
246 void GameScript::SetNamelessDisguise(Scriptable
* Sender
, Action
* parameters
)
248 SetVariable(Sender
, "APPEARANCE", "GLOBAL", parameters
->int0Parameter
);
249 core
->SetEventFlag(EF_UPDATEANIM
);
252 void GameScript::ChangeSpecifics(Scriptable
* Sender
, Action
* parameters
)
254 Scriptable
*scr
= Sender
;
255 if (parameters
->objects
[1]) {
256 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
258 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
261 Actor
* actor
= ( Actor
* ) scr
;
262 actor
->SetBase( IE_SPECIFIC
, parameters
->int0Parameter
);
265 void GameScript::PermanentStatChange(Scriptable
* Sender
, Action
* parameters
)
267 Scriptable
*scr
= Sender
;
268 if (parameters
->objects
[1]) {
269 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
271 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
274 Actor
* actor
= ( Actor
* ) scr
;
276 switch (parameters
->int1Parameter
) {
278 value
= actor
->GetBase(parameters
->int0Parameter
);
279 value
-= parameters
->int2Parameter
;
282 value
= actor
->GetBase(parameters
->int0Parameter
);
283 value
+= parameters
->int2Parameter
;
286 default: //no idea what happens
287 value
= parameters
->int2Parameter
;
290 actor
->SetBase( parameters
->int0Parameter
, value
);
293 void GameScript::ChangeStat(Scriptable
* Sender
, Action
* parameters
)
295 Scriptable
*scr
= Sender
;
296 if (parameters
->objects
[1]) {
297 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
299 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
302 Actor
* actor
= ( Actor
* ) scr
;
303 ieDword value
= parameters
->int1Parameter
;
304 if (parameters
->int2Parameter
==1) {
305 value
+=actor
->GetBase(parameters
->int0Parameter
);
307 actor
->SetBase( parameters
->int0Parameter
, value
);
310 void GameScript::ChangeStatGlobal(Scriptable
* Sender
, Action
* parameters
)
312 Scriptable
*scr
= Sender
;
313 if (parameters
->objects
[1]) {
314 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
316 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
319 ieDword value
= (ieDword
) CheckVariable( Sender
, parameters
->string0Parameter
, parameters
->string1Parameter
);
320 Actor
* actor
= ( Actor
* ) scr
;
321 if (parameters
->int1Parameter
==1) {
322 value
+=actor
->GetBase(parameters
->int0Parameter
);
324 actor
->SetBase( parameters
->int0Parameter
, value
);
327 void GameScript::ChangeGender(Scriptable
* Sender
, Action
* parameters
)
329 Scriptable
*scr
= Sender
;
330 if (parameters
->objects
[1]) {
331 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
333 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
336 Actor
* actor
= ( Actor
* ) scr
;
337 actor
->SetBase( IE_SEX
, parameters
->int0Parameter
);
340 void GameScript::ChangeAlignment(Scriptable
* Sender
, Action
* parameters
)
342 Scriptable
*scr
= Sender
;
343 if (parameters
->objects
[1]) {
344 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
346 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
349 Actor
* actor
= ( Actor
* ) scr
;
350 actor
->SetBase( IE_ALIGNMENT
, parameters
->int0Parameter
);
353 void GameScript::SetFaction(Scriptable
* Sender
, Action
* parameters
)
355 Scriptable
*scr
= Sender
;
356 if (parameters
->objects
[1]) {
357 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
359 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
362 Actor
* actor
= ( Actor
* ) scr
;
363 actor
->SetBase( IE_FACTION
, parameters
->int0Parameter
);
366 void GameScript::SetHP(Scriptable
* Sender
, Action
* parameters
)
368 Scriptable
*scr
= Sender
;
369 if (parameters
->objects
[1]) {
370 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
372 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
375 Actor
* actor
= ( Actor
* ) scr
;
376 actor
->SetBase( IE_HITPOINTS
, parameters
->int0Parameter
);
379 void GameScript::SetHPPercent(Scriptable
* Sender
, Action
* parameters
)
381 Scriptable
*scr
= Sender
;
382 if (parameters
->objects
[1]) {
383 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
385 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
388 Actor
* actor
= ( Actor
* ) scr
;
389 actor
->NewBase( IE_HITPOINTS
, parameters
->int0Parameter
, MOD_PERCENT
);
392 void GameScript::AddHP(Scriptable
* Sender
, Action
* parameters
)
394 Scriptable
*scr
= Sender
;
395 if (parameters
->objects
[1]) {
396 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
398 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
401 Actor
* actor
= ( Actor
* ) scr
;
402 actor
->NewBase(IE_HITPOINTS
, parameters
->int0Parameter
, MOD_ADDITIVE
);
405 //this works on an object (pst)
406 //but can also work on actor itself (gemrb)
407 void GameScript::SetTeam(Scriptable
* Sender
, Action
* parameters
)
409 Scriptable
*scr
= Sender
;
410 if (parameters
->objects
[1]) {
411 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
413 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
416 Actor
* actor
= ( Actor
* ) scr
;
417 actor
->SetBase( IE_TEAM
, parameters
->int0Parameter
);
420 //this works on an object (gemrb)
421 //or on Myself if object isn't given (iwd2)
422 void GameScript::SetTeamBit(Scriptable
* Sender
, Action
* parameters
)
424 Scriptable
*scr
= Sender
;
425 if (parameters
->objects
[1]) {
426 scr
=GetActorFromObject( Sender
, parameters
->objects
[1] );
428 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
431 Actor
* actor
= ( Actor
* ) scr
;
432 if (parameters
->int1Parameter
) {
433 actor
->SetBase( IE_TEAM
, actor
->GetStat(IE_TEAM
) | parameters
->int0Parameter
);
435 actor
->SetBase( IE_TEAM
, actor
->GetStat(IE_TEAM
) & ~parameters
->int0Parameter
);
439 void GameScript::TriggerActivation(Scriptable
* Sender
, Action
* parameters
)
443 if (!parameters
->objects
[1]) {
446 ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
448 if (!ip
|| (ip
->Type
!=ST_TRIGGER
&& ip
->Type
!=ST_TRAVEL
&& ip
->Type
!=ST_PROXIMITY
)) {
449 printf("Script error: No Trigger Named \"%s\"\n", parameters
->objects
[1]->objectName
);
452 InfoPoint
*trigger
= (InfoPoint
*) ip
;
453 if ( parameters
->int0Parameter
!= 0 ) {
454 trigger
->Flags
&= ~TRAP_DEACTIVATED
;
456 trigger
->Flags
|= TRAP_DEACTIVATED
;
460 void GameScript::FadeToColor(Scriptable
* Sender
, Action
* parameters
)
462 core
->timer
->SetFadeToColor( parameters
->pointParameter
.x
);
463 // Sender->SetWait( parameters->pointParameter.x );
464 Sender
->ReleaseCurrentAction(); // todo, blocking?
467 void GameScript::FadeFromColor(Scriptable
* Sender
, Action
* parameters
)
469 core
->timer
->SetFadeFromColor( parameters
->pointParameter
.x
);
470 // Sender->SetWait( parameters->pointParameter.x );
471 Sender
->ReleaseCurrentAction(); // todo, blocking?
474 void GameScript::FadeToAndFromColor(Scriptable
* Sender
, Action
* parameters
)
476 core
->timer
->SetFadeToColor( parameters
->pointParameter
.x
);
477 core
->timer
->SetFadeFromColor( parameters
->pointParameter
.x
);
478 // Sender->SetWait( parameters->pointParameter.x<<1 ); //multiply by 2
479 Sender
->ReleaseCurrentAction(); // todo, blocking?
482 void GameScript::JumpToPoint(Scriptable
* Sender
, Action
* parameters
)
484 if (Sender
->Type
!= ST_ACTOR
) {
487 Actor
* ab
= ( Actor
* ) Sender
;
488 ab
->SetPosition( parameters
->pointParameter
, true );
491 void GameScript::JumpToPointInstant(Scriptable
* Sender
, Action
* parameters
)
493 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
494 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
497 Actor
* ab
= ( Actor
* ) tar
;
498 ab
->SetPosition( parameters
->pointParameter
, true );
501 /** instant jump to location saved in stats */
502 /** default subject is the current actor */
503 void GameScript::JumpToSavedLocation(Scriptable
* Sender
, Action
* parameters
)
505 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
509 if (tar
->Type
!= ST_ACTOR
) {
512 Actor
*actor
= (Actor
*) tar
;
513 Point
p((short) actor
->GetStat(IE_SAVEDXPOS
), (short) actor
->GetStat(IE_SAVEDYPOS
) );
514 actor
->SetPosition(p
, true );
515 actor
->SetOrientation( actor
->GetStat(IE_SAVEDFACE
), false );
518 void GameScript::JumpToObject(Scriptable
* Sender
, Action
* parameters
)
520 if (Sender
->Type
!= ST_ACTOR
) {
523 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
528 const Map
*map
= tar
->GetCurrentArea();
531 if (parameters
->string0Parameter
[0]) {
532 CreateVisualEffectCore(Sender
, Sender
->Pos
, parameters
->string0Parameter
, 0);
534 MoveBetweenAreasCore( (Actor
*) Sender
, map
->GetScriptName(), tar
->Pos
, -1, true);
538 void GameScript::TeleportParty(Scriptable
* /*Sender*/, Action
* parameters
)
540 Game
*game
= core
->GetGame();
541 int i
= game
->GetPartySize(false);
543 Actor
*tar
= game
->GetPC(i
, false);
544 MoveBetweenAreasCore( tar
, parameters
->string1Parameter
,
545 parameters
->pointParameter
, -1, true);
549 //this is unfinished, maybe the original moves actors too?
551 void GameScript::MoveToExpansion(Scriptable
* Sender
, Action
* /*parameters*/)
553 Game
*game
= core
->GetGame();
555 game
->SetExpansion(1);
556 core
->GetDictionary()->SetAt( "PlayMode", 2 );
557 //TODO: set the new world map
559 int i
= game
->GetPartySize(false);
561 Actor
*actor
= game
->GetPC(i
, false);
562 game
->InitActorPos(actor
);
565 core
->SetEventFlag(EF_MASTERSCRIPT
);
566 Sender
->ReleaseCurrentAction();
569 //add some animation effects too?
570 void GameScript::ExitPocketPlane(Scriptable
* /*Sender*/, Action
* /*parameters*/)
572 Game
*game
= core
->GetGame();
573 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
574 Actor
* act
= game
->GetPC( i
, false );
576 if (game
->GetPlaneLocationCount() <= (unsigned int)i
) {
577 // what are we meant to do here?
578 printf("argh, couldn't restore party member %d!", i
+ 1);
581 GAMLocationEntry
*gle
= game
->GetPlaneLocationEntry(i
);
582 MoveBetweenAreasCore(act
, gle
->AreaResRef
, gle
->Pos
, -1, true);
586 // presumably this is correct
587 game
->ClearPlaneLocations();
590 //moves pcs and npcs from an area to another area
591 void GameScript::MoveGlobalsTo(Scriptable
* /*Sender*/, Action
* parameters
)
593 Game
*game
= core
->GetGame();
594 int i
= game
->GetPartySize(false);
596 Actor
*tar
= game
->GetPC(i
, false);
597 //if the actor isn't in the area, we don't care
598 if (strnicmp(tar
->Area
, parameters
->string0Parameter
,8) ) {
601 MoveBetweenAreasCore( tar
, parameters
->string1Parameter
,
602 parameters
->pointParameter
, -1, true);
604 i
= game
->GetNPCCount();
606 Actor
*tar
= game
->GetNPC(i
);
607 //if the actor isn't in the area, we don't care
608 if (strnicmp(tar
->Area
, parameters
->string0Parameter
,8) ) {
611 MoveBetweenAreasCore( tar
, parameters
->string1Parameter
,
612 parameters
->pointParameter
, -1, true);
616 void GameScript::MoveGlobal(Scriptable
* Sender
, Action
* parameters
)
618 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
619 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
623 MoveBetweenAreasCore( (Actor
*) tar
, parameters
->string0Parameter
,
624 parameters
->pointParameter
, -1, true);
627 //we also allow moving to door, container
628 void GameScript::MoveGlobalObject(Scriptable
* Sender
, Action
* parameters
)
630 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
631 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
634 Scriptable
* to
= GetActorFromObject( Sender
, parameters
->objects
[2] );
638 const Map
*map
= to
->GetCurrentArea();
641 MoveBetweenAreasCore( (Actor
*) tar
, map
->GetScriptName(),
646 void GameScript::MoveGlobalObjectOffScreen(Scriptable
* Sender
, Action
* parameters
)
648 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
649 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
652 Scriptable
* to
= GetActorFromObject( Sender
, parameters
->objects
[2] );
656 MoveBetweenAreasCore( (Actor
*) tar
, parameters
->string0Parameter
,
660 //don't use offset from Sender
661 void GameScript::CreateCreature(Scriptable
* Sender
, Action
* parameters
)
663 CreateCreatureCore( Sender
, parameters
, CC_CHECK_IMPASSABLE
|CC_CHECK_OVERLAP
|CC_SCRIPTNAME
);
666 //another highly redundant action
667 void GameScript::CreateCreatureDoor(Scriptable
* Sender
, Action
* parameters
)
669 //we hack this to death
670 strcpy(parameters
->string1Parameter
, "SPDIMNDR");
671 CreateCreatureCore( Sender
, parameters
, CC_CHECK_IMPASSABLE
|CC_CHECK_OVERLAP
| CC_PLAY_ANIM
);
674 //another highly redundant action
675 void GameScript::CreateCreatureObjectDoor(Scriptable
* Sender
, Action
* parameters
)
677 //we hack this to death
678 strcpy(parameters
->string1Parameter
, "SPDIMNDR");
679 CreateCreatureCore( Sender
, parameters
, CC_OFFSET
| CC_CHECK_IMPASSABLE
|CC_CHECK_OVERLAP
| CC_PLAY_ANIM
);
682 //don't use offset from Sender
683 void GameScript::CreateCreatureImpassable(Scriptable
* Sender
, Action
* parameters
)
685 CreateCreatureCore( Sender
, parameters
, CC_CHECK_OVERLAP
);
688 void GameScript::CreateCreatureImpassableAllowOverlap(Scriptable
* Sender
, Action
* parameters
)
690 CreateCreatureCore( Sender
, parameters
, 0 );
693 //use offset from Sender
694 void GameScript::CreateCreatureAtFeet(Scriptable
* Sender
, Action
* parameters
)
696 CreateCreatureCore( Sender
, parameters
, CC_OFFSET
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
);
699 void GameScript::CreateCreatureOffScreen(Scriptable
* Sender
, Action
* parameters
)
701 CreateCreatureCore( Sender
, parameters
, CC_OFFSCREEN
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
);
704 //creates copy at actor, plays animation
705 void GameScript::CreateCreatureObjectCopy(Scriptable
* Sender
, Action
* parameters
)
707 CreateCreatureCore( Sender
, parameters
, CC_OBJECT
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
| CC_COPY
| CC_PLAY_ANIM
);
710 //creates copy at absolute point
711 void GameScript::CreateCreatureCopyPoint(Scriptable
* Sender
, Action
* parameters
)
713 CreateCreatureCore( Sender
, parameters
, CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
| CC_COPY
| CC_PLAY_ANIM
);
716 //this is the same, object + offset
717 //using this for simple createcreatureobject, (0 offsets)
718 //createcreatureobjecteffect may have animation
719 void GameScript::CreateCreatureObjectOffset(Scriptable
* Sender
, Action
* parameters
)
721 CreateCreatureCore( Sender
, parameters
, CC_OBJECT
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
| CC_PLAY_ANIM
);
724 void GameScript::CreateCreatureObjectOffScreen(Scriptable
* Sender
, Action
* parameters
)
726 CreateCreatureCore( Sender
, parameters
, CC_OFFSCREEN
| CC_OBJECT
| CC_CHECK_IMPASSABLE
| CC_CHECK_OVERLAP
);
729 //I think this simply removes the cursor and hides the gui without disabling scripts
730 //See Interface::SetCutSceneMode
731 void GameScript::SetCursorState(Scriptable
* /*Sender*/, Action
* parameters
)
733 int active
= parameters
->int0Parameter
;
735 Game
*game
= core
->GetGame();
737 game
->ControlStatus
|= CS_HIDEGUI
;
739 game
->ControlStatus
&= ~CS_HIDEGUI
;
741 core
->SetEventFlag(EF_CONTROL
);
742 core
->GetVideoDriver()->SetMouseEnabled(!active
);
745 void GameScript::StartCutSceneMode(Scriptable
* /*Sender*/, Action
* /*parameters*/)
747 core
->SetCutSceneMode( true );
750 void GameScript::EndCutSceneMode(Scriptable
* /*Sender*/, Action
* /*parameters*/)
752 core
->SetCutSceneMode( false );
755 void GameScript::StartCutScene(Scriptable
* Sender
, Action
* parameters
)
757 GameScript
* gs
= new GameScript( parameters
->string0Parameter
, Sender
);
758 gs
->EvaluateAllBlocks();
760 Sender
->ClearCutsceneID();
763 void GameScript::CutSceneID(Scriptable
* Sender
, Action
* parameters
)
765 Sender
->SetCutsceneID( GetActorFromObject( Sender
, parameters
->objects
[1] ) );
766 if (InDebug
&ID_CUTSCENE
) {
767 if (!Sender
->GetCutsceneID()) {
768 printMessage("GameScript","Failed to set CutSceneID!\n",YELLOW
);
769 parameters
->objects
[1]->Dump();
774 void GameScript::Enemy(Scriptable
* Sender
, Action
* /*parameters*/)
776 if (Sender
->Type
!= ST_ACTOR
) {
779 Actor
* actor
= ( Actor
* ) Sender
;
780 actor
->SetBase( IE_EA
, EA_ENEMY
);
783 void GameScript::Ally(Scriptable
* Sender
, Action
* /*parameters*/)
785 if (Sender
->Type
!= ST_ACTOR
) {
788 Actor
* actor
= ( Actor
* ) Sender
;
789 actor
->SetBase( IE_EA
, EA_ALLY
);
792 /** GemRB extension: you can replace baldur.bcs */
793 void GameScript::ChangeAIScript(Scriptable
* Sender
, Action
* parameters
)
795 if (parameters
->int0Parameter
>7) {
798 if (Sender
->Type
!=ST_ACTOR
&& parameters
->int0Parameter
) {
801 Sender
->SetScript( parameters
->string0Parameter
, parameters
->int0Parameter
, false );
804 void GameScript::ForceAIScript(Scriptable
* Sender
, Action
* parameters
)
806 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
807 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
810 Actor
* actor
= ( Actor
* ) tar
;
811 //changeaiscript clears the queue, i believe
812 // actor->ClearActions();
813 actor
->SetScript( parameters
->string0Parameter
, parameters
->int0Parameter
, false );
816 void GameScript::SetPlayerSound(Scriptable
* Sender
, Action
* parameters
)
818 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
819 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
822 Actor
* actor
= ( Actor
* ) tar
;
823 actor
->StrRefs
[parameters
->int0Parameter
]=parameters
->int1Parameter
;
826 //this one works only on real actors, they got constants
827 void GameScript::VerbalConstantHead(Scriptable
* Sender
, Action
* parameters
)
829 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
830 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
833 DisplayStringCore( tar
, parameters
->int0Parameter
, DS_HEAD
|DS_CONSOLE
|DS_CONST
);
836 void GameScript::VerbalConstant(Scriptable
* Sender
, Action
* parameters
)
838 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
839 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
842 DisplayStringCore( tar
, parameters
->int0Parameter
, DS_CONSOLE
|DS_CONST
);
846 void GameScript::SaveLocation(Scriptable
* Sender
, Action
* parameters
)
848 ieDword value
= parameters
->pointParameter
.asDword();
849 if (!parameters
->string0Parameter
[0]) {
850 strcpy(parameters
->string0Parameter
,"LOCALSsavedlocation");
852 printf("SaveLocation: %s\n",parameters
->string0Parameter
);
853 SetVariable(Sender
, parameters
->string0Parameter
, value
);
856 //PST:has parameters, IWD2: no params
857 void GameScript::SetSavedLocation(Scriptable
* Sender
, Action
* parameters
)
859 if (Sender
->Type
!=ST_ACTOR
) {
862 Actor
*actor
= (Actor
*) Sender
;
864 if (parameters
->pointParameter
.isnull()) {
865 actor
->SetBase(IE_SAVEDXPOS
, actor
->Pos
.x
);
866 actor
->SetBase(IE_SAVEDYPOS
, actor
->Pos
.y
);
867 actor
->SetBase(IE_SAVEDFACE
, actor
->GetOrientation());
871 actor
->SetBase(IE_SAVEDXPOS
, parameters
->pointParameter
.x
);
872 actor
->SetBase(IE_SAVEDYPOS
, parameters
->pointParameter
.y
);
873 actor
->SetBase(IE_SAVEDFACE
, parameters
->int0Parameter
);
875 //IWD2, sets the homepoint int0,int1,int2
876 void GameScript::SetSavedLocationPoint(Scriptable
* Sender
, Action
* parameters
)
878 if (Sender
->Type
!=ST_ACTOR
) {
881 Actor
*actor
= (Actor
*) Sender
;
882 actor
->SetBase(IE_SAVEDXPOS
, parameters
->int0Parameter
);
883 actor
->SetBase(IE_SAVEDYPOS
, parameters
->int1Parameter
);
884 actor
->SetBase(IE_SAVEDFACE
, parameters
->int2Parameter
);
886 //IWD2, sets the homepoint P
887 void GameScript::SetStartPos(Scriptable
* Sender
, Action
* parameters
)
889 if (Sender
->Type
!=ST_ACTOR
) {
892 Actor
*actor
= (Actor
*) Sender
;
893 actor
->SetBase(IE_SAVEDXPOS
, parameters
->pointParameter
.x
);
894 actor
->SetBase(IE_SAVEDYPOS
, parameters
->pointParameter
.y
);
895 actor
->SetBase(IE_SAVEDFACE
, parameters
->int0Parameter
);
898 void GameScript::SaveObjectLocation(Scriptable
* Sender
, Action
* parameters
)
900 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
904 ieDword value
= tar
->Pos
.asDword();
905 if (!parameters
->string0Parameter
[0]) {
906 strcpy(parameters
->string0Parameter
,"LOCALSsavedlocation");
908 printf("SaveLocation: %s\n",parameters
->string0Parameter
);
909 SetVariable(Sender
, parameters
->string0Parameter
, value
);
912 /** you may omit the string0Parameter, in this case this will be a */
913 /** CreateCreatureAtSavedLocation */
914 void GameScript::CreateCreatureAtLocation(Scriptable
* Sender
, Action
* parameters
)
916 if (!parameters
->string0Parameter
[0]) {
917 strcpy(parameters
->string0Parameter
,"LOCALSsavedlocation");
919 ieDword value
= CheckVariable(Sender
, parameters
->string0Parameter
);
920 parameters
->pointParameter
.y
= (ieWord
) (value
& 0xffff);
921 parameters
->pointParameter
.x
= (ieWord
) (value
>> 16);
922 CreateCreatureCore(Sender
, parameters
, CC_CHECK_IMPASSABLE
|CC_STRING1
);
925 void GameScript::WaitRandom(Scriptable
* Sender
, Action
* parameters
)
927 if (!Sender
->CurrentActionState
) {
928 int width
= parameters
->int1Parameter
-parameters
->int0Parameter
;
930 width
= parameters
->int0Parameter
;
932 width
= rand() % width
+ parameters
->int0Parameter
;
934 Sender
->CurrentActionState
= width
* AI_UPDATE_TIME
;
936 Sender
->CurrentActionState
--;
939 if (!Sender
->CurrentActionState
) {
940 Sender
->ReleaseCurrentAction();
943 assert(Sender
->CurrentActionState
>= 0);
946 void GameScript::Wait(Scriptable
* Sender
, Action
* parameters
)
948 if (!Sender
->CurrentActionState
) {
949 Sender
->CurrentActionState
= parameters
->int0Parameter
* AI_UPDATE_TIME
;
951 Sender
->CurrentActionState
--;
954 if (!Sender
->CurrentActionState
) {
955 Sender
->ReleaseCurrentAction();
958 assert(Sender
->CurrentActionState
>= 0);
961 void GameScript::SmallWait(Scriptable
* Sender
, Action
* parameters
)
963 if (!Sender
->CurrentActionState
) {
964 Sender
->CurrentActionState
= parameters
->int0Parameter
;
966 Sender
->CurrentActionState
--;
969 if (!Sender
->CurrentActionState
) {
970 Sender
->ReleaseCurrentAction();
973 assert(Sender
->CurrentActionState
>= 0);
976 void GameScript::SmallWaitRandom(Scriptable
* Sender
, Action
* parameters
)
978 if (!Sender
->CurrentActionState
) {
979 int random
= parameters
->int1Parameter
- parameters
->int0Parameter
;
983 Sender
->CurrentActionState
= rand() % random
+ parameters
->int0Parameter
;
985 Sender
->CurrentActionState
--;
988 if (!Sender
->CurrentActionState
) {
989 Sender
->ReleaseCurrentAction();
992 assert(Sender
->CurrentActionState
>= 0);
995 void GameScript::MoveViewPoint(Scriptable
* Sender
, Action
* parameters
)
997 core
->timer
->SetMoveViewPort( parameters
->pointParameter
.x
, parameters
->pointParameter
.y
, parameters
->int0Parameter
<<1, true );
998 Sender
->SetWait(1); // todo, blocking?
999 Sender
->ReleaseCurrentAction(); // todo, blocking?
1002 void GameScript::MoveViewObject(Scriptable
* Sender
, Action
* parameters
)
1004 Scriptable
* scr
= GetActorFromObject( Sender
, parameters
->objects
[1]);
1008 core
->timer
->SetMoveViewPort( scr
->Pos
.x
, scr
->Pos
.y
, parameters
->int0Parameter
<<1, true );
1009 Sender
->SetWait(1); // todo, blocking?
1010 Sender
->ReleaseCurrentAction(); // todo, blocking?
1013 void GameScript::AddWayPoint(Scriptable
* Sender
, Action
* parameters
)
1015 if (Sender
->Type
!= ST_ACTOR
) {
1018 Actor
* actor
= ( Actor
* ) Sender
;
1019 actor
->AddWayPoint( parameters
->pointParameter
);
1020 // this is marked as AF_BLOCKING (and indeed AddWayPoint causes moves),
1021 // but this probably needs more thought
1022 Sender
->ReleaseCurrentAction();
1025 void GameScript::MoveToPointNoRecticle(Scriptable
* Sender
, Action
* parameters
)
1027 if (Sender
->Type
!= ST_ACTOR
) {
1028 Sender
->ReleaseCurrentAction();
1031 Actor
*actor
= ( Actor
* ) Sender
;
1032 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1033 actor
->WalkTo( parameters
->pointParameter
, IF_NORECTICLE
, 0 );
1035 if (!actor
->InMove()) {
1036 // we should probably instead keep retrying until we reach dest
1037 Sender
->ReleaseCurrentAction();
1041 void GameScript::MoveToPointNoInterrupt(Scriptable
* Sender
, Action
* parameters
)
1043 if (Sender
->Type
!= ST_ACTOR
) {
1044 Sender
->ReleaseCurrentAction();
1047 Actor
* actor
= ( Actor
* ) Sender
;
1048 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1049 actor
->WalkTo( parameters
->pointParameter
, IF_NOINT
, 0 );
1051 // should we always force IF_NOINT here?
1052 if (!actor
->InMove()) {
1053 // we should probably instead keep retrying until we reach dest
1055 Sender
->ReleaseCurrentAction();
1059 void GameScript::RunToPointNoRecticle(Scriptable
* Sender
, Action
* parameters
)
1061 if (Sender
->Type
!= ST_ACTOR
) {
1062 Sender
->ReleaseCurrentAction();
1065 Actor
* actor
= ( Actor
* ) Sender
;
1066 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1067 actor
->WalkTo( parameters
->pointParameter
, IF_NORECTICLE
|IF_RUNNING
, 0 );
1069 if (!actor
->InMove()) {
1070 // we should probably instead keep retrying until we reach dest
1071 Sender
->ReleaseCurrentAction();
1075 void GameScript::RunToPoint(Scriptable
* Sender
, Action
* parameters
)
1077 if (Sender
->Type
!= ST_ACTOR
) {
1078 Sender
->ReleaseCurrentAction();
1081 Actor
* actor
= ( Actor
* ) Sender
;
1082 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1083 actor
->WalkTo( parameters
->pointParameter
, IF_RUNNING
, 0 );
1085 if (!actor
->InMove()) {
1086 // we should probably instead keep retrying until we reach dest
1087 Sender
->ReleaseCurrentAction();
1091 //movetopoint until timer is down or target reached
1092 void GameScript::TimedMoveToPoint(Scriptable
* Sender
, Action
* parameters
)
1094 if (Sender
->Type
!= ST_ACTOR
) {
1095 Sender
->ReleaseCurrentAction();
1098 if (parameters
->int0Parameter
<=0) {
1099 Sender
->ReleaseCurrentAction();
1102 Actor
*actor
= (Actor
*) Sender
;
1104 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1105 actor
->WalkTo( parameters
->pointParameter
, parameters
->int1Parameter
,0 );
1108 //hopefully this hack will prevent lockups
1109 if (!actor
->InMove()) {
1110 // we should probably instead keep retrying until we reach dest
1111 Sender
->ReleaseCurrentAction();
1115 //repeat movement...
1116 if (parameters
->int0Parameter
>0) {
1117 Action
*newaction
= ParamCopyNoOverride(parameters
);
1118 newaction
->int0Parameter
--;
1119 actor
->AddActionInFront(newaction
);
1123 Sender
->ReleaseCurrentAction();
1126 void GameScript::MoveToPoint(Scriptable
* Sender
, Action
* parameters
)
1128 if (Sender
->Type
!= ST_ACTOR
) {
1129 Sender
->ReleaseCurrentAction();
1132 Actor
* actor
= ( Actor
* ) Sender
;
1133 //WalkTo could release the current action, so we need this
1134 ieDword tmp
= (ieDword
) parameters
->int0Parameter
;
1135 //InMove can clear destination, so we need to save it
1136 Point dest
= actor
->Destination
;
1138 // try the actual move, if we are not already moving there
1139 if (!actor
->InMove() || actor
->Destination
!= parameters
->pointParameter
) {
1140 actor
->WalkTo( parameters
->pointParameter
, 0, tmp
);
1141 dest
= actor
->Destination
;
1144 // give up if we can't move there (no path was found)
1145 if (!actor
->InMove()) {
1146 // we should probably instead keep retrying until we reach dest
1147 Sender
->ReleaseCurrentAction();
1151 if (!actor
->InMove()) {
1152 //can't reach target, movement failed
1153 //we have to use tmp-1 because the distance required might be 0,
1154 //so in GoNearAndRetry we add 1 to distance
1155 if (Distance(dest
,actor
)>tmp
-1) {
1156 //to prevent deadlocks, we free the action
1157 //which caused MoveToPoint in the first place
1158 Sender
->PopNextAction();
1164 //bg2, jumps to saved location in variable
1165 void GameScript::MoveToSavedLocation(Scriptable
* Sender
, Action
* parameters
)
1167 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1171 if (tar
->Type
!= ST_ACTOR
) {
1172 Sender
->ReleaseCurrentAction();
1177 Actor
* actor
= ( Actor
* ) tar
;
1178 ieDword value
= (ieDword
) CheckVariable( Sender
, parameters
->string0Parameter
);
1180 actor
->SetPosition(p
, true );
1181 Sender
->ReleaseCurrentAction();
1183 /** iwd2 returntosavedlocation (with stats) */
1184 /** pst returntosavedplace */
1185 /** use Sender as default subject */
1186 void GameScript::ReturnToSavedLocation(Scriptable
* Sender
, Action
* parameters
)
1188 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
1192 if (tar
->Type
!= ST_ACTOR
) {
1193 Sender
->ReleaseCurrentAction();
1197 Actor
* actor
= ( Actor
* ) tar
;
1198 Point
p((short) actor
->GetBase(IE_SAVEDXPOS
),(short) actor
->GetBase(IE_SAVEDYPOS
) );
1200 Sender
->ReleaseCurrentAction();
1203 if (!actor
->InMove() || actor
->Destination
!= p
) {
1204 actor
->WalkTo( p
, 0, 0 );
1206 if (!actor
->InMove()) {
1207 // we should probably instead keep retrying until we reach dest
1208 Sender
->ReleaseCurrentAction();
1213 void GameScript::RunToSavedLocation(Scriptable
* Sender
, Action
* parameters
)
1215 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
1219 if (tar
->Type
!= ST_ACTOR
) {
1220 Sender
->ReleaseCurrentAction();
1224 Actor
* actor
= ( Actor
* ) tar
;
1225 Point
p((short) actor
->GetBase(IE_SAVEDXPOS
),(short) actor
->GetBase(IE_SAVEDYPOS
) );
1227 Sender
->ReleaseCurrentAction();
1230 if (!actor
->InMove() || actor
->Destination
!= p
) {
1231 actor
->WalkTo( p
, IF_RUNNING
, 0 );
1233 if (!actor
->InMove()) {
1234 // we should probably instead keep retrying until we reach dest
1235 Sender
->ReleaseCurrentAction();
1240 void GameScript::ReturnToSavedLocationDelete(Scriptable
* Sender
, Action
* parameters
)
1242 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
1246 if (tar
->Type
!= ST_ACTOR
) {
1247 Sender
->ReleaseCurrentAction();
1251 Actor
* actor
= ( Actor
* ) tar
;
1252 Point
p((short) actor
->GetBase(IE_SAVEDXPOS
),(short) actor
->GetBase(IE_SAVEDYPOS
) );
1253 actor
->SetBase(IE_SAVEDXPOS
,0);
1254 actor
->SetBase(IE_SAVEDYPOS
,0);
1256 Sender
->ReleaseCurrentAction();
1259 if (!actor
->InMove() || actor
->Destination
!= p
) {
1260 actor
->WalkTo( p
, 0, 0 );
1263 if (!actor
->InMove()) {
1264 // we should probably instead keep retrying until we reach dest
1265 Sender
->ReleaseCurrentAction();
1269 void GameScript::MoveToObjectNoInterrupt(Scriptable
* Sender
, Action
* parameters
)
1271 MoveToObjectCore(Sender
, parameters
, IF_NOINT
, false);
1274 void GameScript::RunToObject(Scriptable
* Sender
, Action
* parameters
)
1276 MoveToObjectCore(Sender
, parameters
, IF_RUNNING
, false);
1279 void GameScript::MoveToObject(Scriptable
* Sender
, Action
* parameters
)
1281 MoveToObjectCore(Sender
, parameters
, 0, false);
1284 void GameScript::MoveToObjectUntilSee(Scriptable
* Sender
, Action
* parameters
)
1286 MoveToObjectCore(Sender
, parameters
, 0, true);
1289 void GameScript::MoveToObjectFollow(Scriptable
* Sender
, Action
* parameters
)
1291 if (Sender
->Type
!= ST_ACTOR
) {
1292 Sender
->ReleaseCurrentAction();
1295 Scriptable
* target
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
1297 Sender
->ReleaseCurrentAction();
1300 Actor
* actor
= ( Actor
* ) Sender
;
1301 //follow leader from a distance of 5
1302 //could also follow the leader with a point offset
1303 if (target
->Type
==ST_ACTOR
) {
1304 actor
->SetLeader( (Actor
*) target
, 5);
1306 MoveNearerTo(Sender
, target
, MAX_OPERATING_DISTANCE
);
1309 void GameScript::StorePartyLocation(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1311 Game
*game
= core
->GetGame();
1312 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
1313 Actor
* act
= game
->GetPC( i
, false );
1314 GAMLocationEntry
*gle
= game
->GetSavedLocationEntry(i
);
1316 gle
->Pos
= act
->Pos
;
1317 memcpy(gle
->AreaResRef
, act
->Area
, 9);
1322 void GameScript::RestorePartyLocation(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1324 Game
*game
= core
->GetGame();
1325 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
1326 Actor
* act
= game
->GetPC( i
, false );
1328 if (game
->GetSavedLocationCount() <= (unsigned int)i
) {
1329 // what are we meant to do here?
1330 printf("argh, couldn't restore party member %d!", i
+ 1);
1333 GAMLocationEntry
*gle
= game
->GetSavedLocationEntry(i
);
1334 MoveBetweenAreasCore(act
, gle
->AreaResRef
, gle
->Pos
, -1, true);
1338 // presumably this is correct
1339 game
->ClearSavedLocations();
1342 void GameScript::MoveToCenterOfScreen(Scriptable
* Sender
, Action
* /*parameters*/)
1344 if (Sender
->Type
!= ST_ACTOR
) {
1345 Sender
->ReleaseCurrentAction();
1348 Region vp
= core
->GetVideoDriver()->GetViewport();
1349 Actor
* actor
= ( Actor
* ) Sender
;
1350 Point
p((short) (vp
.x
+vp
.w
/2), (short) (vp
.y
+vp
.h
/2) );
1351 if (!actor
->InMove() || actor
->Destination
!= p
) {
1352 actor
->WalkTo( p
, IF_NOINT
, 0 );
1354 if (!actor
->InMove()) {
1355 // we should probably instead keep retrying until we reach dest
1356 Sender
->ReleaseCurrentAction();
1360 void GameScript::MoveToOffset(Scriptable
* Sender
, Action
* parameters
)
1362 if (Sender
->Type
!= ST_ACTOR
) {
1363 Sender
->ReleaseCurrentAction();
1366 Actor
* actor
= ( Actor
* ) Sender
;
1367 Point
p(Sender
->Pos
.x
+parameters
->pointParameter
.x
, Sender
->Pos
.y
+parameters
->pointParameter
.y
);
1368 if (!actor
->InMove() || actor
->Destination
!= p
) {
1369 actor
->WalkTo( p
, 0, 0 );
1371 if (!actor
->InMove()) {
1372 // we should probably instead keep retrying until we reach dest
1373 Sender
->ReleaseCurrentAction();
1377 void GameScript::RunAwayFrom(Scriptable
* Sender
, Action
* parameters
)
1379 if (Sender
->Type
!= ST_ACTOR
) {
1380 Sender
->ReleaseCurrentAction();
1383 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
1384 Sender
->ReleaseCurrentAction();
1387 Actor
* actor
= ( Actor
* ) Sender
;
1388 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
1390 Sender
->ReleaseCurrentAction();
1393 //TODO: actor could use travel areas
1394 // we should be using int0Parameter for the timing here, not distance
1395 if (!actor
->InMove()) {
1396 // we should make sure our existing walk is a 'run away', or fix moving/path code
1397 actor
->RunAwayFrom( tar
->Pos
, parameters
->int0Parameter
, false);
1400 //repeat movement...
1401 if (parameters
->int0Parameter
>0) {
1402 Action
*newaction
= ParamCopyNoOverride(parameters
);
1403 newaction
->int0Parameter
--;
1404 actor
->AddActionInFront(newaction
);
1408 Sender
->ReleaseCurrentAction();
1411 void GameScript::RunAwayFromNoLeaveArea(Scriptable
* Sender
, Action
* parameters
)
1413 if (Sender
->Type
!= ST_ACTOR
) {
1414 Sender
->ReleaseCurrentAction();
1417 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
1418 Sender
->ReleaseCurrentAction();
1421 Actor
* actor
= ( Actor
* ) Sender
;
1422 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
1424 Sender
->ReleaseCurrentAction();
1427 // we should be using int0Parameter for the timing here, not distance
1428 if (!actor
->InMove()) {
1429 // we should make sure our existing walk is a 'run away', or fix moving/path code
1430 actor
->RunAwayFrom( tar
->Pos
, parameters
->int0Parameter
, false);
1433 //repeat movement...
1434 if (parameters
->int0Parameter
>0) {
1435 Action
*newaction
= ParamCopyNoOverride(parameters
);
1436 newaction
->int0Parameter
--;
1437 actor
->AddActionInFront(newaction
);
1441 Sender
->ReleaseCurrentAction();
1444 void GameScript::RunAwayFromNoInterrupt(Scriptable
* Sender
, Action
* parameters
)
1446 if (Sender
->Type
!= ST_ACTOR
) {
1447 Sender
->ReleaseCurrentAction();
1450 //i believe being dead still interrupts this action
1451 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
1452 Sender
->ReleaseCurrentAction();
1455 Actor
* actor
= ( Actor
* ) Sender
;
1456 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
1458 Sender
->ReleaseCurrentAction();
1461 //actor->InternalFlags|=IF_NOINT;
1462 actor
->NoInterrupt();
1463 // we should be using int0Parameter for the timing here, not distance
1464 if (!actor
->InMove()) {
1465 // we should make sure our existing walk is a 'run away', or fix moving/path code
1466 actor
->RunAwayFrom( tar
->Pos
, parameters
->int0Parameter
, false);
1469 //repeat movement...
1470 if (parameters
->int0Parameter
>0) {
1471 Action
*newaction
= ParamCopyNoOverride(parameters
);
1472 newaction
->int0Parameter
--;
1473 actor
->AddActionInFront(newaction
);
1479 Sender
->ReleaseCurrentAction();
1482 void GameScript::RunAwayFromPoint(Scriptable
* Sender
, Action
* parameters
)
1484 if (Sender
->Type
!= ST_ACTOR
) {
1485 Sender
->ReleaseCurrentAction();
1488 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
1489 Sender
->ReleaseCurrentAction();
1492 Actor
* actor
= ( Actor
* ) Sender
;
1493 // we should be using int0Parameter for the timing here, not distance?
1494 if (!actor
->InMove()) {
1495 // we should make sure our existing walk is a 'run away', or fix moving/path code
1496 actor
->RunAwayFrom( parameters
->pointParameter
, parameters
->int0Parameter
, false);
1499 //repeat movement...
1500 if (parameters
->int0Parameter
>0) {
1501 Action
*newaction
= ParamCopyNoOverride(parameters
);
1502 newaction
->int0Parameter
--;
1503 actor
->AddActionInFront(newaction
);
1507 Sender
->ReleaseCurrentAction();
1510 void GameScript::DisplayStringNoName(Scriptable
* Sender
, Action
* parameters
)
1512 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1]);
1516 if (Sender
->Type
==ST_ACTOR
) {
1517 DisplayStringCore( target
, parameters
->int0Parameter
, DS_CONSOLE
|DS_NONAME
);
1519 DisplayStringCore( target
, parameters
->int0Parameter
, DS_AREA
|DS_NONAME
);
1523 void GameScript::DisplayStringNoNameHead(Scriptable
* Sender
, Action
* parameters
)
1525 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1530 DisplayStringCore( target
, parameters
->int0Parameter
, DS_HEAD
|DS_CONSOLE
|DS_NONAME
);
1533 //display message over current script owner
1534 void GameScript::DisplayMessage(Scriptable
* Sender
, Action
* parameters
)
1536 DisplayStringCore(Sender
, parameters
->int0Parameter
, DS_CONSOLE
);
1539 //float message over target
1540 void GameScript::DisplayStringHead(Scriptable
* Sender
, Action
* parameters
)
1542 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1545 printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
1548 DisplayStringCore(target
, parameters
->int0Parameter
, DS_CONSOLE
|DS_HEAD
|DS_SPEECH
);
1551 void GameScript::KillFloatMessage(Scriptable
* Sender
, Action
* parameters
)
1553 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1557 target
->DisplayHeadText(NULL
);
1560 void GameScript::DisplayStringHeadOwner(Scriptable
* /*Sender*/, Action
* parameters
)
1562 Game
*game
=core
->GetGame();
1564 int i
= game
->GetPartySize(true);
1566 Actor
*actor
= game
->GetPC(i
, true);
1567 if (actor
->inventory
.HasItem(parameters
->string0Parameter
,parameters
->int0Parameter
) ) {
1568 DisplayStringCore(actor
, parameters
->int0Parameter
, DS_CONSOLE
|DS_HEAD
);
1573 void GameScript::FloatMessageFixed(Scriptable
* Sender
, Action
* parameters
)
1575 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1578 printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
1581 DisplayStringCore(target
, parameters
->int0Parameter
, DS_CONSOLE
|DS_HEAD
);
1584 void GameScript::FloatMessageFixedRnd(Scriptable
* Sender
, Action
* parameters
)
1586 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1589 printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
1592 SrcVector
*rndstr
=LoadSrc(parameters
->string0Parameter
);
1594 printMessage("GameScript","Cannot display resource!",LIGHT_RED
);
1597 DisplayStringCore(target
, rndstr
->at(rand()%rndstr
->size()), DS_CONSOLE
|DS_HEAD
);
1598 FreeSrc(rndstr
, parameters
->string0Parameter
);
1601 void GameScript::FloatMessageRnd(Scriptable
* Sender
, Action
* parameters
)
1603 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1606 printf("DisplayStringHead/FloatMessage got no target, assuming Sender!\n");
1609 SrcVector
*rndstr
=LoadSrc(parameters
->string0Parameter
);
1611 printMessage("GameScript","Cannot display resource!",LIGHT_RED
);
1614 DisplayStringCore(target
, rndstr
->at(rand()%rndstr
->size()), DS_CONSOLE
|DS_HEAD
);
1615 FreeSrc(rndstr
, parameters
->string0Parameter
);
1618 //apparently this should not display over head (for actors)
1619 void GameScript::DisplayString(Scriptable
* Sender
, Action
* parameters
)
1621 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1]);
1625 if (Sender
->Type
==ST_ACTOR
) {
1626 DisplayStringCore( target
, parameters
->int0Parameter
, DS_CONSOLE
);
1628 DisplayStringCore( target
, parameters
->int0Parameter
, DS_AREA
);
1632 //DisplayStringHead, but wait for previous talk to succeed
1633 void GameScript::DisplayStringWait(Scriptable
* Sender
, Action
* parameters
)
1635 if (core
->GetAudioDrv()->IsSpeaking()) {
1636 //Sender->AddActionInFront( Sender->CurrentAction );
1639 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1]);
1643 DisplayStringCore( target
, parameters
->int0Parameter
, DS_CONSOLE
|DS_WAIT
|DS_SPEECH
|DS_HEAD
);
1644 Sender
->ReleaseCurrentAction();
1647 void GameScript::ForceFacing(Scriptable
* Sender
, Action
* parameters
)
1649 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1650 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
1651 Sender
->ReleaseCurrentAction();
1654 Actor
*actor
= (Actor
*) tar
;
1655 actor
->SetOrientation(parameters
->int0Parameter
, false);
1658 /* A -1 means random facing? */
1659 void GameScript::Face(Scriptable
* Sender
, Action
* parameters
)
1661 if (Sender
->Type
!= ST_ACTOR
) {
1662 Sender
->ReleaseCurrentAction();
1665 Actor
* actor
= ( Actor
* ) Sender
;
1666 if (parameters
->int0Parameter
==-1) {
1667 actor
->SetOrientation(core
->Roll(1,MAX_ORIENT
,-1), false);
1669 actor
->SetOrientation(parameters
->int0Parameter
, false);
1671 actor
->SetWait( 1 );
1672 Sender
->ReleaseCurrentAction(); // todo, blocking?
1675 void GameScript::FaceObject(Scriptable
* Sender
, Action
* parameters
)
1677 if (Sender
->Type
!= ST_ACTOR
) {
1678 Sender
->ReleaseCurrentAction();
1681 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1683 Sender
->ReleaseCurrentAction();
1686 Actor
* actor
= ( Actor
* ) Sender
;
1687 actor
->SetOrientation( GetOrient( target
->Pos
, actor
->Pos
), false);
1688 actor
->SetWait( 1 );
1689 Sender
->ReleaseCurrentAction(); // todo, blocking?
1692 void GameScript::FaceSavedLocation(Scriptable
* Sender
, Action
* parameters
)
1694 Scriptable
* target
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1695 if (!target
|| target
->Type
!=ST_ACTOR
) {
1696 Sender
->ReleaseCurrentAction();
1699 Actor
* actor
= ( Actor
* ) target
;
1701 if (!parameters
->string0Parameter
[0]) {
1702 strcpy(parameters
->string0Parameter
,"LOCALSsavedlocation");
1704 value
= (ieDword
) CheckVariable( target
, parameters
->string0Parameter
);
1708 actor
->SetOrientation ( GetOrient( p
, actor
->Pos
), false);
1709 actor
->SetWait( 1 );
1710 Sender
->ReleaseCurrentAction(); // todo, blocking?
1713 /*pst and bg2 can play a song designated by index*/
1714 /*actually pst has some extra params not currently implemented*/
1715 /*switchplaylist could implement fade */
1716 void GameScript::StartSong(Scriptable
* /*Sender*/, Action
* parameters
)
1718 const char* string
= core
->GetMusicPlaylist( parameters
->int0Parameter
);
1719 if (!string
|| string
[0] == '*') {
1720 core
->GetMusicMgr()->HardEnd();
1722 core
->GetMusicMgr()->SwitchPlayList( string
, true );
1726 void GameScript::StartMusic(Scriptable
* Sender
, Action
* parameters
)
1728 Map
*map
= Sender
->GetCurrentArea();
1729 map
->PlayAreaSong(parameters
->int0Parameter
);
1732 /*iwd2 can set an areasong slot*/
1733 void GameScript::SetMusic(Scriptable
* Sender
, Action
* parameters
)
1735 //iwd2 seems to have 10 slots, dunno if it is important
1736 if (parameters
->int0Parameter
>4) return;
1737 Map
*map
= Sender
->GetCurrentArea();
1738 map
->SongHeader
.SongList
[parameters
->int0Parameter
]=parameters
->int1Parameter
;
1741 //optional integer parameter (isSpeech)
1742 void GameScript::PlaySound(Scriptable
* Sender
, Action
* parameters
)
1744 printf( "PlaySound(%s)\n", parameters
->string0Parameter
);
1745 core
->GetAudioDrv()->Play( parameters
->string0Parameter
, Sender
->Pos
.x
,
1746 Sender
->Pos
.y
, parameters
->int0Parameter
);
1749 void GameScript::PlaySoundPoint(Scriptable
* /*Sender*/, Action
* parameters
)
1751 printf( "PlaySound(%s)\n", parameters
->string0Parameter
);
1752 core
->GetAudioDrv()->Play( parameters
->string0Parameter
, parameters
->pointParameter
.x
, parameters
->pointParameter
.y
);
1755 void GameScript::PlaySoundNotRanged(Scriptable
* /*Sender*/, Action
* parameters
)
1757 printf( "PlaySound(%s)\n", parameters
->string0Parameter
);
1758 core
->GetAudioDrv()->Play( parameters
->string0Parameter
, 0, 0, 0);
1761 void GameScript::Continue(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1765 // creates area vvc at position of object
1766 void GameScript::CreateVisualEffectObject(Scriptable
* Sender
, Action
* parameters
)
1768 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1772 CreateVisualEffectCore(tar
, tar
->Pos
, parameters
->string0Parameter
, parameters
->int0Parameter
);
1775 // creates sticky vvc on actor or normal animation on object
1776 void GameScript::CreateVisualEffectObjectSticky(Scriptable
* Sender
, Action
* parameters
)
1778 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1782 if (tar
->Type
==ST_ACTOR
) {
1783 CreateVisualEffectCore((Actor
*) tar
, parameters
->string0Parameter
, parameters
->int0Parameter
);
1785 CreateVisualEffectCore(tar
, tar
->Pos
, parameters
->string0Parameter
, parameters
->int0Parameter
);
1789 // creates area effect at point
1790 void GameScript::CreateVisualEffect(Scriptable
* Sender
, Action
* parameters
)
1792 CreateVisualEffectCore(Sender
, parameters
->pointParameter
, parameters
->string0Parameter
, parameters
->int0Parameter
);
1795 void GameScript::DestroySelf(Scriptable
* Sender
, Action
* /*parameters*/)
1797 if (Sender
->Type
!= ST_ACTOR
) {
1800 Sender
->ClearActions();
1801 Actor
* actor
= ( Actor
* ) Sender
;
1802 actor
->DestroySelf();
1803 //actor->InternalFlags |= IF_CLEANUP;
1806 void GameScript::ScreenShake(Scriptable
* Sender
, Action
* parameters
)
1808 if (parameters
->int1Parameter
) { //IWD2 has a different profile
1809 core
->timer
->SetScreenShake( parameters
->int1Parameter
,
1810 parameters
->int2Parameter
, parameters
->int0Parameter
);
1812 core
->timer
->SetScreenShake( parameters
->pointParameter
.x
,
1813 parameters
->pointParameter
.y
, parameters
->int0Parameter
);
1815 Sender
->SetWait( parameters
->int0Parameter
);
1816 Sender
->ReleaseCurrentAction(); // todo, blocking?
1819 void GameScript::UnhideGUI(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1821 Game
* game
= core
->GetGame();
1822 game
->SetControlStatus(CS_HIDEGUI
, BM_NAND
);
1825 void GameScript::HideGUI(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1827 Game
* game
= core
->GetGame();
1828 game
->SetControlStatus(CS_HIDEGUI
, BM_OR
);
1831 void GameScript::LockScroll(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1833 GameControl
* gc
= core
->GetGameControl();
1835 gc
->SetScreenFlags(SF_LOCKSCROLL
, BM_OR
);
1839 void GameScript::UnlockScroll(Scriptable
* /*Sender*/, Action
* /*parameters*/)
1841 GameControl
* gc
= core
->GetGameControl();
1843 gc
->SetScreenFlags(SF_LOCKSCROLL
, BM_NAND
);
1847 //no string, increase talkcount, no interrupt
1848 void GameScript::Dialogue(Scriptable
* Sender
, Action
* parameters
)
1850 BeginDialog( Sender
, parameters
, BD_SOURCE
| BD_TALKCOUNT
| BD_CHECKDIST
);
1853 void GameScript::DialogueForceInterrupt(Scriptable
* Sender
, Action
* parameters
)
1855 BeginDialog( Sender
, parameters
, BD_SOURCE
| BD_TALKCOUNT
| BD_INTERRUPT
);
1858 // not in IESDP but this one should affect ambients
1859 void GameScript::SoundActivate(Scriptable
* /*Sender*/, Action
* parameters
)
1861 AmbientMgr
* ambientmgr
= core
->GetAudioDrv()->GetAmbientMgr();
1862 if (parameters
->int0Parameter
) {
1863 ambientmgr
->activate(parameters
->objects
[1]->objectName
);
1865 ambientmgr
->deactivate(parameters
->objects
[1]->objectName
);
1869 // according to IESDP this action is about animations
1870 void GameScript::AmbientActivate(Scriptable
* Sender
, Action
* parameters
)
1872 AreaAnimation
* anim
= Sender
->GetCurrentArea( )->GetAnimation( parameters
->string0Parameter
);
1874 anim
= Sender
->GetCurrentArea( )->GetAnimation( parameters
->objects
[1]->objectName
);
1877 printf( "Script error: No Animation Named \"%s\" or \"%s\"\n",
1878 parameters
->string0Parameter
,parameters
->objects
[1]->objectName
);
1881 if (parameters
->int0Parameter
) {
1882 anim
->Flags
|= A_ANI_ACTIVE
;
1884 anim
->Flags
&= ~A_ANI_ACTIVE
;
1888 void GameScript::ChangeTileState(Scriptable
* Sender
, Action
* parameters
)
1890 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
1894 if (tar
->Type
!= ST_DOOR
) {
1897 Door
* door
= ( Door
* ) tar
;
1898 int state
= parameters
->int0Parameter
;
1900 door
->ToggleTiles(state
); /* default is false for playsound */
1904 void GameScript::StaticStart(Scriptable
* Sender
, Action
* parameters
)
1906 AreaAnimation
*anim
= Sender
->GetCurrentArea()->GetAnimation(parameters
->objects
[1]->objectName
);
1908 printf( "Script error: No Animation Named \"%s\"\n",
1909 parameters
->objects
[1]->objectName
);
1912 anim
->Flags
&=~A_ANI_PLAYONCE
;
1915 void GameScript::StaticStop(Scriptable
* Sender
, Action
* parameters
)
1917 AreaAnimation
*anim
= Sender
->GetCurrentArea()->GetAnimation(parameters
->objects
[1]->objectName
);
1919 printf( "Script error: No Animation Named \"%s\"\n",
1920 parameters
->objects
[1]->objectName
);
1923 anim
->Flags
|= A_ANI_PLAYONCE
;
1926 void GameScript::StaticPalette(Scriptable
* Sender
, Action
* parameters
)
1928 AreaAnimation
*anim
= Sender
->GetCurrentArea()->GetAnimation(parameters
->objects
[1]->objectName
);
1930 printf( "Script error: No Animation Named \"%s\"\n",
1931 parameters
->objects
[1]->objectName
);
1934 anim
->SetPalette( parameters
->string0Parameter
);
1937 //this is a special case of PlaySequence (with wait time, not for area anims)
1938 void GameScript::PlaySequenceTimed(Scriptable
* Sender
, Action
* parameters
)
1941 if (parameters
->objects
[1]) {
1942 tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1946 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
1949 Actor
* actor
= ( Actor
* ) tar
;
1950 actor
->SetStance( parameters
->int0Parameter
);
1951 int delay
= parameters
->int1Parameter
|| 1;
1952 actor
->SetWait( delay
);
1955 //waitanimation: waiting while animation of target is of a certain type
1956 void GameScript::WaitAnimation(Scriptable
* Sender
, Action
* parameters
)
1958 Scriptable
*tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1962 if (tar
->Type
!= ST_ACTOR
) {
1965 Actor
* actor
= ( Actor
* ) tar
;
1966 if (actor
->GetStance()!=parameters
->int0Parameter
) {
1967 Sender
->ReleaseCurrentAction();
1972 // PlaySequence without object parameter defaults to Sender
1973 void GameScript::PlaySequence(Scriptable
* Sender
, Action
* parameters
)
1976 if (parameters
->objects
[1]) {
1977 tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
1979 //could be an animation
1980 AreaAnimation
* anim
= Sender
->GetCurrentArea( )->GetAnimation( parameters
->objects
[1]->objectName
);
1982 //set animation's cycle to parameters->int0Parameter;
1983 anim
->sequence
=parameters
->int0Parameter
;
1985 //what else to be done???
1986 anim
->InitAnimation();
1994 if (tar
->Type
!= ST_ACTOR
) {
1997 Actor
* actor
= ( Actor
* ) tar
;
1998 actor
->SetStance( parameters
->int0Parameter
);
2001 void GameScript::SetDialogue(Scriptable
* Sender
, Action
* parameters
)
2003 if (Sender
->Type
!= ST_ACTOR
) {
2006 Actor
* target
= ( Actor
* ) Sender
;
2007 target
->SetDialog( parameters
->string0Parameter
);
2010 void GameScript::ChangeDialogue(Scriptable
* Sender
, Action
* parameters
)
2012 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2016 if (tar
->Type
!= ST_ACTOR
) {
2019 Actor
* target
= ( Actor
* ) tar
;
2020 target
->SetDialog( parameters
->string0Parameter
);
2023 //string0, no interrupt, talkcount increased
2024 void GameScript::StartDialogue(Scriptable
* Sender
, Action
* parameters
)
2026 BeginDialog( Sender
, parameters
, BD_STRING0
| BD_TALKCOUNT
| BD_SETDIALOG
);
2029 //string0, no interrupt, talkcount increased, don't set default
2030 //optionally item name is used
2031 void GameScript::StartDialogueOverride(Scriptable
* Sender
, Action
* parameters
)
2033 int flags
= BD_STRING0
| BD_TALKCOUNT
;
2035 if (parameters
->int2Parameter
) {
2038 BeginDialog( Sender
, parameters
, flags
);
2041 //string0, no interrupt, talkcount increased, don't set default
2042 //optionally item name is used
2043 void GameScript::StartDialogueOverrideInterrupt(Scriptable
* Sender
,
2046 int flags
= BD_STRING0
| BD_TALKCOUNT
| BD_INTERRUPT
;
2048 if (parameters
->int2Parameter
) {
2051 BeginDialog( Sender
, parameters
, flags
);
2054 //start talking to oneself
2055 void GameScript::PlayerDialogue(Scriptable
* Sender
, Action
* parameters
)
2057 BeginDialog( Sender
, parameters
, BD_RESERVED
| BD_OWN
);
2060 //we hijack this action for the player initiated dialogue
2061 void GameScript::NIDSpecial1(Scriptable
* Sender
, Action
* parameters
)
2063 BeginDialog( Sender
, parameters
, BD_INTERRUPT
| BD_TARGET
/*| BD_NUMERIC*/ | BD_TALKCOUNT
| BD_CHECKDIST
);
2066 void GameScript::NIDSpecial2(Scriptable
* Sender
, Action
* /*parameters*/)
2068 if (Sender
->Type
!= ST_ACTOR
) {
2069 Sender
->ReleaseCurrentAction();
2072 Game
*game
=core
->GetGame();
2073 if (!game
->EveryoneStopped() ) {
2075 Sender
->SetWait( 1 * AI_UPDATE_TIME
);
2078 Actor
*actor
= (Actor
*) Sender
;
2079 if (!game
->EveryoneNearPoint(actor
->GetCurrentArea(), actor
->Pos
, true) ) {
2080 //we abort the command, everyone should be here
2081 Sender
->ReleaseCurrentAction();
2084 //travel direction passed to guiscript
2085 int direction
= Sender
->GetCurrentArea()->WhichEdge(actor
->Pos
);
2086 printf("Travel direction returned: %d\n", direction
);
2087 if (direction
==-1) {
2088 Sender
->ReleaseCurrentAction();
2091 core
->GetDictionary()->SetAt("Travel", (ieDword
) direction
);
2092 core
->GetGUIScriptEngine()->RunFunction( "OpenWorldMapWindow" );
2093 //sorry, i have absolutely no idea when i should do this :)
2094 Sender
->ReleaseCurrentAction();
2097 void GameScript::StartDialogueInterrupt(Scriptable
* Sender
, Action
* parameters
)
2099 BeginDialog( Sender
, parameters
,
2100 BD_STRING0
| BD_INTERRUPT
| BD_TALKCOUNT
| BD_SETDIALOG
);
2103 //No string, flags:0
2104 void GameScript::StartDialogueNoSet(Scriptable
* Sender
, Action
* parameters
)
2106 BeginDialog( Sender
, parameters
, BD_TALKCOUNT
| BD_SOURCE
);
2109 void GameScript::StartDialogueNoSetInterrupt(Scriptable
* Sender
,
2112 BeginDialog( Sender
, parameters
, BD_TALKCOUNT
| BD_SOURCE
| BD_INTERRUPT
);
2115 //no talkcount, using banter dialogs
2116 //probably banter dialogs are random, like rumours!
2117 //no, they aren't, but they increase interactcount
2118 void GameScript::Interact(Scriptable
* Sender
, Action
* parameters
)
2120 BeginDialog( Sender
, parameters
, BD_INTERACT
| BD_NOEMPTY
);
2123 static unsigned int FindNearPoint(Scriptable
* Sender
, Point
*&p1
, Point
*&p2
)
2125 unsigned int distance1
= Distance(*p1
, Sender
);
2126 unsigned int distance2
= Distance(*p2
, Sender
);
2127 if (distance1
<= distance2
) {
2137 //this is an immediate action without checking Sender
2138 void GameScript::DetectSecretDoor(Scriptable
* Sender
, Action
* parameters
)
2140 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
2144 if (tar
->Type
!= ST_DOOR
) {
2147 Door
* door
= ( Door
* ) tar
;
2148 if (door
->Flags
& DOOR_SECRET
) {
2149 door
->Flags
|= DOOR_FOUND
;
2153 //this is an immediate action without checking Sender
2154 void GameScript::Lock(Scriptable
* Sender
, Action
* parameters
)
2156 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2160 switch (tar
->Type
) {
2162 ((Door
*)tar
)->SetDoorLocked(true, true);
2165 ((Container
*)tar
)->SetContainerLocked(true);
2172 void GameScript::Unlock(Scriptable
* Sender
, Action
* parameters
)
2174 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2178 switch (tar
->Type
) {
2180 ((Door
*)tar
)->SetDoorLocked(false, true);
2183 ((Container
*)tar
)->SetContainerLocked(false);
2190 void GameScript::SetDoorLocked(Scriptable
* Sender
, Action
* parameters
)
2192 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2196 if (tar
->Type
!= ST_DOOR
) {
2199 Door
* door
= ( Door
* ) tar
;
2200 door
->SetDoorLocked( parameters
->int0Parameter
!=0, false);
2203 void GameScript::SetDoorFlag(Scriptable
* Sender
, Action
* parameters
)
2205 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2209 if (tar
->Type
!= ST_DOOR
) {
2212 Door
* door
= ( Door
* ) tar
;
2213 ieDword flag
= parameters
->int0Parameter
;
2215 //these are special flags
2216 if (flag
&DOOR_LOCKED
) {
2218 door
->SetDoorLocked(parameters
->int1Parameter
!=0, false);
2220 if (flag
&DOOR_OPEN
) {
2222 door
->SetDoorOpen(parameters
->int1Parameter
!=0, false, 0);
2225 if (parameters
->int1Parameter
) {
2232 void GameScript::RemoveTraps(Scriptable
* Sender
, Action
* parameters
)
2234 //only actors may try to pick a lock
2235 if (Sender
->Type
!= ST_ACTOR
) {
2236 Sender
->ReleaseCurrentAction();
2239 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2241 Sender
->ReleaseCurrentAction();
2244 unsigned int distance
;
2247 Container
*container
= NULL
;
2248 InfoPoint
*trigger
= NULL
;
2249 ScriptableType type
= tar
->Type
;
2254 door
= ( Door
* ) tar
;
2255 if (door
->IsOpen()) {
2256 //door is already open
2257 Sender
->ReleaseCurrentAction();
2261 otherp
= door
->toOpen
+1;
2262 distance
= FindNearPoint( Sender
, p
, otherp
);
2263 flags
= door
->Trapped
&& door
->TrapDetected
;
2266 container
= (Container
*) tar
;
2267 p
= &container
->Pos
;
2269 distance
= Distance(*p
, Sender
);
2270 flags
= container
->Trapped
&& container
->TrapDetected
;
2273 trigger
= (InfoPoint
*) tar
;
2274 // this point is incorrect! will cause actor to enter trap
2275 // need to find a point using trigger->outline
2278 distance
= Distance(tar
, Sender
);
2279 flags
= trigger
->Trapped
&& trigger
->TrapDetected
&& trigger
->CanDetectTrap();
2282 Sender
->ReleaseCurrentAction();
2285 Actor
* actor
= (Actor
*) Sender
;
2286 actor
->SetOrientation( GetOrient( *otherp
, actor
->Pos
), false);
2287 if (distance
<= MAX_OPERATING_DISTANCE
) {
2291 door
->TryDisarm(actor
);
2294 container
->TryDisarm(actor
);
2297 trigger
->TryDisarm(actor
);
2305 //core->DisplayString(STR_NOT_TRAPPED);
2308 MoveNearerTo(Sender
, *p
, MAX_OPERATING_DISTANCE
,0);
2312 Sender
->ReleaseCurrentAction();
2315 void GameScript::PickLock(Scriptable
* Sender
, Action
* parameters
)
2317 //only actors may try to pick a lock
2318 if (Sender
->Type
!= ST_ACTOR
) {
2319 Sender
->ReleaseCurrentAction();
2322 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2324 Sender
->ReleaseCurrentAction();
2327 unsigned int distance
;
2330 Container
*container
= NULL
;
2331 ScriptableType type
= tar
->Type
;
2336 door
= ( Door
* ) tar
;
2337 if (door
->IsOpen()) {
2338 //door is already open
2339 Sender
->ReleaseCurrentAction();
2343 otherp
= door
->toOpen
+1;
2344 distance
= FindNearPoint( Sender
, p
, otherp
);
2345 flags
= door
->Flags
&DOOR_LOCKED
;
2348 container
= (Container
*) tar
;
2349 p
= &container
->Pos
;
2351 distance
= Distance(*p
, Sender
);
2352 flags
= container
->Flags
&CONT_LOCKED
;
2355 Sender
->ReleaseCurrentAction();
2358 Actor
* actor
= (Actor
*) Sender
;
2359 actor
->SetOrientation( GetOrient( *otherp
, actor
->Pos
), false);
2360 if (distance
<= MAX_OPERATING_DISTANCE
) {
2362 if (type
==ST_DOOR
) {
2363 door
->TryPickLock(actor
);
2365 container
->TryPickLock(actor
);
2369 //core->DisplayString(STR_NOT_LOCKED);
2372 MoveNearerTo(Sender
, *p
, MAX_OPERATING_DISTANCE
,0);
2376 Sender
->ReleaseCurrentAction();
2379 void GameScript::OpenDoor(Scriptable
* Sender
, Action
* parameters
) {
2380 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2384 if (tar
->Type
!= ST_DOOR
) {
2387 Door
* door
= ( Door
* ) tar
;
2388 // no idea if this is right, or whether OpenDoor/CloseDoor should allow opening
2389 // of all doors, or some doors, or whether it should still check for non-actors
2390 if (Sender
->Type
== ST_ACTOR
) {
2391 Actor
*actor
= (Actor
*)Sender
;
2392 actor
->SetModal(MS_NONE
);
2393 if (!door
->TryUnlock(actor
)) {
2397 //if not an actor opens, it don't play sound
2398 door
->SetDoorOpen( true, (Sender
->Type
== ST_ACTOR
), 0 );
2399 Sender
->ReleaseCurrentAction();
2402 void GameScript::CloseDoor(Scriptable
* Sender
, Action
* parameters
) {
2403 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2407 if (tar
->Type
!= ST_DOOR
) {
2410 Door
* door
= ( Door
* ) tar
;
2411 // see comments in OpenDoor above
2412 if (Sender
->Type
== ST_ACTOR
) {
2413 Actor
*actor
= (Actor
*)Sender
;
2414 if (!door
->TryUnlock(actor
)) {
2418 //if not an actor closes, it don't play sound
2419 door
->SetDoorOpen( false, (Sender
->Type
== ST_ACTOR
), 0 );
2420 Sender
->ReleaseCurrentAction();
2423 void GameScript::ToggleDoor(Scriptable
* Sender
, Action
* /*parameters*/)
2425 if (Sender
->Type
!= ST_ACTOR
) {
2426 Sender
->ReleaseCurrentAction();
2429 Actor
*actor
= (Actor
*) Sender
;
2430 actor
->SetModal(MS_NONE
);
2432 // TargetDoor is set when GameControl makes the action, so should be fine
2433 // unless this action is quietly called by a script (and UseDoor in the
2434 // original engine crashes, so this is surely no worse..), but we should
2435 // maybe have a better solution
2436 Scriptable
* tar
= actor
->TargetDoor
;
2438 Sender
->ReleaseCurrentAction();
2441 if (tar
->Type
!= ST_DOOR
) {
2442 Sender
->ReleaseCurrentAction();
2445 Door
* door
= ( Door
* ) tar
;
2446 unsigned int distance
;
2447 Point
*p
= door
->toOpen
;
2448 Point
*otherp
= door
->toOpen
+1;
2449 distance
= FindNearPoint( Sender
, p
, otherp
);
2450 if (distance
<= MAX_OPERATING_DISTANCE
) {
2451 actor
->SetOrientation( GetOrient( *otherp
, actor
->Pos
), false);
2452 if (!door
->TryUnlock(actor
)) {
2453 core
->DisplayConstantString(STR_DOORLOCKED
,0xd7d7be,door
);
2454 //playsound unsuccessful opening of door
2456 core
->PlaySound(DS_CLOSE_FAIL
);
2458 core
->PlaySound(DS_OPEN_FAIL
);
2459 Sender
->ReleaseCurrentAction();
2460 return; //don't open door
2463 // should we be triggering the trap on close?
2464 door
->TriggerTrap(0, actor
->GetID());
2465 door
->SetDoorOpen( !door
->IsOpen(), true, actor
->GetID() );
2467 MoveNearerTo(Sender
, *p
, MAX_OPERATING_DISTANCE
,0);
2471 Sender
->ReleaseCurrentAction();
2474 void GameScript::ContainerEnable(Scriptable
* Sender
, Action
* parameters
)
2476 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2477 if (!tar
|| tar
->Type
!=ST_CONTAINER
) {
2480 Container
*cnt
= (Container
*) tar
;
2481 if (parameters
->int0Parameter
) {
2482 cnt
->Flags
&=~CONT_DISABLED
;
2484 cnt
->Flags
|=CONT_DISABLED
;
2488 void GameScript::MoveBetweenAreas(Scriptable
* Sender
, Action
* parameters
)
2490 if (Sender
->Type
!= ST_ACTOR
) {
2493 if (parameters
->string1Parameter
[0]) {
2494 CreateVisualEffectCore(Sender
, Sender
->Pos
, parameters
->string1Parameter
, 0);
2496 MoveBetweenAreasCore((Actor
*) Sender
, parameters
->string0Parameter
,
2497 parameters
->pointParameter
, parameters
->int0Parameter
, true);
2500 //spell is depleted, casting time is calculated, interruptible
2501 //FIXME The caster must meet the level requirements as set in the spell file
2502 void GameScript::Spell(Scriptable
* Sender
, Action
* parameters
)
2507 if (!ResolveSpellName( spellres
, parameters
) ) {
2508 Sender
->ReleaseCurrentAction();
2512 //if target was set, fire spell
2513 if (Sender
->LastTarget
) {
2514 Sender
->CastSpellEnd( spellres
);
2515 Sender
->ReleaseCurrentAction();
2519 //the target was converted to a point
2520 if(!Sender
->LastTargetPos
.isempty()) {
2521 Sender
->CastSpellPointEnd( spellres
);
2522 Sender
->ReleaseCurrentAction();
2527 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
2529 Sender
->ReleaseCurrentAction();
2533 if(Sender
->Type
==ST_ACTOR
) {
2534 Actor
*act
= (Actor
*) Sender
;
2536 unsigned int dist
= GetSpellDistance(spellres
, act
);
2538 //move near to target
2539 if (PersonalDistance(tar
, Sender
) > dist
) {
2540 MoveNearerTo(Sender
,tar
,dist
);
2545 if (tar
!= Sender
) {
2546 act
->SetOrientation( GetOrient( tar
->Pos
, act
->Pos
), false );
2549 //stop doing anything else
2550 act
->SetModal(MS_NONE
);
2552 int duration
= Sender
->CastSpell( spellres
, tar
, true );
2553 if (duration
!= -1) Sender
->SetWait(duration
);
2555 //if target was set, feed action back
2556 if (!Sender
->LastTarget
&& Sender
->LastTargetPos
.isempty()) {
2557 Sender
->ReleaseCurrentAction();
2561 //spell is depleted, casting time is calculated, interruptible
2562 //FIXME The caster must meet the level requirements as set in the spell file
2563 void GameScript::SpellPoint(Scriptable
* Sender
, Action
* parameters
)
2568 if (!ResolveSpellName( spellres
, parameters
) ) {
2569 Sender
->ReleaseCurrentAction();
2573 //if target was set, fire spell
2574 if (!Sender
->LastTargetPos
.isempty()) {
2575 Sender
->CastSpellPointEnd( spellres
);
2576 Sender
->ReleaseCurrentAction();
2580 if(Sender
->Type
==ST_ACTOR
) {
2581 Actor
*act
= (Actor
*) Sender
;
2583 unsigned int dist
= GetSpellDistance(spellres
, act
);
2585 //move near to target
2586 if (PersonalDistance(parameters
->pointParameter
, Sender
) > dist
) {
2587 MoveNearerTo(Sender
,parameters
->pointParameter
,dist
, 0);
2592 act
->SetOrientation( GetOrient( parameters
->pointParameter
, act
->Pos
), false );
2593 //stop doing anything else
2594 act
->SetModal(MS_NONE
);
2597 int duration
= Sender
->CastSpellPoint( spellres
, parameters
->pointParameter
, true );
2598 if (duration
!= -1) Sender
->SetWait(duration
);
2600 //if target was set, feed action back
2601 if (!Sender
->LastTarget
&& Sender
->LastTargetPos
.isempty()) {
2602 Sender
->ReleaseCurrentAction();
2606 //spell is not depleted (doesn't need to be memorised or known)
2607 //casting time is calculated, interruptible
2608 //FIXME The caster must meet the level requirements as set in the spell file
2609 void GameScript::SpellNoDec(Scriptable
* Sender
, Action
* parameters
)
2614 if (!ResolveSpellName( spellres
, parameters
) ) {
2615 Sender
->ReleaseCurrentAction();
2619 //if target was set, fire spell
2620 if (Sender
->LastTarget
) {
2621 Sender
->CastSpellEnd( spellres
);
2622 Sender
->ReleaseCurrentAction();
2626 //the target was converted to a point
2627 if(!Sender
->LastTargetPos
.isempty()) {
2628 Sender
->CastSpellPointEnd( spellres
);
2629 Sender
->ReleaseCurrentAction();
2634 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
2636 Sender
->ReleaseCurrentAction();
2641 if (Sender
->Type
==ST_ACTOR
) {
2642 Actor
*act
= (Actor
*) Sender
;
2643 if (tar
!= Sender
) {
2644 act
->SetOrientation( GetOrient( tar
->Pos
, act
->Pos
), false );
2647 //stop doing anything else
2648 act
->SetModal(MS_NONE
);
2650 int duration
= Sender
->CastSpell( spellres
, tar
, false );
2651 if (duration
!= -1) Sender
->SetWait(duration
);
2653 //if target was set, feed action back
2654 if (!Sender
->LastTarget
&& Sender
->LastTargetPos
.isempty()) {
2655 Sender
->ReleaseCurrentAction();
2659 //spell is not depleted (doesn't need to be memorised or known)
2660 //casting time is calculated, interruptible
2661 //FIXME The caster must meet the level requirements as set in the spell file
2662 void GameScript::SpellPointNoDec(Scriptable
* Sender
, Action
* parameters
)
2667 if (!ResolveSpellName( spellres
, parameters
) ) {
2668 Sender
->ReleaseCurrentAction();
2672 //if target was set, fire spell
2673 if (!Sender
->LastTargetPos
.isempty()) {
2674 Sender
->CastSpellPointEnd( spellres
);
2675 Sender
->ReleaseCurrentAction();
2680 if (Sender
->Type
==ST_ACTOR
) {
2681 Actor
*act
= (Actor
*) Sender
;
2682 act
->SetOrientation( GetOrient( parameters
->pointParameter
, act
->Pos
), false );
2684 //stop doing anything else
2685 act
->SetModal(MS_NONE
);
2688 int duration
= Sender
->CastSpellPoint( spellres
, parameters
->pointParameter
, false );
2689 if (duration
!= -1) Sender
->SetWait(duration
);
2691 //if target was set, feed action back
2692 if (Sender
->LastTargetPos
.isempty()) {
2693 Sender
->ReleaseCurrentAction();
2697 //spell is not depleted (doesn't need to be memorised or known)
2698 //casting time is calculated, not interruptable
2699 //FIXME The caster must meet the level requirements as set in the spell file
2700 void GameScript::ForceSpell(Scriptable
* Sender
, Action
* parameters
)
2705 if (!ResolveSpellName( spellres
, parameters
) ) {
2706 Sender
->ReleaseCurrentAction();
2710 //if target was set, fire spell
2711 if (Sender
->LastTarget
) {
2712 Sender
->CastSpellEnd( spellres
);
2713 Sender
->ReleaseCurrentAction();
2717 //the target was converted to a point
2718 if(!Sender
->LastTargetPos
.isempty()) {
2719 Sender
->CastSpellPointEnd( spellres
);
2720 Sender
->ReleaseCurrentAction();
2725 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
2727 Sender
->ReleaseCurrentAction();
2732 if (Sender
->Type
==ST_ACTOR
) {
2733 Actor
*act
= (Actor
*) Sender
;
2734 if (tar
!= Sender
) {
2735 act
->SetOrientation( GetOrient( tar
->Pos
, act
->Pos
), false );
2738 //stop doing anything else
2739 act
->SetModal(MS_NONE
);
2741 int duration
= Sender
->CastSpell (spellres
, tar
, false);
2742 if (duration
!= -1) Sender
->SetWait(duration
);
2744 //if target was set, feed action back
2745 if (!Sender
->LastTarget
&& Sender
->LastTargetPos
.isempty()) {
2746 Sender
->ReleaseCurrentAction();
2750 //spell is not depleted (doesn't need to be memorised or known)
2751 //casting time is calculated, not interruptable
2752 //FIXME The caster must meet the level requirements as set in the spell file
2753 void GameScript::ForceSpellPoint(Scriptable
* Sender
, Action
* parameters
)
2757 if (!ResolveSpellName( spellres
, parameters
) ) {
2758 Sender
->ReleaseCurrentAction();
2762 //if target was set, fire spell
2763 if (!Sender
->LastTargetPos
.isempty()) {
2764 Sender
->CastSpellPointEnd( spellres
);
2765 Sender
->ReleaseCurrentAction();
2770 if (Sender
->Type
==ST_ACTOR
) {
2771 Actor
*act
= (Actor
*) Sender
;
2772 act
->SetOrientation( GetOrient( parameters
->pointParameter
, act
->Pos
), false );
2774 //stop doing anything else
2775 act
->SetModal(MS_NONE
);
2778 int duration
= Sender
->CastSpellPoint (spellres
, parameters
->pointParameter
, false);
2779 if (duration
!= -1) Sender
->SetWait(duration
);
2781 //if target was set, feed action back
2782 if (Sender
->LastTargetPos
.isempty()) {
2783 Sender
->ReleaseCurrentAction();
2787 //ForceSpell with zero casting time
2788 //zero casting time, no depletion, not interruptable
2789 //FIXME The caster must meet the level requirements as set in the spell file
2790 void GameScript::ReallyForceSpell(Scriptable
* Sender
, Action
* parameters
)
2794 if (!ResolveSpellName( spellres
, parameters
) ) {
2795 Sender
->ReleaseCurrentAction();
2799 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2801 Sender
->ReleaseCurrentAction();
2804 if (Sender
->Type
== ST_ACTOR
) {
2805 Actor
*actor
= (Actor
*) Sender
;
2806 if (tar
!= Sender
) {
2807 actor
->SetOrientation( GetOrient( tar
->Pos
, actor
->Pos
), false );
2809 actor
->SetStance (IE_ANI_CONJURE
);
2811 Sender
->CastSpell (spellres
, tar
, false, true);
2812 if (tar
->Type
==ST_ACTOR
) {
2813 Sender
->CastSpellEnd(spellres
);
2815 Sender
->CastSpellPointEnd(spellres
);
2817 Sender
->ReleaseCurrentAction();
2820 //ForceSpellPoint with zero casting time
2821 //zero casting time, no depletion (finish casting at point), not interruptable
2823 //FIXME The caster must meet the level requirements as set in the spell file
2824 void GameScript::ReallyForceSpellPoint(Scriptable
* Sender
, Action
* parameters
)
2828 if (!ResolveSpellName( spellres
, parameters
) ) {
2829 Sender
->ReleaseCurrentAction();
2833 //Sender->LastTargetPos=parameters->pointParameter;
2834 if (Sender
->Type
== ST_ACTOR
) {
2835 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
2836 Sender
->ReleaseCurrentAction();
2839 Actor
*actor
= (Actor
*) Sender
;
2840 actor
->SetOrientation( GetOrient( parameters
->pointParameter
, actor
->Pos
), false );
2841 actor
->SetStance (IE_ANI_CONJURE
);
2843 Sender
->CastSpellPoint (spellres
, parameters
->pointParameter
, false, true);
2844 Sender
->CastSpellPointEnd(spellres
);
2845 Sender
->ReleaseCurrentAction();
2848 // this differs from ReallyForceSpell that this one allows dead Sender casting
2849 // zero casting time, no depletion
2850 void GameScript::ReallyForceSpellDead(Scriptable
* Sender
, Action
* parameters
)
2854 if (!ResolveSpellName( spellres
, parameters
) ) {
2855 Sender
->ReleaseCurrentAction();
2859 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2861 Sender
->ReleaseCurrentAction();
2864 Sender
->LastTargetPos
=parameters
->pointParameter
;
2866 if (Sender->Type == ST_ACTOR) {
2867 Actor *actor = (Actor *) Sender;
2868 //the dead don't wiggle their fingers
2869 //actor->SetStance (IE_ANI_CONJURE);
2872 Sender
->CastSpell (spellres
, tar
, false, true);
2873 if (tar
->Type
==ST_ACTOR
) {
2874 Sender
->CastSpellEnd(spellres
);
2876 Sender
->CastSpellPointEnd(spellres
);
2878 Sender
->ReleaseCurrentAction();
2881 void GameScript::Deactivate(Scriptable
* Sender
, Action
* parameters
)
2883 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2887 if (tar
->Type
!= ST_ACTOR
) {
2893 void GameScript::MakeGlobal(Scriptable
* Sender
, Action
* /*parameters*/)
2895 if (Sender
->Type
!= ST_ACTOR
) {
2898 Actor
* act
= ( Actor
* ) Sender
;
2899 core
->GetGame()->AddNPC( act
);
2902 void GameScript::UnMakeGlobal(Scriptable
* Sender
, Action
* /*parameters*/)
2904 if (Sender
->Type
!= ST_ACTOR
) {
2907 Actor
* act
= ( Actor
* ) Sender
;
2909 slot
= core
->GetGame()->InStore( act
);
2911 core
->GetGame()->DelNPC( slot
);
2915 //this apparently doesn't check the gold, thus could be used from non actors
2916 void GameScript::GivePartyGoldGlobal(Scriptable
* Sender
, Action
* parameters
)
2918 ieDword gold
= (ieDword
) CheckVariable( Sender
, parameters
->string0Parameter
, parameters
->string1Parameter
);
2919 if (Sender
->Type
== ST_ACTOR
) {
2920 Actor
* act
= ( Actor
* ) Sender
;
2921 ieDword mygold
= act
->GetStat(IE_GOLD
);
2922 if (mygold
< gold
) {
2925 //will get saved, not adjusted
2926 act
->SetBase(IE_GOLD
, act
->GetBase(IE_GOLD
)-gold
);
2928 core
->GetGame()->AddGold(gold
);
2931 void GameScript::CreatePartyGold(Scriptable
* /*Sender*/, Action
* parameters
)
2933 core
->GetGame()->AddGold(parameters
->int0Parameter
);
2936 void GameScript::GivePartyGold(Scriptable
* Sender
, Action
* parameters
)
2938 ieDword gold
= (ieDword
) parameters
->int0Parameter
;
2939 if (Sender
->Type
== ST_ACTOR
) {
2940 Actor
* act
= ( Actor
* ) Sender
;
2941 ieDword mygold
= act
->GetStat(IE_GOLD
);
2942 if (mygold
< gold
) {
2945 //will get saved, not adjusted
2946 act
->SetBase(IE_GOLD
, act
->GetBase(IE_GOLD
)-gold
);
2948 core
->GetGame()->AddGold(gold
);
2951 void GameScript::DestroyPartyGold(Scriptable
* /*Sender*/, Action
* parameters
)
2953 int gold
= core
->GetGame()->PartyGold
;
2954 if (gold
>parameters
->int0Parameter
) {
2955 gold
=parameters
->int0Parameter
;
2957 core
->GetGame()->AddGold(-gold
);
2960 void GameScript::TakePartyGold(Scriptable
* Sender
, Action
* parameters
)
2962 ieDword gold
= core
->GetGame()->PartyGold
;
2963 if (gold
>(ieDword
) parameters
->int0Parameter
) {
2964 gold
=(ieDword
) parameters
->int0Parameter
;
2966 core
->GetGame()->AddGold((ieDword
) -(int) gold
);
2967 if (Sender
->Type
== ST_ACTOR
) {
2968 Actor
* act
= ( Actor
* ) Sender
;
2969 act
->SetBase(IE_GOLD
, act
->GetBase(IE_GOLD
)+gold
);
2973 void GameScript::AddXPObject(Scriptable
* Sender
, Action
* parameters
)
2975 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
2979 if (tar
->Type
!= ST_ACTOR
) {
2982 Actor
* actor
= ( Actor
* ) tar
;
2983 int xp
= parameters
->int0Parameter
;
2984 if (core
->HasStringReference(STR_GOTQUESTXP
)) {
2985 core
->GetTokenDictionary()->SetAtCopy("EXPERIENCEAMOUNT", xp
);
2986 core
->DisplayConstantStringName(STR_GOTQUESTXP
, 0xbcefbc, actor
);
2988 core
->DisplayConstantStringValue(STR_GOTXP
, 0xbcefbc, (ieDword
)xp
);
2990 actor
->AddExperience(xp
);
2993 void GameScript::AddXP2DA(Scriptable
* /*Sender*/, Action
* parameters
)
2997 if (core
->HasFeature(GF_HAS_EXPTABLE
) ) {
2998 xptable
.load("exptable");
3000 xptable
.load("xplist");
3003 if (parameters
->int0Parameter
>0) {
3004 core
->DisplayString(parameters
->int0Parameter
, 0x40f0f000,IE_STR_SOUND
);
3007 printMessage("GameScript","Can't perform ADDXP2DA",LIGHT_RED
);
3010 const char * xpvalue
= xptable
->QueryField( parameters
->string0Parameter
, "0" ); //level is unused
3012 if ( xpvalue
[0]=='P' && xpvalue
[1]=='_') {
3014 core
->GetGame()->ShareXP(atoi(xpvalue
+2), SX_DIVIDE
);
3017 core
->GetGame()->ShareXP(atoi(xpvalue
), 0 );
3021 void GameScript::AddExperienceParty(Scriptable
* /*Sender*/, Action
* parameters
)
3023 core
->GetGame()->ShareXP(parameters
->int0Parameter
, SX_DIVIDE
);
3026 //this needs moncrate.2da, but otherwise independent from GF_CHALLENGERATING
3027 void GameScript::AddExperiencePartyCR(Scriptable
* /*Sender*/, Action
* parameters
)
3029 core
->GetGame()->ShareXP(parameters
->int0Parameter
, SX_DIVIDE
|SX_CR
);
3032 void GameScript::AddExperiencePartyGlobal(Scriptable
* Sender
, Action
* parameters
)
3034 ieDword xp
= CheckVariable( Sender
, parameters
->string0Parameter
, parameters
->string1Parameter
);
3035 core
->GetGame()->ShareXP(xp
, SX_DIVIDE
);
3038 void GameScript::SetMoraleAI(Scriptable
* Sender
, Action
* parameters
)
3040 if (Sender
->Type
!= ST_ACTOR
) {
3043 Actor
* act
= ( Actor
* ) Sender
;
3044 act
->SetBase(IE_MORALE
, parameters
->int0Parameter
);
3047 void GameScript::IncMoraleAI(Scriptable
* Sender
, Action
* parameters
)
3049 if (Sender
->Type
!= ST_ACTOR
) {
3052 Actor
* act
= ( Actor
* ) Sender
;
3053 act
->SetBase(IE_MORALE
, parameters
->int0Parameter
+act
->GetBase(IE_MORALE
) );
3056 void GameScript::MoraleSet(Scriptable
* Sender
, Action
* parameters
)
3058 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3062 if (tar
->Type
!= ST_ACTOR
) {
3065 Actor
* act
= ( Actor
* ) tar
;
3066 act
->SetBase(IE_MORALEBREAK
, parameters
->int0Parameter
);
3069 void GameScript::MoraleInc(Scriptable
* Sender
, Action
* parameters
)
3071 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3075 if (tar
->Type
!= ST_ACTOR
) {
3078 Actor
* act
= ( Actor
* ) tar
;
3079 act
->SetBase(IE_MORALEBREAK
, act
->GetBase(IE_MORALEBREAK
)+parameters
->int0Parameter
);
3082 void GameScript::MoraleDec(Scriptable
* Sender
, Action
* parameters
)
3084 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3088 if (tar
->Type
!= ST_ACTOR
) {
3091 Actor
* act
= ( Actor
* ) tar
;
3092 act
->SetBase(IE_MORALEBREAK
, act
->GetBase(IE_MORALEBREAK
)-parameters
->int0Parameter
);
3095 void GameScript::JoinParty(Scriptable
* Sender
, Action
* parameters
)
3097 if (Sender
->Type
!= ST_ACTOR
) {
3100 /* calling this, so it is simpler to change */
3101 /* i'm not sure this is required here at all */
3102 SetBeenInPartyFlags(Sender
, parameters
);
3103 Actor
* act
= ( Actor
* ) Sender
;
3104 act
->SetBase( IE_EA
, EA_PC
);
3105 if (core
->HasFeature( GF_HAS_DPLAYER
)) {
3106 /* we must reset various existing scripts */
3107 act
->SetScript( "DEFAULT", AI_SCRIPT_LEVEL
, true );
3108 act
->SetScript( "", SCR_RACE
, true );
3109 act
->SetScript( "", SCR_GENERAL
, true );
3110 act
->SetScript( "DPLAYER2", SCR_DEFAULT
, false );
3112 AutoTable
pdtable("pdialog");
3114 const char* scriptname
= act
->GetScriptName();
3116 //set dialog only if we got a row
3117 if (pdtable
->GetRowIndex( scriptname
) != -1) {
3118 strnlwrcpy(resref
, pdtable
->QueryField( scriptname
, "JOIN_DIALOG_FILE"),8);
3119 act
->SetDialog( resref
);
3122 core
->GetGame()->JoinParty( act
, JP_JOIN
);
3123 core
->GetGUIScriptEngine()->RunFunction( "UpdatePortraitWindow" );
3126 void GameScript::LeaveParty(Scriptable
* Sender
, Action
* /*parameters*/)
3128 if (Sender
->Type
!= ST_ACTOR
) {
3131 Actor
* act
= ( Actor
* ) Sender
;
3132 core
->GetGame()->LeaveParty( act
);
3133 core
->GetGUIScriptEngine()->RunFunction( "UpdatePortraitWindow" );
3136 //HideCreature hides only the visuals of a creature
3137 //(feet circle and avatar)
3138 //the scripts of the creature are still running
3139 //iwd2 stores this flag in the MC field
3140 void GameScript::HideCreature(Scriptable
* Sender
, Action
* parameters
)
3142 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3143 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3146 Actor
* actor
= ( Actor
* ) tar
;
3147 actor
->BaseStats
[IE_AVATARREMOVAL
]=parameters
->int0Parameter
;
3150 //i have absolutely no idea why this is needed when we have HideCreature
3151 void GameScript::ForceHide(Scriptable
* Sender
, Action
* parameters
)
3153 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3157 if (tar
->Type
!= ST_ACTOR
) {
3160 Actor
* actor
= ( Actor
* ) tar
;
3161 actor
->BaseStats
[IE_AVATARREMOVAL
]=1;
3164 void GameScript::Activate(Scriptable
* Sender
, Action
* parameters
)
3166 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3167 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3170 // Deactivate hides, so this should unhide..
3175 void GameScript::ForceLeaveAreaLUA(Scriptable
* Sender
, Action
* parameters
)
3177 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3178 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3181 Actor
* actor
= ( Actor
* ) tar
;
3182 //the LoadMos ResRef may be empty
3183 strncpy(core
->GetGame()->LoadMos
, parameters
->string1Parameter
,8);
3184 MoveBetweenAreasCore( actor
, parameters
->string0Parameter
, parameters
->pointParameter
, parameters
->int0Parameter
, true);
3187 void GameScript::LeaveAreaLUA(Scriptable
* Sender
, Action
* parameters
)
3189 if (Sender
->Type
!= ST_ACTOR
) {
3192 Actor
* actor
= ( Actor
* ) Sender
;
3193 //the LoadMos ResRef may be empty
3194 strncpy(core
->GetGame()->LoadMos
, parameters
->string1Parameter
,8);
3195 MoveBetweenAreasCore( actor
, parameters
->string0Parameter
, parameters
->pointParameter
, parameters
->int0Parameter
, true);
3198 //this is a blocking action, because we have to move to the Entry
3199 void GameScript::LeaveAreaLUAEntry(Scriptable
* Sender
, Action
* parameters
)
3201 if (Sender
->Type
!= ST_ACTOR
) {
3202 Sender
->ReleaseCurrentAction();
3205 Actor
*actor
= (Actor
*) Sender
;
3206 Game
*game
= core
->GetGame();
3207 strncpy(game
->LoadMos
, parameters
->string1Parameter
,8);
3208 Point p
= GetEntryPoint(actor
->Area
, parameters
->string1Parameter
);
3210 Sender
->ReleaseCurrentAction();
3213 parameters
->pointParameter
=p
;
3214 LeaveAreaLUA(Sender
, parameters
);
3215 Sender
->ReleaseCurrentAction();
3218 void GameScript::LeaveAreaLUAPanic(Scriptable
* Sender
, Action
* parameters
)
3220 if (Sender
->Type
!= ST_ACTOR
) {
3223 Actor
* actor
= ( Actor
* ) Sender
;
3224 strncpy(core
->GetGame()->LoadMos
, parameters
->string1Parameter
,8);
3225 MoveBetweenAreasCore( actor
, parameters
->string0Parameter
, parameters
->pointParameter
, parameters
->int0Parameter
, true);
3228 //this is a blocking action, because we have to move to the Entry
3229 void GameScript::LeaveAreaLUAPanicEntry(Scriptable
* Sender
, Action
* parameters
)
3231 if (Sender
->Type
!= ST_ACTOR
) {
3232 Sender
->ReleaseCurrentAction();
3235 Actor
*actor
= (Actor
*) Sender
;
3236 Game
*game
= core
->GetGame();
3237 strncpy(game
->LoadMos
, parameters
->string1Parameter
,8);
3238 Point p
= GetEntryPoint(actor
->Area
, parameters
->string1Parameter
);
3240 Sender
->ReleaseCurrentAction();
3243 parameters
->pointParameter
=p
;
3244 LeaveAreaLUAPanic(Sender
, parameters
);
3245 Sender
->ReleaseCurrentAction();
3248 void GameScript::SetToken(Scriptable
* /*Sender*/, Action
* parameters
)
3250 //SetAt takes a newly created reference (no need of free/copy)
3251 char * str
= core
->GetString( parameters
->int0Parameter
);
3252 core
->GetTokenDictionary()->SetAt( parameters
->string1Parameter
, str
);
3255 //Assigns a numeric variable to the token
3256 void GameScript::SetTokenGlobal(Scriptable
* Sender
, Action
* parameters
)
3258 ieDword value
= CheckVariable( Sender
, parameters
->string0Parameter
);
3259 //using SetAtCopy because we need a copy of the value
3260 core
->GetTokenDictionary()->SetAtCopy( parameters
->string1Parameter
, value
);
3263 //Assigns the target object's name (not scriptname) to the token
3264 void GameScript::SetTokenObject(Scriptable
* Sender
, Action
* parameters
)
3266 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3267 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3270 Actor
* actor
= ( Actor
* ) tar
;
3271 core
->GetTokenDictionary()->SetAtCopy( parameters
->string0Parameter
, actor
->GetName(0) );
3274 void GameScript::PlayDead(Scriptable
* Sender
, Action
* parameters
)
3276 if (Sender
->Type
!= ST_ACTOR
) {
3277 Sender
->ReleaseCurrentAction();
3280 Actor
* actor
= ( Actor
* ) Sender
;
3281 if (Sender
->CurrentActionState
== 0) {
3282 Sender
->CurrentActionState
= 1;
3283 actor
->SetStance( IE_ANI_DIE
);
3284 actor
->playDeadCounter
= parameters
->int0Parameter
;
3285 actor
->NoInterrupt();
3287 if (actor
->playDeadCounter
== 0) {
3288 Sender
->ReleaseCurrentAction();
3292 /** no difference at this moment, but this action should be interruptable */
3293 /** probably that means, we don't have to issue the SetWait, but this needs */
3294 /** further research */
3295 void GameScript::PlayDeadInterruptable(Scriptable
* Sender
, Action
* parameters
)
3297 if (Sender
->Type
!= ST_ACTOR
) {
3300 Actor
* actor
= ( Actor
* ) Sender
;
3301 actor
->SetStance( IE_ANI_DIE
);
3302 //also set time for playdead!
3303 actor
->playDeadCounter
= parameters
->int0Parameter
;
3304 actor
->SetWait( 1 );
3305 Sender
->ReleaseCurrentAction(); // todo, blocking?
3308 /* this may not be correct, just a placeholder you can fix */
3309 void GameScript::Swing(Scriptable
* Sender
, Action
* /*parameters*/)
3311 if (Sender
->Type
!= ST_ACTOR
) {
3314 Actor
* actor
= ( Actor
* ) Sender
;
3315 actor
->SetStance( IE_ANI_ATTACK
);
3316 actor
->SetWait( 1 );
3319 /* this may not be correct, just a placeholder you can fix */
3320 void GameScript::SwingOnce(Scriptable
* Sender
, Action
* /*parameters*/)
3322 if (Sender
->Type
!= ST_ACTOR
) {
3325 Actor
* actor
= ( Actor
* ) Sender
;
3326 actor
->SetStance( IE_ANI_ATTACK
);
3327 actor
->SetWait( 1 );
3330 void GameScript::Recoil(Scriptable
* Sender
, Action
* /*parameters*/)
3332 if (Sender
->Type
!= ST_ACTOR
) {
3335 Actor
* actor
= ( Actor
* ) Sender
;
3336 actor
->SetStance( IE_ANI_DAMAGE
);
3337 actor
->SetWait( 1 );
3340 void GameScript::GlobalSetGlobal(Scriptable
* Sender
, Action
* parameters
)
3342 ieDword value
= CheckVariable( Sender
, parameters
->string0Parameter
);
3343 SetVariable( Sender
, parameters
->string1Parameter
, value
);
3346 /* adding the second variable to the first, they must be GLOBAL */
3347 void GameScript::AddGlobals(Scriptable
* Sender
, Action
* parameters
)
3349 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
, "GLOBAL");
3350 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
, "GLOBAL");
3351 SetVariable( Sender
, parameters
->string0Parameter
, "GLOBAL", value1
+ value2
);
3354 /* adding the second variable to the first, they could be area or locals */
3355 void GameScript::GlobalAddGlobal(Scriptable
* Sender
, Action
* parameters
)
3357 ieDword value1
= CheckVariable( Sender
,
3358 parameters
->string0Parameter
);
3359 ieDword value2
= CheckVariable( Sender
,
3360 parameters
->string1Parameter
);
3361 SetVariable( Sender
, parameters
->string0Parameter
, value1
+ value2
);
3364 /* adding the number to the global, they could be area or locals */
3365 void GameScript::IncrementGlobal(Scriptable
* Sender
, Action
* parameters
)
3367 ieDword value
= CheckVariable( Sender
, parameters
->string0Parameter
);
3368 SetVariable( Sender
, parameters
->string0Parameter
,
3369 value
+ parameters
->int0Parameter
);
3372 /* adding the number to the global ONLY if the first global is zero */
3373 void GameScript::IncrementGlobalOnce(Scriptable
* Sender
, Action
* parameters
)
3375 ieDword value
= CheckVariable( Sender
, parameters
->string0Parameter
);
3379 value
= CheckVariable( Sender
, parameters
->string1Parameter
);
3380 SetVariable( Sender
, parameters
->string1Parameter
,
3381 value
+ parameters
->int0Parameter
);
3384 void GameScript::GlobalSubGlobal(Scriptable
* Sender
, Action
* parameters
)
3386 ieDword value1
= CheckVariable( Sender
,
3387 parameters
->string0Parameter
);
3388 ieDword value2
= CheckVariable( Sender
,
3389 parameters
->string1Parameter
);
3390 SetVariable( Sender
, parameters
->string0Parameter
, value1
- value2
);
3393 void GameScript::GlobalAndGlobal(Scriptable
* Sender
, Action
* parameters
)
3395 ieDword value1
= CheckVariable( Sender
,
3396 parameters
->string0Parameter
);
3397 ieDword value2
= CheckVariable( Sender
,
3398 parameters
->string1Parameter
);
3399 SetVariable( Sender
, parameters
->string0Parameter
, value1
&& value2
);
3402 void GameScript::GlobalOrGlobal(Scriptable
* Sender
, Action
* parameters
)
3404 ieDword value1
= CheckVariable( Sender
,
3405 parameters
->string0Parameter
);
3406 ieDword value2
= CheckVariable( Sender
,
3407 parameters
->string1Parameter
);
3408 SetVariable( Sender
, parameters
->string0Parameter
, value1
|| value2
);
3411 void GameScript::GlobalBOrGlobal(Scriptable
* Sender
, Action
* parameters
)
3413 ieDword value1
= CheckVariable( Sender
,
3414 parameters
->string0Parameter
);
3415 ieDword value2
= CheckVariable( Sender
,
3416 parameters
->string1Parameter
);
3417 SetVariable( Sender
, parameters
->string0Parameter
, value1
| value2
);
3420 void GameScript::GlobalBAndGlobal(Scriptable
* Sender
, Action
* parameters
)
3422 ieDword value1
= CheckVariable( Sender
,
3423 parameters
->string0Parameter
);
3424 ieDword value2
= CheckVariable( Sender
,
3425 parameters
->string1Parameter
);
3426 SetVariable( Sender
, parameters
->string0Parameter
, value1
& value2
);
3429 void GameScript::GlobalXorGlobal(Scriptable
* Sender
, Action
* parameters
)
3431 ieDword value1
= CheckVariable( Sender
,
3432 parameters
->string0Parameter
);
3433 ieDword value2
= CheckVariable( Sender
,
3434 parameters
->string1Parameter
);
3435 SetVariable( Sender
, parameters
->string0Parameter
, value1
^ value2
);
3438 void GameScript::GlobalBOr(Scriptable
* Sender
, Action
* parameters
)
3440 ieDword value1
= CheckVariable( Sender
,
3441 parameters
->string0Parameter
);
3442 SetVariable( Sender
, parameters
->string0Parameter
,
3443 value1
| parameters
->int0Parameter
);
3446 void GameScript::GlobalBAnd(Scriptable
* Sender
, Action
* parameters
)
3448 ieDword value1
= CheckVariable( Sender
,
3449 parameters
->string0Parameter
);
3450 SetVariable( Sender
, parameters
->string0Parameter
,
3451 value1
& parameters
->int0Parameter
);
3454 void GameScript::GlobalXor(Scriptable
* Sender
, Action
* parameters
)
3456 ieDword value1
= CheckVariable( Sender
,
3457 parameters
->string0Parameter
);
3458 SetVariable( Sender
, parameters
->string0Parameter
,
3459 value1
^ parameters
->int0Parameter
);
3462 void GameScript::GlobalMax(Scriptable
* Sender
, Action
* parameters
)
3464 long value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3465 if (value1
> parameters
->int0Parameter
) {
3466 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3470 void GameScript::GlobalMin(Scriptable
* Sender
, Action
* parameters
)
3472 long value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3473 if (value1
< parameters
->int0Parameter
) {
3474 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3478 void GameScript::BitClear(Scriptable
* Sender
, Action
* parameters
)
3480 ieDword value1
= CheckVariable( Sender
,
3481 parameters
->string0Parameter
);
3482 SetVariable( Sender
, parameters
->string0Parameter
,
3483 value1
& ~parameters
->int0Parameter
);
3486 void GameScript::GlobalShL(Scriptable
* Sender
, Action
* parameters
)
3488 ieDword value1
= CheckVariable( Sender
,
3489 parameters
->string0Parameter
);
3490 ieDword value2
= parameters
->int0Parameter
;
3496 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3499 void GameScript::GlobalShR(Scriptable
* Sender
, Action
* parameters
)
3501 ieDword value1
= CheckVariable( Sender
,
3502 parameters
->string0Parameter
);
3503 ieDword value2
= parameters
->int0Parameter
;
3509 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3512 void GameScript::GlobalMaxGlobal(Scriptable
* Sender
, Action
* parameters
)
3514 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3515 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
);
3516 if (value1
< value2
) {
3517 SetVariable( Sender
, parameters
->string0Parameter
, value2
);
3521 void GameScript::GlobalMinGlobal(Scriptable
* Sender
, Action
* parameters
)
3523 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3524 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
);
3525 if (value1
> value2
) {
3526 SetVariable( Sender
, parameters
->string0Parameter
, value2
);
3530 void GameScript::GlobalShLGlobal(Scriptable
* Sender
, Action
* parameters
)
3532 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3533 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
);
3539 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3541 void GameScript::GlobalShRGlobal(Scriptable
* Sender
, Action
* parameters
)
3543 ieDword value1
= CheckVariable( Sender
, parameters
->string0Parameter
);
3544 ieDword value2
= CheckVariable( Sender
, parameters
->string1Parameter
);
3550 SetVariable( Sender
, parameters
->string0Parameter
, value1
);
3553 void GameScript::ClearAllActions(Scriptable
* Sender
, Action
* /*parameters*/)
3555 Actor
*except
= NULL
;
3556 if (Sender
->Type
==ST_ACTOR
) {
3557 except
= (Actor
*) Sender
;
3559 Map
*map
= Sender
->GetCurrentArea();
3560 ieDword gametime
= core
->GetGame()->GameTime
;
3561 int i
= map
->GetActorCount(true);
3563 Actor
* act
= map
->GetActor(i
,true);
3564 if (act
&& act
!=except
) {
3565 if (!act
->ValidTarget(GA_NO_DEAD
) ) {
3568 //Do we need this???
3569 if (!act
->Schedule(gametime
, false) ) {
3572 act
->ClearActions();
3574 act
->SetModal(MS_NONE
);
3579 void GameScript::ClearActions(Scriptable
* Sender
, Action
* parameters
)
3581 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3585 tar
->ClearActions();
3586 if (tar
->Type
==ST_ACTOR
) {
3587 Actor
* act
= (Actor
*) tar
;
3589 //not sure about this
3590 //act->SetModal(MS_NONE);
3594 void GameScript::SetNumTimesTalkedTo(Scriptable
* Sender
, Action
* parameters
)
3596 if (Sender
->Type
!= ST_ACTOR
) {
3599 Actor
* actor
= ( Actor
* ) Sender
;
3600 actor
->TalkCount
= parameters
->int0Parameter
;
3603 void GameScript::StartMovie(Scriptable
* Sender
, Action
* parameters
)
3605 core
->PlayMovie( parameters
->string0Parameter
);
3606 Sender
->ReleaseCurrentAction(); // should this be blocking?
3609 void GameScript::SetLeavePartyDialogFile(Scriptable
* Sender
, Action
* /*parameters*/)
3611 if (Sender
->Type
!= ST_ACTOR
) {
3614 AutoTable
pdtable("pdialog");
3615 Actor
* act
= ( Actor
* ) Sender
;
3616 const char* scriptingname
= act
->GetScriptName();
3617 act
->SetDialog( pdtable
->QueryField( scriptingname
, "POST_DIALOG_FILE" ) );
3620 void GameScript::TextScreen(Scriptable
* Sender
, Action
* parameters
)
3622 strnlwrcpy(core
->GetGame()->LoadMos
, parameters
->string0Parameter
,8);
3623 core
->GetGUIScriptEngine()->RunFunction( "StartTextScreen" );
3624 core
->GetVideoDriver()->SetMouseEnabled(true);
3626 Sender
->ReleaseCurrentAction(); // should this be blocking?
3629 void GameScript::IncrementChapter(Scriptable
* Sender
, Action
* parameters
)
3631 TextScreen(Sender
, parameters
); // textscreen will release blocking for us
3632 core
->GetGame()->IncrementChapter();
3635 void GameScript::SetCriticalPathObject(Scriptable
* Sender
, Action
* parameters
)
3637 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3638 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3641 Actor
* actor
= ( Actor
* ) tar
;
3642 if (parameters
->int0Parameter
) {
3643 actor
->SetMCFlag(MC_PLOT_CRITICAL
, BM_OR
);
3645 actor
->SetMCFlag(MC_PLOT_CRITICAL
, BM_NAND
);
3649 void GameScript::SetBeenInPartyFlags(Scriptable
* Sender
, Action
* /*parameters*/)
3651 if (Sender
->Type
!= ST_ACTOR
) {
3654 Actor
* actor
= ( Actor
* ) Sender
;
3655 //it is bit 15 of the multi-class flags (confirmed)
3656 actor
->SetMCFlag(MC_BEENINPARTY
, BM_OR
);
3659 /*iwd2 sets the high MC bits this way*/
3660 void GameScript::SetCreatureAreaFlag(Scriptable
* Sender
, Action
* parameters
)
3662 if (Sender
->Type
!= ST_ACTOR
) {
3665 Actor
* actor
= ( Actor
* ) Sender
;
3666 actor
->SetMCFlag(parameters
->int0Parameter
, parameters
->int1Parameter
);
3669 //this will be a global change, fixme if it should be local
3670 void GameScript::SetTextColor(Scriptable
* /*Sender*/, Action
* parameters
)
3673 memcpy(&c
,¶meters
->int0Parameter
,4);
3674 core
->SetInfoTextColor(c
);
3677 void GameScript::BitGlobal(Scriptable
* Sender
, Action
* parameters
)
3679 ieDword value
= CheckVariable(Sender
, parameters
->string0Parameter
);
3680 HandleBitMod( value
, parameters
->int0Parameter
, parameters
->int1Parameter
);
3681 SetVariable(Sender
, parameters
->string0Parameter
, value
);
3684 void GameScript::GlobalBitGlobal(Scriptable
* Sender
, Action
* parameters
)
3686 ieDword value1
= CheckVariable(Sender
, parameters
->string0Parameter
);
3687 ieDword value2
= CheckVariable(Sender
, parameters
->string1Parameter
);
3688 HandleBitMod( value1
, value2
, parameters
->int1Parameter
);
3689 SetVariable(Sender
, parameters
->string0Parameter
, value1
);
3692 void GameScript::SetVisualRange(Scriptable
* Sender
, Action
* parameters
)
3694 if (Sender
->Type
!= ST_ACTOR
) {
3697 Actor
* actor
= ( Actor
* ) Sender
;
3698 actor
->SetBase(IE_VISUALRANGE
,parameters
->int0Parameter
);
3701 void GameScript::MakeUnselectable(Scriptable
* Sender
, Action
* parameters
)
3703 Sender
->UnselectableTimer
=parameters
->int0Parameter
;
3706 if (Sender
->Type
!= ST_ACTOR
) {
3709 Actor
* actor
= ( Actor
* ) Sender
;
3710 if (parameters
->int0Parameter
) {
3711 // flags may be wrong
3712 core
->GetGame()->SelectActor(actor
, false, SELECT_QUIET
);
3715 actor
->SetCircleSize();
3718 void GameScript::Debug(Scriptable
* /*Sender*/, Action
* parameters
)
3720 InDebug
=parameters
->int0Parameter
;
3721 printMessage("GameScript",parameters
->string0Parameter
,YELLOW
);
3724 void GameScript::IncrementProficiency(Scriptable
* Sender
, Action
* parameters
)
3726 unsigned int idx
= parameters
->int0Parameter
;
3730 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3734 if (tar
->Type
!= ST_ACTOR
) {
3737 Actor
* target
= ( Actor
* ) tar
;
3738 //start of the proficiency stats
3739 target
->SetBase(IE_PROFICIENCYBASTARDSWORD
+idx
,
3740 target
->GetBase(IE_PROFICIENCYBASTARDSWORD
+idx
)+parameters
->int1Parameter
);
3743 void GameScript::IncrementExtraProficiency(Scriptable
* Sender
, Action
* parameters
)
3745 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3749 if (tar
->Type
!= ST_ACTOR
) {
3752 Actor
* target
= ( Actor
* ) tar
;
3753 target
->SetBase(IE_FREESLOTS
, target
->GetBase(IE_FREESLOTS
)+parameters
->int0Parameter
);
3756 //the third parameter is a GemRB extension
3757 void GameScript::AddJournalEntry(Scriptable
* /*Sender*/, Action
* parameters
)
3759 core
->GetGame()->AddJournalEntry(parameters
->int0Parameter
, parameters
->int1Parameter
, parameters
->int2Parameter
);
3762 void GameScript::SetQuestDone(Scriptable
* /*Sender*/, Action
* parameters
)
3764 Game
*game
= core
->GetGame();
3765 game
->DeleteJournalEntry(parameters
->int0Parameter
);
3766 game
->AddJournalEntry(parameters
->int0Parameter
, IE_GAM_QUEST_DONE
, parameters
->int2Parameter
);
3770 void GameScript::RemoveJournalEntry(Scriptable
* /*Sender*/, Action
* parameters
)
3772 core
->GetGame()->DeleteJournalEntry(parameters
->int0Parameter
);
3775 void GameScript::SetInternal(Scriptable
* Sender
, Action
* parameters
)
3777 unsigned int idx
= parameters
->int0Parameter
;
3781 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3785 if (tar
->Type
!= ST_ACTOR
) {
3788 Actor
* target
= ( Actor
* ) tar
;
3789 //start of the internal stats
3790 target
->SetBase(IE_INTERNAL_0
+idx
, parameters
->int1Parameter
);
3793 void GameScript::IncInternal(Scriptable
* Sender
, Action
* parameters
)
3795 unsigned int idx
= parameters
->int0Parameter
;
3799 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3800 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3803 Actor
* target
= ( Actor
* ) tar
;
3804 //start of the internal stats
3805 target
->SetBase(IE_INTERNAL_0
+idx
,
3806 target
->GetBase(IE_INTERNAL_0
+idx
)+parameters
->int1Parameter
);
3809 void GameScript::DestroyAllEquipment(Scriptable
* Sender
, Action
* /*parameters*/)
3811 Inventory
*inv
=NULL
;
3813 switch (Sender
->Type
) {
3815 inv
= &(((Actor
*) Sender
)->inventory
);
3818 inv
= &(((Container
*) Sender
)->inventory
);
3823 inv
->DestroyItem("",0,(ieDword
) ~0); //destroy any and all
3827 void GameScript::DestroyItem(Scriptable
* Sender
, Action
* parameters
)
3829 Inventory
*inv
=NULL
;
3831 switch (Sender
->Type
) {
3833 inv
= &(((Actor
*) Sender
)->inventory
);
3836 inv
= &(((Container
*) Sender
)->inventory
);
3841 inv
->DestroyItem(parameters
->string0Parameter
,0,1); //destroy one (even indestructible?)
3845 //negative destroygold creates gold
3846 void GameScript::DestroyGold(Scriptable
* Sender
, Action
* parameters
)
3848 if (Sender
->Type
!=ST_ACTOR
)
3850 Actor
*act
=(Actor
*) Sender
;
3851 int max
=(int) act
->GetStat(IE_GOLD
);
3852 if (max
>parameters
->int0Parameter
) {
3853 max
=parameters
->int0Parameter
;
3855 act
->SetBase(IE_GOLD
, act
->GetBase(IE_GOLD
)-max
);
3858 void GameScript::DestroyPartyItem(Scriptable
* /*Sender*/, Action
* parameters
)
3860 Game
*game
= core
->GetGame();
3861 int i
= game
->GetPartySize(false);
3863 if (parameters
->int0Parameter
) {
3869 Inventory
*inv
= &(game
->GetPC( i
,false )->inventory
);
3870 int res
=inv
->DestroyItem(parameters
->string0Parameter
,0,count
);
3871 if ( (count
== 1) && res
) {
3877 /* this is a gemrb extension */
3878 void GameScript::DestroyPartyItemNum(Scriptable
* /*Sender*/, Action
* parameters
)
3880 Game
*game
= core
->GetGame();
3881 int i
= game
->GetPartySize(false);
3883 count
= parameters
->int0Parameter
;
3885 Inventory
*inv
= &(game
->GetPC( i
,false )->inventory
);
3886 count
-= inv
->DestroyItem(parameters
->string0Parameter
,0,count
);
3893 void GameScript::DestroyAllDestructableEquipment(Scriptable
* Sender
, Action
* /*parameters*/)
3895 Inventory
*inv
=NULL
;
3897 switch (Sender
->Type
) {
3899 inv
= &(((Actor
*) Sender
)->inventory
);
3902 inv
= &(((Container
*) Sender
)->inventory
);
3907 inv
->DestroyItem("", IE_INV_ITEM_DESTRUCTIBLE
, (ieDword
) ~0);
3911 void GameScript::SetApparentName(Scriptable
* Sender
, Action
* parameters
)
3913 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3914 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3917 Actor
* target
= ( Actor
* ) tar
;
3918 target
->SetName(parameters
->int0Parameter
,1);
3921 void GameScript::SetRegularName(Scriptable
* Sender
, Action
* parameters
)
3923 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3924 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3927 Actor
* target
= ( Actor
* ) tar
;
3928 target
->SetName(parameters
->int0Parameter
,2);
3931 /** this is a gemrb extension */
3932 void GameScript::UnloadArea(Scriptable
* /*Sender*/, Action
* parameters
)
3934 int map
=core
->GetGame()->FindMap(parameters
->string0Parameter
);
3936 core
->GetGame()->DelMap(map
, parameters
->int0Parameter
);
3940 void GameScript::Kill(Scriptable
* Sender
, Action
* parameters
)
3942 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3943 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3946 Actor
* target
= ( Actor
* ) tar
;
3947 target
->SetBase(IE_HITPOINTS
,(ieDword
) -100);
3950 void GameScript::SetGabber(Scriptable
* Sender
, Action
* parameters
)
3952 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3953 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3956 GameControl
* gc
= core
->GetGameControl();
3957 if (gc
->GetDialogueFlags()&DF_IN_DIALOG
) {
3958 gc
->speakerID
= ((Actor
*) tar
)->globalID
;
3960 printMessage("GameScript","Can't set gabber!",YELLOW
);
3964 void GameScript::ReputationSet(Scriptable
* /*Sender*/, Action
* parameters
)
3966 core
->GetGame()->SetReputation(parameters
->int0Parameter
*10);
3969 void GameScript::ReputationInc(Scriptable
* /*Sender*/, Action
* parameters
)
3971 Game
*game
= core
->GetGame();
3972 game
->SetReputation( (int) game
->Reputation
+ parameters
->int0Parameter
*10);
3975 void GameScript::FullHeal(Scriptable
* Sender
, Action
* parameters
)
3977 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
3978 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
3981 Actor
*scr
= (Actor
*) tar
;
3982 //0 means full healing
3983 //Heal() might contain curing of some conditions
3984 //if FullHeal doesn't do that, replace this with a SetBase
3985 //fullhealex might still be the curing action
3989 void GameScript::RemovePaladinHood(Scriptable
* Sender
, Action
* /*parameters*/)
3991 if (Sender
->Type
!=ST_ACTOR
) {
3994 Actor
*act
= (Actor
*) Sender
;
3995 act
->SetMCFlag(MC_FALLEN_PALADIN
, BM_OR
);
3998 void GameScript::RemoveRangerHood(Scriptable
* Sender
, Action
* /*parameters*/)
4000 if (Sender
->Type
!=ST_ACTOR
) {
4003 Actor
*act
= (Actor
*) Sender
;
4004 act
->SetMCFlag(MC_FALLEN_RANGER
, BM_OR
);
4007 void GameScript::RegainPaladinHood(Scriptable
* Sender
, Action
* /*parameters*/)
4009 if (Sender
->Type
!=ST_ACTOR
) {
4012 Actor
*act
= (Actor
*) Sender
;
4013 act
->SetMCFlag(MC_FALLEN_PALADIN
, BM_NAND
);
4016 void GameScript::RegainRangerHood(Scriptable
* Sender
, Action
* /*parameters*/)
4018 if (Sender
->Type
!=ST_ACTOR
) {
4021 Actor
*act
= (Actor
*) Sender
;
4022 act
->SetMCFlag(MC_FALLEN_RANGER
, BM_NAND
);
4025 //transfering item from Sender to target, target must be an actor
4026 //if target can't get it, it will be dropped at its feet
4027 //a container or an actor can take an item from someone
4028 void GameScript::GetItem(Scriptable
* Sender
, Action
* parameters
)
4030 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4031 MoveItemCore(tar
, Sender
, parameters
->string0Parameter
,0,0);
4034 //getting one single item
4035 void GameScript::TakePartyItem(Scriptable
* Sender
, Action
* parameters
)
4037 Game
*game
=core
->GetGame();
4038 int i
=game
->GetPartySize(false);
4040 int res
=MoveItemCore(game
->GetPC(i
,false), Sender
, parameters
->string0Parameter
,0,IE_INV_ITEM_UNSTEALABLE
);
4041 if (res
!=MIC_NOITEM
) return;
4045 //getting x single item
4046 void GameScript::TakePartyItemNum(Scriptable
* Sender
, Action
* parameters
)
4048 int count
= parameters
->int0Parameter
;
4049 Game
*game
=core
->GetGame();
4050 int i
=game
->GetPartySize(false);
4052 int res
=MoveItemCore(game
->GetPC(i
,false), Sender
, parameters
->string0Parameter
,0, IE_INV_ITEM_UNSTEALABLE
);
4053 if (res
== MIC_GOTITEM
) {
4061 void GameScript::TakePartyItemRange(Scriptable
* Sender
, Action
* parameters
)
4063 Game
*game
=core
->GetGame();
4064 int i
=game
->GetPartySize(false);
4066 Actor
*ac
= game
->GetPC(i
,false);
4067 if (Distance(Sender
, ac
)<MAX_OPERATING_DISTANCE
) {
4068 while (MoveItemCore(ac
, Sender
, parameters
->string0Parameter
,0,IE_INV_ITEM_UNSTEALABLE
)==MIC_GOTITEM
) { }
4073 void GameScript::TakePartyItemAll(Scriptable
* Sender
, Action
* parameters
)
4075 Game
*game
=core
->GetGame();
4076 int i
=game
->GetPartySize(false);
4078 while (MoveItemCore(game
->GetPC(i
,false), Sender
, parameters
->string0Parameter
,0, IE_INV_ITEM_UNSTEALABLE
)==MIC_GOTITEM
) { }
4082 //an actor can 'give' an item to a container or another actor
4083 void GameScript::GiveItem(Scriptable
*Sender
, Action
* parameters
)
4085 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4086 MoveItemCore(Sender
, tar
, parameters
->string0Parameter
,0,0);
4089 //this action creates an item in a container or a creature
4090 //if there is an object it works as GiveItemCreate
4091 //otherwise it creates the item on the Sender
4092 void GameScript::CreateItem(Scriptable
*Sender
, Action
* parameters
)
4095 if (parameters
->objects
[1]) {
4096 tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4106 myinv
= &((Actor
*) tar
)->inventory
;
4109 myinv
= &((Container
*) tar
)->inventory
;
4115 CREItem
*item
= new CREItem();
4116 CreateItemCore(item
, parameters
->string0Parameter
, parameters
->int0Parameter
, parameters
->int1Parameter
, parameters
->int2Parameter
);
4117 if (tar
->Type
==ST_CONTAINER
) {
4118 myinv
->AddItem(item
);
4120 if ( ASI_SUCCESS
!= myinv
->AddSlotItem(item
, SLOT_ONLYINVENTORY
)) {
4121 Map
*map
=tar
->GetCurrentArea();
4122 // drop it at my feet
4123 map
->AddItemToLocation(tar
->Pos
, item
);
4124 if (((Actor
*)tar
)->InParty
) core
->DisplayConstantString(STR_INVFULL_ITEMDROP
, 0xbcefbc);
4126 if (((Actor
*)tar
)->InParty
) core
->DisplayConstantString(STR_GOTITEM
, 0xbcefbc);
4131 void GameScript::CreateItemNumGlobal(Scriptable
*Sender
, Action
* parameters
)
4135 switch(Sender
->Type
) {
4137 myinv
= &((Actor
*) Sender
)->inventory
;
4140 myinv
= &((Container
*) Sender
)->inventory
;
4145 int value
= CheckVariable( Sender
, parameters
->string0Parameter
);
4146 CREItem
*item
= new CREItem();
4147 CreateItemCore(item
, parameters
->string1Parameter
, value
, 0, 0);
4148 if (Sender
->Type
==ST_CONTAINER
) {
4149 myinv
->AddItem(item
);
4151 if ( ASI_SUCCESS
!= myinv
->AddSlotItem(item
, SLOT_ONLYINVENTORY
)) {
4152 Map
*map
=Sender
->GetCurrentArea();
4153 // drop it at my feet
4154 map
->AddItemToLocation(Sender
->Pos
, item
);
4155 if (((Actor
*)Sender
)->InParty
) core
->DisplayConstantString(STR_INVFULL_ITEMDROP
, 0xbcefbc);
4157 if (((Actor
*)Sender
)->InParty
) core
->DisplayConstantString(STR_GOTITEM
, 0xbcefbc);
4162 void GameScript::TakeItemReplace(Scriptable
*Sender
, Action
* parameters
)
4164 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4165 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
4169 Actor
*scr
= (Actor
*) tar
;
4171 int slot
= scr
->inventory
.RemoveItem(parameters
->string1Parameter
, 0, &item
);
4173 item
= new CREItem();
4175 CreateItemCore(item
, parameters
->string0Parameter
, -1, 0, 0);
4176 if (ASI_SUCCESS
!= scr
->inventory
.AddSlotItem(item
,slot
)) {
4177 Map
*map
= scr
->GetCurrentArea();
4178 map
->AddItemToLocation(Sender
->Pos
, item
);
4182 //same as equipitem, but with additional slots parameter, and object to perform action
4183 void GameScript::XEquipItem(Scriptable
*Sender
, Action
* parameters
)
4185 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4187 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4190 Actor
*actor
= (Actor
*) tar
;
4191 int slot
= actor
->inventory
.FindItem(parameters
->string0Parameter
, 0);
4195 actor
->inventory
.EquipItem(slot
);
4196 actor
->ReinitQuickSlots();
4199 //iwd2 also has a flag for unequip (it might collide with original!)
4200 void GameScript::EquipItem(Scriptable
*Sender
, Action
* parameters
)
4202 if (Sender
->Type
!=ST_ACTOR
) {
4205 Actor
*actor
= (Actor
*) Sender
;
4206 int slot
= actor
->inventory
.FindItem(parameters
->string0Parameter
, IE_INV_ITEM_UNDROPPABLE
);
4213 if (parameters
->int0Parameter
) {
4214 //unequip item, and move it to the inventory
4215 slot2
= SLOT_ONLYINVENTORY
;
4217 //equip item if possible
4218 slot2
= SLOT_AUTOEQUIP
;
4220 CREItem
*si
= actor
->inventory
.RemoveItem(slot
);
4222 if (actor
->inventory
.AddSlotItem(si
, slot2
)==ASI_FAILED
) {
4223 Map
*map
= Sender
->GetCurrentArea();
4225 //drop item at the feet of the character instead of destroying it
4226 map
->AddItemToLocation(Sender
->Pos
, si
);
4232 actor
->ReinitQuickSlots();
4235 void GameScript::DropItem(Scriptable
*Sender
, Action
* parameters
)
4237 if (Sender
->Type
!=ST_ACTOR
) {
4238 Sender
->ReleaseCurrentAction();
4241 if (Distance(parameters
->pointParameter
, Sender
) > 10) {
4242 MoveNearerTo(Sender
, parameters
->pointParameter
, 10,0);
4245 Actor
*scr
= (Actor
*) Sender
;
4246 Map
*map
= Sender
->GetCurrentArea();
4248 if (parameters
->string0Parameter
[0]) {
4249 //dropping location isn't exactly our place, this is why i didn't use a simple DropItem
4250 scr
->inventory
.DropItemAtLocation(parameters
->string0Parameter
,
4251 0, map
, parameters
->pointParameter
);
4253 //this should be converted from scripting slot to physical slot
4254 scr
->inventory
.DropItemAtLocation(parameters
->int0Parameter
, 0, map
, parameters
->pointParameter
);
4257 Sender
->ReleaseCurrentAction();
4260 void GameScript::DropInventory(Scriptable
*Sender
, Action
* /*parameters*/)
4262 if (Sender
->Type
!=ST_ACTOR
) {
4265 Actor
*scr
= (Actor
*) Sender
;
4266 scr
->DropItem("",0);
4269 //this should work on containers!
4270 //using the same code for DropInventoryEXExclude
4271 void GameScript::DropInventoryEX(Scriptable
*Sender
, Action
* parameters
)
4273 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4277 Inventory
*inv
= NULL
;
4278 switch (Sender
->Type
) {
4280 inv
= &(((Actor
*) tar
)->inventory
);
4283 inv
= &(((Container
*) tar
)->inventory
);
4288 int x
= inv
->GetSlotCount();
4289 Map
*area
= tar
->GetCurrentArea();
4291 if (parameters
->string0Parameter
[0]) {
4292 const char *resref
= inv
->GetSlotItem(x
)->ItemResRef
;
4293 if (!strnicmp(parameters
->string0Parameter
, resref
, 8)) {
4297 inv
->DropItemAtLocation(x
, 0, area
, tar
->Pos
);
4302 void GameScript::GivePartyAllEquipment(Scriptable
*Sender
, Action
* /*parameters*/)
4304 if (Sender
->Type
!=ST_ACTOR
) {
4307 Game
*game
= core
->GetGame();
4308 // pick the first actor first
4309 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
4310 Actor
*tar
= game
->GetPC(i
,false);
4311 //don't try to give self, it would be an infinite loop
4312 if (tar
==(Actor
*) Sender
)
4314 while(MoveItemCore(Sender
, tar
, "",0,0)!=MIC_NOITEM
) { }
4318 //This is unsure, Plunder could be just handling ground piles and not dead actors
4319 void GameScript::Plunder(Scriptable
*Sender
, Action
* parameters
)
4321 if (Sender
->Type
!=ST_ACTOR
) {
4322 Sender
->ReleaseCurrentAction();
4325 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
4327 Sender
->ReleaseCurrentAction();
4331 //you must be joking
4333 Sender
->ReleaseCurrentAction();
4337 if (tar
->Type
== ST_ACTOR
) {
4338 Actor
*scr
= (Actor
*) tar
;
4339 //can plunder only dead actors
4340 if (! (scr
->BaseStats
[IE_STATE_ID
]&STATE_DEAD
) ) {
4341 Sender
->ReleaseCurrentAction();
4345 if (PersonalDistance(Sender
, tar
)>MAX_OPERATING_DISTANCE
) {
4346 MoveNearerTo(Sender
, tar
->Pos
, MAX_OPERATING_DISTANCE
,0);
4349 //move all movable item from the target to the Sender
4350 //the rest will be dropped at the feet of Sender
4351 while(MoveItemCore(tar
, Sender
, "",0,0)!=MIC_NOITEM
) { }
4352 Sender
->ReleaseCurrentAction();
4355 void GameScript::MoveInventory(Scriptable
*Sender
, Action
* parameters
)
4357 Scriptable
* src
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4358 if (!src
|| src
->Type
!=ST_ACTOR
) {
4361 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[2] );
4362 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4365 //don't try to move to self, it would create infinite loop
4368 //move all movable item from the target to the Sender
4369 //the rest will be dropped at the feet of Sender
4370 while(MoveItemCore(src
, tar
, "",0,0)!=MIC_NOITEM
) { }
4373 void GameScript::PickPockets(Scriptable
*Sender
, Action
* parameters
)
4375 if (Sender
->Type
!=ST_ACTOR
) {
4376 Sender
->ReleaseCurrentAction();
4379 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
4380 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4381 Sender
->ReleaseCurrentAction();
4384 Actor
*snd
= (Actor
*) Sender
;
4385 Actor
*scr
= (Actor
*) tar
;
4386 //for PP one must go REALLY close
4388 if (PersonalDistance(Sender
, tar
)>10 ) {
4389 MoveNearerTo(Sender
, tar
, 10);
4393 if (scr
->LastTarget
) {
4394 core
->DisplayConstantString(STR_PICKPOCKET_EVIL
,0xffffff);
4395 Sender
->ReleaseCurrentAction();
4399 int skill
= snd
->GetStat(IE_PICKPOCKET
) - scr
->GetStat(IE_PICKPOCKET
);
4400 skill
+=core
->Roll(1,100,1);
4403 core
->DisplayConstantString(STR_PICKPOCKET_FAIL
,0xffffff);
4404 tar
->LastOpenFailed
=snd
->GetID();
4405 Sender
->ReleaseCurrentAction();
4409 //find a candidate item for stealing (unstealable items are noticed)
4410 int ret
= MoveItemCore(tar
, Sender
, "", IE_INV_ITEM_UNSTEALABLE
, IE_INV_ITEM_STOLEN
);
4411 if (ret
==MIC_NOITEM
) {
4414 if (scr
->GetStat(IE_GOLD
)>0) {
4415 money
=RandomNumValue
%(scr
->GetStat(IE_GOLD
)+1);
4419 core
->DisplayConstantString(STR_PICKPOCKET_NONE
,0xffffff);
4420 Sender
->ReleaseCurrentAction();
4423 CREItem
*item
= new CREItem();
4424 CreateItemCore(item
, core
->GoldResRef
, money
, 0, 0);
4425 if ( ASI_SUCCESS
== snd
->inventory
.AddSlotItem(item
, SLOT_ONLYINVENTORY
)) {
4426 scr
->SetBase(IE_GOLD
,scr
->GetBase(IE_GOLD
)-money
);
4428 Map
*map
=Sender
->GetCurrentArea();
4429 // drop it at my feet
4430 map
->AddItemToLocation(Sender
->Pos
, item
);
4431 if (((Actor
*)Sender
)->InParty
) core
->DisplayConstantString(STR_INVFULL_ITEMDROP
, 0xbcefbc);
4432 Sender
->ReleaseCurrentAction();
4437 core
->DisplayConstantString(STR_PICKPOCKET_DONE
,0xffffff);
4438 DisplayStringCore(snd
, VB_PP_SUCC
, DS_CONSOLE
|DS_CONST
);
4439 Sender
->ReleaseCurrentAction();
4442 void GameScript::TakeItemList(Scriptable
* Sender
, Action
* parameters
)
4444 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4445 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4448 AutoTable
tab(parameters
->string0Parameter
);
4453 int rows
= tab
->GetRowCount();
4454 for (int i
=0;i
<rows
;i
++) {
4455 MoveItemCore(tar
, Sender
, tab
->QueryField(i
,0), 0, IE_INV_ITEM_UNSTEALABLE
);
4459 void GameScript::TakeItemListParty(Scriptable
* Sender
, Action
* parameters
)
4461 AutoTable
tab(parameters
->string0Parameter
);
4465 Game
*game
= core
->GetGame();
4466 int rows
= tab
->GetRowCount();
4467 for (int i
=0;i
<rows
;i
++) {
4468 int j
= game
->GetPartySize(false);
4470 Actor
*tar
= game
->GetPC(j
, false);
4471 MoveItemCore(tar
, Sender
, tab
->QueryField(i
,0), 0, IE_INV_ITEM_UNSTEALABLE
);
4476 void GameScript::TakeItemListPartyNum(Scriptable
* Sender
, Action
* parameters
)
4478 AutoTable
tab(parameters
->string0Parameter
);
4482 Game
*game
= core
->GetGame();
4483 int rows
= tab
->GetRowCount();
4484 for (int i
=0;i
<rows
;i
++) {
4485 int count
= parameters
->int0Parameter
;
4486 int j
= game
->GetPartySize(false);
4488 Actor
*tar
= game
->GetPC(j
, false);
4489 int res
=MoveItemCore(tar
, Sender
, tab
->QueryField(i
,0), 0, IE_INV_ITEM_UNSTEALABLE
);
4490 if (res
==MIC_GOTITEM
) {
4500 void GameScript::SetRestEncounterProbabilityDay(Scriptable
* Sender
, Action
* parameters
)
4502 Map
*map
=Sender
->GetCurrentArea();
4503 map
->RestHeader
.DayChance
= (ieWord
) parameters
->int0Parameter
;
4506 void GameScript::SetRestEncounterProbabilityNight(Scriptable
* Sender
, Action
* parameters
)
4508 Map
*map
=Sender
->GetCurrentArea();
4509 map
->RestHeader
.NightChance
= (ieWord
) parameters
->int0Parameter
;
4513 void GameScript::SetRestEncounterChance(Scriptable
* Sender
, Action
* parameters
)
4515 Map
*map
=Sender
->GetCurrentArea();
4516 map
->RestHeader
.DayChance
= (ieWord
) parameters
->int0Parameter
;
4517 map
->RestHeader
.NightChance
= (ieWord
) parameters
->int1Parameter
;
4520 //easily hardcoded end sequence
4521 void GameScript::EndCredits(Scriptable
* /*Sender*/, Action
* /*parameters*/)
4523 core
->PlayMovie("credits");
4526 //easily hardcoded end sequence
4527 void GameScript::ExpansionEndCredits(Scriptable
* /*Sender*/, Action
* /*parameters*/)
4529 core
->PlayMovie("ecredit");
4532 //always quits game, but based on game it can play end animation, or display
4535 //QuitGame (play two of 3 movies in PST, display death screen with strref)
4536 //EndGame (display death screen with strref)
4537 void GameScript::QuitGame(Scriptable
* Sender
, Action
* parameters
)
4539 ClearAllActions(Sender
, parameters
);
4540 core
->GetDictionary()->SetAt("QuitGame1", (ieDword
) parameters
->int0Parameter
);
4541 core
->GetDictionary()->SetAt("QuitGame2", (ieDword
) parameters
->int1Parameter
);
4542 core
->GetDictionary()->SetAt("QuitGame3", (ieDword
) parameters
->int2Parameter
);
4543 core
->SetNextScript("QuitGame");
4546 void GameScript::StopMoving(Scriptable
* Sender
, Action
* /*parameters*/)
4548 if (Sender
->Type
!=ST_ACTOR
) {
4551 Actor
*actor
= (Actor
*) Sender
;
4555 void GameScript::ApplyDamage(Scriptable
* Sender
, Action
* parameters
)
4559 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4560 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4563 damagee
= (Actor
*) tar
;
4564 if (Sender
->Type
==ST_ACTOR
) {
4565 damager
=(Actor
*) Sender
;
4569 damagee
->Damage(parameters
->int0Parameter
, parameters
->int1Parameter
, damager
);
4572 void GameScript::ApplyDamagePercent(Scriptable
* Sender
, Action
* parameters
)
4576 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4577 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4580 damagee
= (Actor
*) tar
;
4581 if (Sender
->Type
==ST_ACTOR
) {
4582 damager
=(Actor
*) Sender
;
4586 damagee
->Damage(damagee
->GetBase(IE_HITPOINTS
)*parameters
->int0Parameter
/100, parameters
->int1Parameter
, damager
);
4589 void GameScript::Damage(Scriptable
* Sender
, Action
* parameters
)
4593 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4594 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
4597 damagee
= (Actor
*) tar
;
4598 if (Sender
->Type
==ST_ACTOR
) {
4599 damager
=(Actor
*) Sender
;
4603 int damage
= damagee
->LuckyRoll( (parameters
->int1Parameter
>>12)&15, (parameters
->int1Parameter
>>4)&255, parameters
->int1Parameter
&15, 0, 1, damager
);
4604 int type
=MOD_ADDITIVE
;
4605 switch(parameters
->int0Parameter
) {
4616 damagee
->Damage( damage
, type
, damager
);
4619 void GameScript::SetHomeLocation(Scriptable* Sender, Action* parameters)
4621 Scriptable* tar = GetActorFromObject( Sender, parameters->objects[1] );
4622 if (!tar || tar->Type!=ST_ACTOR) {
4625 Movable *movable = (Movable *) tar; //not actor, though it is the only moveable
4626 movable->Destination = parameters->pointParameter;
4627 //no movement should be started here, i think
4631 void GameScript::SetMasterArea(Scriptable
* /*Sender*/, Action
* parameters
)
4633 core
->GetGame()->SetMasterArea(parameters
->string0Parameter
);
4636 void GameScript::Berserk(Scriptable
* Sender
, Action
* /*parameters*/)
4638 if (Sender
->Type
!=ST_ACTOR
) {
4641 Actor
*act
= (Actor
*) Sender
;
4642 act
->SetBaseBit(IE_STATE_ID
, STATE_BERSERK
, true);
4645 void GameScript::Panic(Scriptable
* Sender
, Action
* /*parameters*/)
4647 if (Sender
->Type
!=ST_ACTOR
) {
4650 Actor
*act
= (Actor
*) Sender
;
4654 /* as of now: removes panic and berserk */
4655 void GameScript::Calm(Scriptable
* Sender
, Action
* /*parameters*/)
4657 if (Sender
->Type
!=ST_ACTOR
) {
4660 Actor
*act
= (Actor
*) Sender
;
4661 act
->SetBaseBit(IE_STATE_ID
, STATE_BERSERK
|STATE_PANIC
, false);
4664 void GameScript::RevealAreaOnMap(Scriptable
* /*Sender*/, Action
* parameters
)
4666 WorldMap
*worldmap
= core
->GetWorldMap();
4668 printf("Can't find worldmap!\n");
4671 // WMP_ENTRY_ADJACENT because otherwise revealed bg2 areas are unreachable from city gates
4672 worldmap
->SetAreaStatus(parameters
->string0Parameter
, WMP_ENTRY_VISIBLE
|WMP_ENTRY_ADJACENT
, BM_OR
);
4673 core
->DisplayConstantString(STR_WORLDMAPCHANGE
, 0xc8ffc8);
4676 void GameScript::HideAreaOnMap( Scriptable
* /*Sender*/, Action
* parameters
)
4678 WorldMap
*worldmap
= core
->GetWorldMap();
4680 printf("Can't find worldmap!\n");
4683 // WMP_ENTRY_ADJACENT because otherwise revealed bg2 areas are unreachable from city gates
4684 worldmap
->SetAreaStatus(parameters
->string0Parameter
, WMP_ENTRY_VISIBLE
|WMP_ENTRY_ADJACENT
, BM_NAND
);
4687 void GameScript::SendTrigger(Scriptable
* Sender
, Action
* parameters
)
4689 Scriptable
*tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4693 tar
->TriggerID
=parameters
->int0Parameter
;
4696 void GameScript::Shout( Scriptable
* Sender
, Action
* parameters
)
4698 if (Sender
->Type
!=ST_ACTOR
) {
4701 //according to IESDP silenced creatures cannot use shout
4702 Actor
*actor
= (Actor
*) Sender
;
4703 if (actor
->GetStat( IE_STATE_ID
) & STATE_SILENCED
) {
4706 Map
*map
=Sender
->GetCurrentArea();
4707 //max. shouting distance, please adjust it if you know better
4708 map
->Shout(actor
, parameters
->int0Parameter
, MAX_TRAVELING_DISTANCE
);
4711 void GameScript::GlobalShout( Scriptable
* Sender
, Action
* parameters
)
4713 if (Sender
->Type
!=ST_ACTOR
) {
4716 //according to IESDP silenced creatures cannot use shout
4717 Actor
*actor
= (Actor
*) Sender
;
4718 if (actor
->GetStat( IE_STATE_ID
) & STATE_SILENCED
) {
4721 Map
*map
=Sender
->GetCurrentArea();
4722 // 0 means unlimited shout distance
4723 map
->Shout(actor
, parameters
->int0Parameter
, 0);
4726 void GameScript::Help( Scriptable
* Sender
, Action
* /*parameters*/)
4728 if (Sender
->Type
!=ST_ACTOR
) {
4731 Map
*map
=Sender
->GetCurrentArea();
4732 map
->Shout((Actor
*) Sender
, 0, 40);
4735 void GameScript::GiveOrder(Scriptable
* Sender
, Action
* parameters
)
4737 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
4739 tar
->LastOrderer
= Sender
->GetGlobalID();
4740 tar
->LastOrder
= parameters
->int0Parameter
;
4744 void GameScript::AddMapnote( Scriptable
* Sender
, Action
* parameters
)
4746 Map
*map
=Sender
->GetCurrentArea();
4747 char *str
= core
->GetString( parameters
->int0Parameter
, 0);
4748 map
->AddMapNote(parameters
->pointParameter
, parameters
->int1Parameter
, str
, parameters
->int0Parameter
);
4751 void GameScript::RemoveMapnote( Scriptable
* Sender
, Action
* parameters
)
4753 Map
*map
=Sender
->GetCurrentArea();
4754 map
->RemoveMapNote(parameters
->pointParameter
);
4757 void GameScript::AttackOneRound( Scriptable
* Sender
, Action
* parameters
)
4759 if (Sender
->Type
!= ST_ACTOR
) {
4760 Sender
->ReleaseCurrentAction();
4763 //using auto target!
4765 if (!parameters
->objects
[1]) {
4766 GameControl
*gc
= core
->GetGameControl();
4767 tar
= gc
->GetTarget();
4769 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4771 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4772 Sender
->ReleaseCurrentAction();
4776 //actor is already incapable of attack
4777 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4778 Sender
->ReleaseCurrentAction();
4782 if (!Sender
->CurrentActionState
) {
4783 Sender
->CurrentActionState
= ROUND_SIZE
;
4786 AttackCore(Sender
, tar
, 0);
4788 if (Sender
->CurrentActionState
== 1) {
4789 //this is the LastDisarmFailed field, but this is an actor
4790 //Sender->LastTarget = 0;
4791 Sender
->ReleaseCurrentAction();
4793 Sender
->CurrentActionState
--;
4797 void GameScript::RunningAttackNoSound( Scriptable
* Sender
, Action
* parameters
)
4799 if (Sender
->Type
!= ST_ACTOR
) {
4800 Sender
->ReleaseCurrentAction();
4803 //using auto target!
4805 if (!parameters
->objects
[1]) {
4806 GameControl
*gc
= core
->GetGameControl();
4807 tar
= gc
->GetTarget();
4809 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4811 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4812 Sender
->ReleaseCurrentAction();
4816 //actor is already incapable of attack
4817 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4818 Sender
->ReleaseCurrentAction();
4822 AttackCore(Sender
, tar
, AC_NO_SOUND
|AC_RUNNING
);
4825 void GameScript::AttackNoSound( Scriptable
* Sender
, Action
* parameters
)
4827 if (Sender
->Type
!= ST_ACTOR
) {
4828 Sender
->ReleaseCurrentAction();
4831 //using auto target!
4833 if (!parameters
->objects
[1]) {
4834 GameControl
*gc
= core
->GetGameControl();
4835 tar
= gc
->GetTarget();
4837 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4839 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4840 Sender
->ReleaseCurrentAction();
4844 //actor is already incapable of attack
4845 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4846 Sender
->ReleaseCurrentAction();
4850 AttackCore(Sender
, tar
, AC_NO_SOUND
);
4853 void GameScript::RunningAttack( Scriptable
* Sender
, Action
* parameters
)
4855 if (Sender
->Type
!= ST_ACTOR
) {
4856 Sender
->ReleaseCurrentAction();
4859 //using auto target!
4861 if (!parameters
->objects
[1]) {
4862 GameControl
*gc
= core
->GetGameControl();
4863 tar
= gc
->GetTarget();
4865 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4867 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4868 Sender
->ReleaseCurrentAction();
4872 //actor is already incapable of attack
4873 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4874 Sender
->ReleaseCurrentAction();
4878 AttackCore(Sender
, tar
, AC_RUNNING
);
4881 void GameScript::Attack( Scriptable
* Sender
, Action
* parameters
)
4883 if (Sender
->Type
!= ST_ACTOR
) {
4884 Sender
->ReleaseCurrentAction();
4887 //using auto target!
4889 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4891 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) || tar
== Sender
) {
4892 Sender
->ReleaseCurrentAction();
4896 //actor is already incapable of attack
4897 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4898 Sender
->ReleaseCurrentAction();
4902 AttackCore(Sender
, tar
, 0);
4905 void GameScript::ForceAttack( Scriptable
* Sender
, Action
* parameters
)
4907 Scriptable
* scr
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4908 if (!scr
|| scr
->Type
!= ST_ACTOR
) {
4911 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[2], GA_NO_DEAD
);
4912 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4915 //this is a hack, we use a gui variable for our own hideous reasons?
4916 if (tar
->Type
==ST_ACTOR
) {
4917 GameControl
*gc
= core
->GetGameControl();
4919 //saving the target object ID from the gui variable
4921 strncpy(Tmp
,"NIDSpecial3()",sizeof(Tmp
) );
4922 scr
->AddAction( GenerateActionDirect(Tmp
, (Actor
*) tar
) );
4926 snprintf(Tmp
, sizeof(Tmp
), "BashDoor(%s)", tar
->GetScriptName());
4927 scr
->AddAction ( GenerateAction(Tmp
) );
4931 void GameScript::AttackReevaluate( Scriptable
* Sender
, Action
* parameters
)
4933 if (Sender
->Type
!= ST_ACTOR
) {
4934 Sender
->ReleaseCurrentAction();
4938 if (!Sender
->CurrentActionState
) {
4939 Sender
->CurrentActionState
= parameters
->int0Parameter
;
4940 // TODO: reevaluate target (set CurrentActionTarget to 0) if we are not actively in combat
4944 tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
4945 if (!tar
|| (tar
->Type
!= ST_ACTOR
&& tar
->Type
!=ST_DOOR
&& tar
->Type
!=ST_CONTAINER
) ) {
4946 Sender
->ReleaseCurrentAction();
4950 //actor is already incapable of attack
4951 if (Sender
->GetInternalFlag()&IF_STOPATTACK
) {
4952 Sender
->ReleaseCurrentAction();
4956 AttackCore(Sender
, tar
, 0);
4958 Sender
->CurrentActionState
--;
4961 void GameScript::Explore( Scriptable
* Sender
, Action
* /*parameters*/)
4963 Sender
->GetCurrentArea( )->Explore(-1);
4966 void GameScript::UndoExplore( Scriptable
* Sender
, Action
* /*parameters*/)
4968 Sender
->GetCurrentArea( )->Explore(0);
4971 void GameScript::ExploreMapChunk( Scriptable
* Sender
, Action
* parameters
)
4973 Map
*map
= Sender
->GetCurrentArea();
4975 There is a mode flag in int1Parameter, but i don't know what is it,
4976 our implementation uses it for LOS=1, or no LOS=0
4977 ExploreMapChunk will reveal both visibility/explored map, but the
4978 visibility will fade in the next update cycle (which is quite frequent)
4980 map
->ExploreMapChunk(parameters
->pointParameter
, parameters
->int0Parameter
, parameters
->int1Parameter
);
4983 void GameScript::StartStore( Scriptable
* Sender
, Action
* parameters
)
4985 if (core
->GetCurrentStore() ) {
4988 core
->SetCurrentStore( parameters
->string0Parameter
, Sender
->GetScriptName());
4989 //core->GetGUIScriptEngine()->RunFunction( "OpenStoreWindow" );
4990 core
->SetEventFlag(EF_OPENSTORE
);
4991 //sorry, i have absolutely no idea when i should do this :)
4992 Sender
->ReleaseCurrentAction();
4995 //The integer parameter is a GemRB extension, if set to 1, the player
4996 //gains experience for learning the spell
4997 void GameScript::AddSpecialAbility( Scriptable
* Sender
, Action
* parameters
)
4999 if (Sender
->Type
!= ST_ACTOR
) {
5002 Actor
*actor
= (Actor
*) Sender
;
5003 actor
->LearnSpell (parameters
->string0Parameter
, parameters
->int0Parameter
|LS_MEMO
|LS_LEARN
);
5004 core
->SetEventFlag(EF_ACTION
);
5007 void GameScript::RemoveSpell( Scriptable
* Sender
, Action
* parameters
)
5009 if (Sender
->Type
!=ST_ACTOR
) {
5012 Actor
*actor
= (Actor
*) Sender
;
5013 if (parameters
->string0Parameter
[0]) {
5014 actor
->spellbook
.RemoveSpell(parameters
->string0Parameter
);
5017 actor
->spellbook
.RemoveSpell(parameters
->int0Parameter
);
5020 void GameScript::SetScriptName( Scriptable
* Sender
, Action
* parameters
)
5022 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5023 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5026 tar
->SetScriptName(parameters
->string0Parameter
);
5030 //advance time with a constant
5031 //This is in seconds according to IESDP
5032 void GameScript::AdvanceTime(Scriptable
* /*Sender*/, Action
* parameters
)
5034 core
->GetGame()->AdvanceTime(parameters
->int0Parameter
*1000/AI_UPDATE_TIME
);
5037 //advance at least one day, then stop at next day/dusk/night/morning
5038 //oops, not TimeODay is used but Time (this means we got hours)
5039 //i'm not sure if we should add a whole day either, needs more research
5040 void GameScript::DayNight(Scriptable
* /*Sender*/, Action
* parameters
)
5042 // first, calculate the current number of hours.
5043 int padding
= ((core
->GetGame()->GameTime
/ AI_UPDATE_TIME
) % 7200) / 300;
5044 // then, calculate the offset (in hours) required to take us to the desired hour.
5045 padding
= (24 + parameters
->int0Parameter
- padding
) % 24;
5046 // then, advance one day (7200), plus the desired number of hours.
5047 core
->GetGame()->AdvanceTime(AI_UPDATE_TIME
*(7200 + padding
*300));
5050 //implement pst style parameters:
5051 //suggested dream - unused
5052 //if suggested dream is 0, then area flags determine the 'movie'
5053 //hp - number of hps healed
5054 //renting - crashes pst, we simply ignore it
5055 void GameScript::RestParty(Scriptable
* Sender
, Action
* parameters
)
5057 Game
*game
= core
->GetGame();
5058 game
->RestParty(REST_NOAREA
|REST_NOMOVE
|REST_NOCRITTER
, parameters
->int0Parameter
, parameters
->int1Parameter
);
5059 Sender
->ReleaseCurrentAction();
5062 //doesn't advance game time, just refreshes spells of target
5063 //this is a non-blocking action
5064 void GameScript::Rest(Scriptable
* Sender
, Action
* /*parameters*/)
5066 if (Sender
->Type
!=ST_ACTOR
) {
5069 Actor
*actor
= (Actor
*) Sender
;
5070 actor
->spellbook
.ChargeAllSpells();
5071 //check if this should be a full heal
5073 actor
->fxqueue
.RemoveExpiredEffects(0xffffffff);
5076 //doesn't advance game time (unsure), just refreshes spells of target
5077 void GameScript::RestNoSpells(Scriptable
* Sender
, Action
* /*parameters*/)
5079 if (Sender
->Type
!=ST_ACTOR
) {
5082 Actor
*actor
= (Actor
*) Sender
;
5083 //check if this should be a full heal
5085 actor
->fxqueue
.RemoveExpiredEffects(0xffffffff);
5088 //this is most likely advances time
5089 void GameScript::RestUntilHealed(Scriptable
* Sender
, Action
* /*parameters*/)
5091 if (Sender
->Type
!=ST_ACTOR
) {
5094 Actor
*actor
= (Actor
*) Sender
;
5096 //not sure if this should remove timed effects
5097 //more like execute them hour by hour :>
5101 //removes all delayed/duration/semi permanent effects (like a ctrl-r)
5102 void GameScript::ClearPartyEffects(Scriptable
* /*Sender*/, Action
* /*parameters*/)
5104 Game
*game
= core
->GetGame();
5105 int i
= game
->GetPartySize(false);
5107 Actor
*tar
= game
->GetPC(i
, false);
5108 tar
->fxqueue
.RemoveExpiredEffects(0xffffffff);
5112 //iwd2 removes effects from a single sprite
5113 void GameScript::ClearSpriteEffects(Scriptable
* Sender
, Action
* parameters
)
5115 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5116 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5119 Actor
*actor
= (Actor
*) tar
;
5120 actor
->fxqueue
.RemoveExpiredEffects(0xffffffff);
5123 //IWD2 special, can mark only actors, hope it is enough
5124 void GameScript::MarkObject(Scriptable
* Sender
, Action
* parameters
)
5126 if (Sender
->Type
!= ST_ACTOR
) {
5129 //unsure, could mark dead objects?
5130 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1], GA_NO_DEAD
);
5131 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5134 Actor
*actor
= (Actor
*) Sender
;
5135 actor
->LastMarked
= ((Actor
*) tar
)->GetID();
5136 //if this doesn't modify LastSeen, then remove this line
5137 actor
->LastSeen
= actor
->LastMarked
;
5140 void GameScript::SetDialogueRange(Scriptable
* Sender
, Action
* parameters
)
5142 if (Sender
->Type
!= ST_ACTOR
) {
5145 Actor
*actor
= (Actor
*) Sender
;
5146 actor
->SetBase( IE_DIALOGRANGE
, parameters
->int0Parameter
);
5149 void GameScript::SetGlobalTint(Scriptable
* /*Sender*/, Action
* parameters
)
5151 core
->GetVideoDriver()->SetFadeColor(parameters
->int0Parameter
, parameters
->int1Parameter
, parameters
->int2Parameter
);
5154 void GameScript::SetArmourLevel(Scriptable
* Sender
, Action
* parameters
)
5156 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5157 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5160 Actor
*actor
= (Actor
*) Sender
;
5161 actor
->SetBase( IE_ARMOR_TYPE
, parameters
->int0Parameter
);
5164 void GameScript::RandomWalk(Scriptable
* Sender
, Action
* /*parameters*/)
5166 if (Sender
->Type
!= ST_ACTOR
) {
5167 Sender
->ReleaseCurrentAction();
5170 Actor
* actor
= ( Actor
* ) Sender
;
5171 actor
->RandomWalk( true, false );
5172 Sender
->ReleaseCurrentAction();
5175 void GameScript::RandomRun(Scriptable
* Sender
, Action
* /*parameters*/)
5177 if (Sender
->Type
!= ST_ACTOR
) {
5178 Sender
->ReleaseCurrentAction();
5181 Actor
* actor
= ( Actor
* ) Sender
;
5182 actor
->RandomWalk( true, true );
5183 Sender
->ReleaseCurrentAction();
5186 void GameScript::RandomWalkContinuous(Scriptable
* Sender
, Action
* /*parameters*/)
5188 if (Sender
->Type
!= ST_ACTOR
) {
5189 Sender
->ReleaseCurrentAction();
5192 Actor
* actor
= ( Actor
* ) Sender
;
5193 actor
->RandomWalk( false, false );
5196 void GameScript::RandomFly(Scriptable
* Sender
, Action
* /*parameters*/)
5198 if (Sender
->Type
!= ST_ACTOR
) {
5199 Sender
->ReleaseCurrentAction();
5202 Actor
* actor
= ( Actor
* ) Sender
;
5205 actor
->SetOrientation(actor
->GetOrientation()-1, false);
5207 actor
->SetOrientation(actor
->GetOrientation()+1, false);
5209 //fly in this direction for 5 steps
5210 actor
->MoveLine(5, GL_PASS
, actor
->GetOrientation() );
5211 //readding the action to the end of the queue
5212 //Sender->AddAction( parameters );
5213 //Sender->ReleaseCurrentAction();
5216 //UseContainer uses the predefined target (like Nidspecial1 dialog hack)
5217 void GameScript::UseContainer(Scriptable
* Sender
, Action
* /*parameters*/)
5219 if (Sender
->Type
!= ST_ACTOR
) {
5220 Sender
->ReleaseCurrentAction();
5223 Actor
*actor
= (Actor
*)Sender
;
5224 Container
*container
= core
->GetCurrentContainer();
5226 printMessage("GameScript","No container selected!", YELLOW
);
5227 Sender
->ReleaseCurrentAction();
5231 ieDword distance
= PersonalDistance(Sender
, container
);
5232 ieDword needed
= MAX_OPERATING_DISTANCE
;
5233 if (container
->Type
==IE_CONTAINER_PILE
) {
5234 needed
= 0; // less than a search square (width)
5236 if (distance
<=needed
)
5238 //check if the container is unlocked
5239 if (!container
->TryUnlock(actor
)) {
5240 //playsound can't open container
5241 //display string, etc
5242 core
->DisplayConstantString(STR_CONTLOCKED
,0xd7d7be,container
);
5243 Sender
->ReleaseCurrentAction();
5246 Actor
*actor
= (Actor
*)Sender
;
5247 actor
->SetModal(MS_NONE
);
5248 container
->TriggerTrap(0, actor
->GetID());
5249 core
->SetCurrentContainer(actor
, container
, true);
5250 Sender
->ReleaseCurrentAction();
5253 MoveNearerTo(Sender
, container
, needed
);
5256 //call the usecontainer action in target (not used)
5257 void GameScript::ForceUseContainer(Scriptable
* Sender
, Action
* parameters
)
5259 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5260 if (!tar
|| tar
->Type
!= ST_ACTOR
) {
5261 Sender
->ReleaseCurrentAction(); //why blocking???
5265 sprintf( Tmp
, "UseContainer()");
5266 Action
*newaction
= GenerateAction(Tmp
);
5267 tar
->AddActionInFront(newaction
);
5268 Sender
->ReleaseCurrentAction(); //why blocking???
5271 //these actions directly manipulate a game variable (as the original engine)
5272 void GameScript::SetMazeEasier(Scriptable
* Sender
, Action
* /*parameters*/)
5274 int value
= CheckVariable( Sender
, "MAZEDIFFICULTY","GLOBAL");
5276 SetVariable(Sender
, "MAZEDIFFICULTY", "GLOBAL", value
-1);
5280 void GameScript::SetMazeHarder(Scriptable
* Sender
, Action
* /*parameters*/)
5282 int value
= CheckVariable( Sender
, "MAZEDIFFICULTY","GLOBAL");
5284 SetVariable(Sender
, "MAZEDIFFICULTY", "GLOBAL", value
+1);
5288 void GameScript::StartRainNow(Scriptable
* /*Sender*/, Action
* /*parameters*/)
5290 core
->GetGame()->StartRainOrSnow( false, WB_RAIN
|WB_LIGHTNING
);
5293 void GameScript::Weather(Scriptable
* /*Sender*/, Action
* parameters
)
5295 Game
*game
= core
->GetGame();
5296 switch(parameters
->int0Parameter
& WB_FOG
) {
5298 game
->StartRainOrSnow( false, 0);
5301 game
->StartRainOrSnow( true, WB_RAIN
|WB_LIGHTNING
);
5304 game
->StartRainOrSnow( true, WB_SNOW
);
5307 game
->StartRainOrSnow( true, WB_FOG
);
5312 void GameScript::CopyGroundPilesTo(Scriptable
* Sender
, Action
* parameters
)
5314 Map
*map
= Sender
->GetCurrentArea();
5315 Map
*othermap
= core
->GetGame()->GetMap( parameters
->string0Parameter
, false );
5319 map
->CopyGroundPiles( othermap
, parameters
->pointParameter
);
5323 void GameScript::PlayBardSong(Scriptable
* Sender
, Action
* /*parameters*/)
5325 if (Sender
->Type
!=ST_ACTOR
) {
5328 //actually this one must use int0Parameter to set a bardsong
5329 Actor
*actor
= (Actor
*) Sender
;
5330 actor
->SetModal( MS_BATTLESONG
);
5333 void GameScript::BattleSong(Scriptable
* Sender
, Action
* /*parameters*/)
5335 if (Sender
->Type
!=ST_ACTOR
) {
5338 Actor
*actor
= (Actor
*) Sender
;
5339 actor
->SetModal( MS_BATTLESONG
);
5342 void GameScript::FindTraps(Scriptable
* Sender
, Action
* /*parameters*/)
5344 if (Sender
->Type
!=ST_ACTOR
) {
5347 Actor
*actor
= (Actor
*) Sender
;
5348 actor
->SetModal( MS_DETECTTRAPS
);
5351 void GameScript::Hide(Scriptable
* Sender
, Action
* /*parameters*/)
5353 if (Sender
->Type
!=ST_ACTOR
) {
5356 Actor
*actor
= (Actor
*) Sender
;
5358 if (actor
->TryToHide()) {
5359 actor
->SetModal(MS_STEALTH
);
5361 //TODO: expiry isn't instant (skill based transition?)
5365 void GameScript::Turn(Scriptable
* Sender
, Action
* /*parameters*/)
5367 if (Sender
->Type
!=ST_ACTOR
) {
5370 Actor
*actor
= (Actor
*) Sender
;
5372 if (actor
->Modified
[IE_DISABLEDBUTTON
] & (1<<ACT_TURN
)) {
5376 int skill
= actor
->GetStat(IE_TURNUNDEADLEVEL
);
5377 if (skill
< 1) return;
5379 actor
->SetModal(MS_TURNUNDEAD
);
5383 void GameScript::TurnAMT(Scriptable
* Sender
, Action
* parameters
)
5385 if (Sender
->Type
!=ST_ACTOR
) {
5386 Sender
->ReleaseCurrentAction();
5389 Actor
*actor
= (Actor
*) Sender
;
5390 actor
->SetOrientation(actor
->GetOrientation()+parameters
->int0Parameter
, true);
5391 actor
->SetWait( 1 );
5392 Sender
->ReleaseCurrentAction(); // todo, blocking?
5395 void GameScript::RandomTurn(Scriptable
* Sender
, Action
* /*parameters*/)
5397 if (Sender
->Type
!=ST_ACTOR
) {
5398 Sender
->ReleaseCurrentAction();
5401 Actor
*actor
= (Actor
*) Sender
;
5402 actor
->SetOrientation(rand() % MAX_ORIENT
, true);
5403 actor
->SetWait( 1 );
5404 Sender
->ReleaseCurrentAction(); // todo, blocking?
5407 void GameScript::AttachTransitionToDoor(Scriptable
* Sender
, Action
* parameters
)
5409 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5410 if (!tar
|| tar
->Type
!= ST_DOOR
) {
5413 Door
* door
= ( Door
* ) tar
;
5414 strnspccpy(door
->LinkedInfo
, parameters
->string0Parameter
, 32);
5417 /*getting a handle of a temporary actor resource to copy its selected attributes*/
5418 void GameScript::ChangeAnimation(Scriptable
* Sender
, Action
* parameters
)
5420 if (Sender
->Type
!=ST_ACTOR
) {
5423 ChangeAnimationCore((Actor
*) Sender
, parameters
->string0Parameter
,1);
5426 void GameScript::ChangeAnimationNoEffect(Scriptable
* Sender
, Action
* parameters
)
5428 if (Sender
->Type
!=ST_ACTOR
) {
5431 ChangeAnimationCore((Actor
*) Sender
, parameters
->string0Parameter
,0);
5434 void GameScript::Polymorph(Scriptable
* Sender
, Action
* parameters
)
5436 if (Sender
->Type
!=ST_ACTOR
) {
5439 Actor
*act
= (Actor
*) Sender
;
5440 act
->SetBase(IE_ANIMATION_ID
, parameters
->int0Parameter
);
5443 void GameScript::PolymorphCopy(Scriptable
* Sender
, Action
* parameters
)
5445 if (Sender
->Type
!=ST_ACTOR
) {
5448 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5449 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5452 PolymorphCopyCore((Actor
*) Sender
, (Actor
*) tar
, false);
5455 /* according to IESDP this only copies the animation ID */
5456 void GameScript::PolymorphCopyBase(Scriptable
* Sender
, Action
* parameters
)
5458 if (Sender
->Type
!=ST_ACTOR
) {
5461 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5462 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5465 Actor
*act
= (Actor
*) Sender
;
5466 Actor
*actor
= (Actor
*) tar
;
5467 act
->SetBase(IE_ANIMATION_ID
, actor
->GetBase(IE_ANIMATION_ID
) );
5470 void GameScript::SaveGame(Scriptable
* /*Sender*/, Action
* parameters
)
5472 if (core
->HasFeature(GF_STRREF_SAVEGAME
)) {
5473 const char *basename
= "Auto-Save";
5474 AutoTable
tab("savegame");
5476 basename
= tab
->QueryDefault();
5478 char * str
= core
->GetString( parameters
->int0Parameter
, IE_STR_STRREFOFF
);
5479 char FolderName
[_MAX_PATH
];
5480 snprintf (FolderName
, sizeof(FolderName
), "%s - %s", basename
, str
);
5481 core
->FreeString( str
);
5482 core
->GetSaveGameIterator()->CreateSaveGame(Holder
< ::SaveGame
>(), FolderName
);
5484 core
->GetSaveGameIterator()->CreateSaveGame(parameters
->int0Parameter
);
5488 /*EscapeAreaMove(S:Area*,I:X*,I:Y*,I:Face*)*/
5489 void GameScript::EscapeArea(Scriptable
* Sender
, Action
* parameters
)
5491 printf("EscapeArea/EscapeAreaMove\n");
5492 if (Sender
->Type
!=ST_ACTOR
) {
5493 Sender
->ReleaseCurrentAction();
5496 Map
*map
= Sender
->GetCurrentArea();
5498 Sender
->ReleaseCurrentAction();
5502 Point p
= Sender
->Pos
;
5503 map
->TMap
->AdjustNearestTravel(p
);
5505 if (parameters
->string0Parameter
[0]) {
5506 Point
q((short) parameters
->int0Parameter
, (short) parameters
->int1Parameter
);
5507 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, q
, 0, parameters
->int2Parameter
);
5509 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, p
, EA_DESTROY
, parameters
->int0Parameter
);
5511 //EscapeAreaCore will do its ReleaseCurrentAction
5512 //Sender->ReleaseCurrentAction();
5515 void GameScript::EscapeAreaDestroy(Scriptable
* Sender
, Action
* parameters
)
5517 printf("EscapeAreaDestroy\n");
5518 if (Sender
->Type
!=ST_ACTOR
) {
5519 Sender
->ReleaseCurrentAction();
5522 Map
*map
= Sender
->GetCurrentArea();
5524 Sender
->ReleaseCurrentAction();
5529 Point p
= Sender
->Pos
;
5530 map
->TMap
->AdjustNearestTravel(p
);
5531 //EscapeAreaCore will do its ReleaseCurrentAction
5532 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, p
, EA_DESTROY
, parameters
->int0Parameter
);
5535 /*EscapeAreaObjectMove(S:Area*,I:X*,I:Y*,I:Face*)*/
5536 void GameScript::EscapeAreaObject(Scriptable
* Sender
, Action
* parameters
)
5538 printf("EscapeAreaObject\n");
5539 if (Sender
->Type
!=ST_ACTOR
) {
5540 Sender
->ReleaseCurrentAction();
5543 Map
*map
= Sender
->GetCurrentArea();
5545 Sender
->ReleaseCurrentAction();
5549 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5551 Sender
->ReleaseCurrentAction();
5555 if (parameters
->string0Parameter
[0]) {
5556 Point
q((short) parameters
->int0Parameter
, (short) parameters
->int1Parameter
);
5557 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, q
, 0, parameters
->int2Parameter
);
5559 EscapeAreaCore( Sender
, p
, 0, p
, EA_DESTROY
, parameters
->int0Parameter
);
5561 //EscapeAreaCore will do its ReleaseCurrentAction
5564 //This one doesn't require the object to be seen?
5565 //We don't have that feature yet, so this is the same as EscapeAreaObject
5566 void GameScript::EscapeAreaObjectNoSee(Scriptable
* Sender
, Action
* parameters
)
5568 printf("EscapeAreaObjectNoSee\n");
5569 if (Sender
->Type
!=ST_ACTOR
) {
5570 Sender
->ReleaseCurrentAction();
5573 Map
*map
= Sender
->GetCurrentArea();
5575 Sender
->ReleaseCurrentAction();
5579 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5581 Sender
->ReleaseCurrentAction();
5585 Sender
->SetWait(parameters
->int0Parameter
);
5586 if (parameters
->string0Parameter
[0]) {
5587 Point
q((short) parameters
->int0Parameter
, (short) parameters
->int1Parameter
);
5588 EscapeAreaCore( Sender
, p
, parameters
->string0Parameter
, q
, 0, parameters
->int2Parameter
);
5590 EscapeAreaCore( Sender
, p
, 0, p
, EA_DESTROY
|EA_NOSEE
, parameters
->int0Parameter
);
5592 //EscapeAreaCore will do its ReleaseCurrentAction
5595 //takes first fitting item from container at feet, doesn't seem to be working in the original engines
5596 void GameScript::PickUpItem(Scriptable
* Sender
, Action
* parameters
)
5598 if (Sender
->Type
!=ST_ACTOR
) {
5601 Actor
*scr
= (Actor
*) Sender
;
5602 Map
*map
= scr
->GetCurrentArea();
5603 Container
*c
= map
->GetPile(scr
->Pos
);
5604 if (!c
) { //this shouldn't happen, but lets prepare for the worst
5608 //the following part is coming from GUISCript.cpp with trivial changes
5609 int Slot
= c
->inventory
.FindItem(parameters
->string0Parameter
, 0);
5613 int res
= core
->CanMoveItem(c
->inventory
.GetSlotItem(Slot
) );
5614 if (!res
) { //cannot move
5617 CREItem
*item
= c
->RemoveItem(Slot
,0);
5621 if (res
!=-1 && scr
->InParty
) { //it is gold and we got the party pool!
5624 res
= scr
->inventory
.AddSlotItem(item
, SLOT_ONLYINVENTORY
);
5625 if (res
!=ASI_SUCCESS
) { //putting it back
5629 item_is_gold
: //we take gold!
5631 core
->GetGame()->PartyGold
+= res
;
5632 //if you want message here then use
5633 //core->GetGame()->AddGold(res);
5635 scr
->SetBase( IE_GOLD
, scr
->GetBase(IE_GOLD
) + res
);
5640 void GameScript::ChangeStoreMarkup(Scriptable
* /*Sender*/, Action
* parameters
)
5642 bool has_current
= false;
5646 Store
*store
= core
->GetCurrentStore();
5648 store
= core
->SetCurrentStore(parameters
->string0Parameter
,NULL
);
5650 if (strnicmp(store
->Name
, parameters
->string0Parameter
, 8) ) {
5651 //not the current store, we need some dirty hack
5653 strnlwrcpy(current
, store
->Name
, 8);
5654 strnuprcpy(owner
, store
->GetOwner(), 32);
5657 store
->BuyMarkup
= parameters
->int0Parameter
;
5658 store
->SellMarkup
= parameters
->int1Parameter
;
5659 //additional markup, is this depreciation???
5660 store
->DepreciationRate
= parameters
->int2Parameter
;
5662 //setting back old store (this will save our current store)
5663 core
->SetCurrentStore(current
, owner
);
5667 void GameScript::SetEncounterProbability(Scriptable
* /*Sender*/, Action
* parameters
)
5669 WorldMap
*wmap
= core
->GetWorldMap(parameters
->string0Parameter
);
5671 //no such starting area
5674 WMPAreaLink
*link
= wmap
->GetLink(parameters
->string0Parameter
, parameters
->string1Parameter
);
5678 link
->EncounterChance
= parameters
->int0Parameter
;
5681 void GameScript::SpawnPtActivate(Scriptable
* Sender
, Action
* parameters
)
5683 if (parameters
->objects
[1]) {
5684 Map
*map
= Sender
->GetCurrentArea();
5685 Spawn
*spawn
= map
->GetSpawn(parameters
->objects
[1]->objectName
);
5692 void GameScript::SpawnPtDeactivate(Scriptable
* Sender
, Action
* parameters
)
5694 if (parameters
->objects
[1]) {
5695 Map
*map
= Sender
->GetCurrentArea();
5696 Spawn
*spawn
= map
->GetSpawn(parameters
->objects
[1]->objectName
);
5703 void GameScript::SpawnPtSpawn(Scriptable
* Sender
, Action
* parameters
)
5705 if (parameters
->objects
[1]) {
5706 Map
*map
= Sender
->GetCurrentArea();
5707 Spawn
*spawn
= map
->GetSpawn(parameters
->objects
[1]->objectName
);
5709 spawn
->Enabled
= 1; //??? maybe use an unconditionality flag
5710 map
->TriggerSpawn(spawn
);
5715 void GameScript::ApplySpell(Scriptable
* Sender
, Action
* parameters
)
5719 if (!ResolveSpellName( spellres
, parameters
) ) {
5723 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5727 if (tar
->Type
==ST_ACTOR
) {
5728 //apply spell on target
5732 if (Sender->Type==ST_ACTOR) {
5733 owner = (Actor *) Sender;
5735 owner = (Actor *) tar;
5738 //core->ApplySpell(spellres, (Actor *) tar, owner, parameters->int1Parameter);
5739 core
->ApplySpell(spellres
, (Actor
*) tar
, Sender
, parameters
->int1Parameter
);
5741 //no idea about this one
5745 if (Sender->Type==ST_ACTOR) {
5746 owner = (Actor *) Sender;
5751 //apply spell on point
5753 GetPositionFromScriptable(tar
, d
, false);
5754 //core->ApplySpellPoint(spellres, tar->GetCurrentArea(), d, owner, parameters->int1Parameter);
5755 core
->ApplySpellPoint(spellres
, tar
->GetCurrentArea(), d
, Sender
, parameters
->int1Parameter
);
5759 void GameScript::ApplySpellPoint(Scriptable
* Sender
, Action
* parameters
)
5764 if (!ResolveSpellName( spellres
, parameters
) ) {
5768 if (Sender
->Type
==ST_ACTOR
) {
5769 owner
= (Actor
*) Sender
;
5773 core
->ApplySpellPoint(spellres
, Sender
->GetCurrentArea(), parameters
->pointParameter
, owner
, parameters
->int1Parameter
);
5776 //this is a gemrb extension
5777 //sets a variable to the stat value
5778 void GameScript::GetStat(Scriptable
* Sender
, Action
* parameters
)
5782 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5783 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5786 Actor
* actor
= ( Actor
* ) tar
;
5787 value
= actor
->GetStat( parameters
->int0Parameter
);
5789 SetVariable( Sender
, parameters
->string0Parameter
, value
);
5792 void GameScript::BreakInstants(Scriptable
* Sender
, Action
* /*parameters*/)
5794 //don't do anything, apparently the point of this action is to
5795 //delay the execution of further actions to the next AI cycle
5797 Sender
->ReleaseCurrentAction(); // this doesn't really need to block
5800 //an interesting improvement would be to pause game for a given duration
5801 void GameScript::PauseGame(Scriptable
* Sender
, Action
* /*parameters*/)
5803 GameControl
*gc
= core
->GetGameControl();
5805 gc
->SetDialogueFlags(DF_FREEZE_SCRIPTS
, BM_OR
);
5806 core
->DisplayConstantString(STR_SCRIPTPAUSED
,0xff0000);
5808 // releasing this action allows actions to continue executing,
5809 // so we force a wait
5811 Sender
->ReleaseCurrentAction(); // does this need to block?
5814 void GameScript::SetNoOneOnTrigger(Scriptable
* Sender
, Action
* parameters
)
5818 if (!parameters
->objects
[1]) {
5821 ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
5823 if (!ip
|| (ip
->Type
!=ST_TRIGGER
&& ip
->Type
!=ST_TRAVEL
&& ip
->Type
!=ST_PROXIMITY
)) {
5824 printf("Script error: No Trigger Named \"%s\"\n", parameters
->objects
[1]->objectName
);
5827 ip
->LastEntered
= 0;
5828 ip
->LastTrigger
= 0;
5829 ip
->LastTriggerObject
= 0;
5832 void GameScript::UseDoor(Scriptable
* Sender
, Action
* parameters
)
5834 GameControl
*gc
= core
->GetGameControl();
5836 Sender
->ReleaseCurrentAction();
5840 gc
->target_mode
= TARGET_MODE_NONE
;
5841 OpenDoor(Sender
, parameters
);
5843 Sender
->ReleaseCurrentAction(); // this is blocking, OpenDoor is not
5846 //this will force bashing the door
5847 void GameScript::BashDoor(Scriptable
* Sender
, Action
* parameters
)
5849 GameControl
*gc
= core
->GetGameControl();
5851 Sender
->ReleaseCurrentAction();
5855 gc
->target_mode
= TARGET_MODE_ATTACK
; //for bashing doors too
5856 OpenDoor(Sender
, parameters
);
5858 Sender
->ReleaseCurrentAction(); // this is blocking, OpenDoor is not
5862 void GameScript::ActivatePortalCursor(Scriptable
* Sender
, Action
* parameters
)
5866 if (!parameters
->objects
[1]) {
5869 ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
5874 if (ip
->Type
!=ST_PROXIMITY
&& ip
->Type
!=ST_TRAVEL
) {
5877 InfoPoint
*tar
= (InfoPoint
*) ip
;
5878 if (parameters
->int0Parameter
) {
5879 tar
->Trapped
|=PORTAL_CURSOR
;
5881 tar
->Trapped
&=~PORTAL_CURSOR
;
5886 void GameScript::EnablePortalTravel(Scriptable
* Sender
, Action
* parameters
)
5890 if (!parameters
->objects
[1]) {
5893 ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
5898 if (ip
->Type
!=ST_PROXIMITY
&& ip
->Type
!=ST_TRAVEL
) {
5901 InfoPoint
*tar
= (InfoPoint
*) ip
;
5902 if (parameters
->int0Parameter
) {
5903 tar
->Trapped
|=PORTAL_TRAVEL
;
5905 tar
->Trapped
&=~PORTAL_TRAVEL
;
5909 //unhardcoded iwd action (for the forge entrance change)
5910 void GameScript::ChangeDestination(Scriptable
* Sender
, Action
* parameters
)
5912 InfoPoint
*ip
= Sender
->GetCurrentArea()->TMap
->GetInfoPoint(parameters
->objects
[1]->objectName
);
5913 if (ip
&& (ip
->Type
==ST_TRAVEL
) ) {
5914 strnlwrcpy(ip
->Destination
, parameters
->string0Parameter
, 32);
5918 void GameScript::MoveCursorPoint(Scriptable
* /*Sender*/, Action
* parameters
)
5920 core
->GetVideoDriver()->MoveMouse(parameters
->pointParameter
.x
, parameters
->pointParameter
.y
);
5923 //false means, no talk
5924 void GameScript::DialogueInterrupt(Scriptable
* Sender
, Action
* parameters
)
5926 if (Sender
->Type
!=ST_ACTOR
) {
5929 Actor
* actor
= ( Actor
* ) Sender
;
5930 if ( parameters
->int0Parameter
!= 0 ) {
5931 actor
->SetMCFlag(MC_NO_TALK
, BM_NAND
);
5933 actor
->SetMCFlag(MC_NO_TALK
, BM_OR
);
5937 void GameScript::EquipMostDamagingMelee(Scriptable
* Sender
, Action
* /*parameters*/)
5939 if (Sender
->Type
!=ST_ACTOR
) {
5942 Actor
* actor
= ( Actor
* ) Sender
;
5943 actor
->inventory
.EquipBestWeapon(EQUIP_MELEE
);
5946 void GameScript::EquipRanged(Scriptable
* Sender
, Action
* /*parameters*/)
5948 if (Sender
->Type
!=ST_ACTOR
) {
5951 Actor
* actor
= ( Actor
* ) Sender
;
5952 actor
->inventory
.EquipBestWeapon(EQUIP_RANGED
);
5955 //will equip best weapon regardless of range considerations
5956 void GameScript::EquipWeapon(Scriptable
* Sender
, Action
* /*parameters*/)
5958 if (Sender
->Type
!=ST_ACTOR
) {
5961 Actor
* actor
= ( Actor
* ) Sender
;
5962 actor
->inventory
.EquipBestWeapon(EQUIP_MELEE
|EQUIP_RANGED
);
5965 void GameScript::SetBestWeapon(Scriptable
* Sender
, Action
* parameters
)
5967 if (Sender
->Type
!=ST_ACTOR
) {
5971 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5972 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5975 Actor
* actor
= ( Actor
* ) Sender
;
5977 Actor
*target
= (Actor
*) tar
;
5978 if (PersonalDistance(actor
,target
)>(unsigned int) parameters
->int0Parameter
) {
5979 actor
->inventory
.EquipBestWeapon(EQUIP_RANGED
);
5981 actor
->inventory
.EquipBestWeapon(EQUIP_MELEE
);
5985 void GameScript::FakeEffectExpiryCheck(Scriptable
* Sender
, Action
* parameters
)
5987 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
5988 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
5991 Actor
*target
= (Actor
*) tar
;
5992 target
->fxqueue
.RemoveExpiredEffects(parameters
->int0Parameter
);
5995 void GameScript::SetInterrupt(Scriptable
* Sender
, Action
* parameters
)
5997 if (parameters
->int0Parameter
) {
5998 Sender
->Interrupt();
6000 Sender
->NoInterrupt();
6004 void GameScript::SelectWeaponAbility(Scriptable
* Sender
, Action
* parameters
)
6006 if (Sender
->Type
!=ST_ACTOR
) {
6009 Actor
*scr
= (Actor
*) Sender
;
6010 int slot
= parameters
->int0Parameter
;
6011 int wslot
= scr
->inventory
.GetWeaponSlot();
6013 if (core
->QuerySlotType(slot
)&SLOT_WEAPON
) {
6015 if (slot
<0 || slot
>=MAX_QUICKWEAPONSLOT
) {
6018 scr
->SetEquippedQuickSlot(slot
, parameters
->int1Parameter
);
6022 wslot
= scr
->inventory
.GetQuickSlot();
6023 if (core
->QuerySlotType(slot
)&SLOT_ITEM
) {
6025 if (slot
<0 || slot
>=MAX_QUICKITEMSLOT
) {
6029 scr
->PCStats
->QuickItemHeaders
[slot
]=(ieWord
) parameters
->int1Parameter
;
6034 void GameScript::UseItem(Scriptable
* Sender
, Action
* parameters
)
6036 if (Sender
->Type
!=ST_ACTOR
) {
6037 Sender
->ReleaseCurrentAction();
6040 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6042 Sender
->ReleaseCurrentAction();
6045 Actor
*act
= (Actor
*) Sender
;
6047 ieDword header
, flags
;
6050 if (parameters
->string0Parameter
[0]) {
6051 Slot
= act
->inventory
.FindItem(parameters
->string0Parameter
, 0);
6052 //this IS in the original game code (ability)
6053 header
= parameters
->int0Parameter
;
6054 flags
= parameters
->int1Parameter
;
6056 Slot
= parameters
->int0Parameter
;
6057 //this is actually not in the original game code
6058 header
= parameters
->int1Parameter
;
6059 flags
= parameters
->int2Parameter
;
6063 Sender
->ReleaseCurrentAction();
6067 if (!ResolveItemName( itemres
, act
, Slot
) ) {
6068 Sender
->ReleaseCurrentAction();
6072 unsigned int dist
= GetItemDistance(itemres
, header
);
6074 if (PersonalDistance(tar
->Pos
, Sender
) > dist
) {
6075 MoveNearerTo(Sender
, tar
, dist
);
6079 act
->UseItem(Slot
, header
, tar
, flags
);
6080 Sender
->ReleaseCurrentAction();
6083 void GameScript::UseItemPoint(Scriptable
* Sender
, Action
* parameters
)
6085 if (Sender
->Type
!=ST_ACTOR
) {
6086 Sender
->ReleaseCurrentAction();
6090 Actor
*act
= (Actor
*) Sender
;
6096 if (parameters
->string0Parameter
[0]) {
6097 Slot
= act
->inventory
.FindItem(parameters
->string0Parameter
, 0);
6098 //this IS in the original game code (ability)
6099 header
= parameters
->int0Parameter
;
6100 flags
= parameters
->int1Parameter
;
6102 Slot
= parameters
->int0Parameter
;
6103 //this is actually not in the original game code
6104 header
= parameters
->int1Parameter
;
6105 flags
= parameters
->int2Parameter
;
6109 Sender
->ReleaseCurrentAction();
6113 if (!ResolveItemName( itemres
, act
, Slot
) ) {
6114 Sender
->ReleaseCurrentAction();
6118 unsigned int dist
= GetItemDistance(itemres
, header
);
6120 if (PersonalDistance(parameters
->pointParameter
, Sender
) > dist
) {
6121 MoveNearerTo(Sender
, parameters
->pointParameter
, dist
, 0);
6125 act
->UseItemPoint(Slot
, header
, parameters
->pointParameter
, flags
);
6126 Sender
->ReleaseCurrentAction();
6129 //addfeat will be able to remove feats too
6130 //(the second int parameter is a bitmode)
6131 void GameScript::AddFeat(Scriptable
* Sender
, Action
* parameters
)
6133 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6134 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6137 Actor
*actor
= (Actor
*)tar
;
6138 actor
->SetFeat(parameters
->int0Parameter
, parameters
->int1Parameter
);
6141 void GameScript::MatchHP(Scriptable
* Sender
, Action
* parameters
)
6143 if (Sender
->Type
!=ST_ACTOR
) {
6146 Actor
*scr
= (Actor
*) Sender
;
6147 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6148 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6151 Actor
*actor
= (Actor
*)tar
;
6152 switch (parameters
->int0Parameter
) {
6153 case 1: //sadly the hpflags are not the same as stats
6154 actor
->SetBase(IE_HITPOINTS
,scr
->GetBase(IE_HITPOINTS
));
6157 actor
->SetBase(IE_MAXHITPOINTS
, scr
->GetBase(IE_MAXHITPOINTS
));
6159 default: //this is gemrb extension
6160 actor
->SetBase(parameters
->int0Parameter
, scr
->GetBase(parameters
->int0Parameter
));
6165 void GameScript::ChangeColor(Scriptable
* Sender
, Action
* parameters
)
6167 if (Sender
->Type
!=ST_ACTOR
) {
6170 Actor
*scr
= (Actor
*) Sender
;
6171 ieDword stat
= parameters
->int0Parameter
;
6172 if (stat
<9 || stat
>14) {
6175 stat
+= IE_COLORS
- 9;
6176 scr
->SetBase(stat
, (scr
->GetBase(stat
)&~255)|(parameters
->int1Parameter
&255));
6179 void GameScript::AddKit(Scriptable
* Sender
, Action
* parameters
)
6181 if (Sender
->Type
!=ST_ACTOR
) {
6184 Actor
*scr
= (Actor
*) Sender
;
6185 //remove previous kit stuff
6186 scr
->SetBase(IE_KIT
, parameters
->int0Parameter
);
6189 void GameScript::AddSuperKit(Scriptable
* Sender
, Action
* parameters
)
6191 if (Sender
->Type
!=ST_ACTOR
) {
6194 Actor
*scr
= (Actor
*) Sender
;
6195 scr
->SetBase(IE_KIT
, parameters
->int0Parameter
);
6198 void GameScript::SetSelection(Scriptable
* /*Sender*/, Action
* parameters
)
6200 GameControl
*gc
= core
->GetGameControl();
6204 gc
->SelectActor(parameters
->int0Parameter
, parameters
->int1Parameter
);
6207 //this action is weird in the original game, because it overwrites ALL
6209 //in this version, if a stat is set to 0, it won't change
6210 //it will alter only the main IDS stats
6211 void GameScript::ChangeAIType(Scriptable
* Sender
, Action
* parameters
)
6213 if (Sender
->Type
!=ST_ACTOR
) {
6216 Object
*ob
= parameters
->objects
[1];
6220 Actor
*scr
= (Actor
*) Sender
;
6221 for (int i
=0;i
<MAX_OBJECT_FIELDS
;i
++) {
6222 int val
= ob
->objectFields
[i
];
6224 if (!strnicmp(ObjectIDSTableNames
[i
],"ea",8)) {
6225 scr
->SetBase(IE_EA
, val
);
6228 if (!strnicmp(ObjectIDSTableNames
[i
],"general",8)) {
6229 scr
->SetBase(IE_GENERAL
, val
);
6232 if (!strnicmp(ObjectIDSTableNames
[i
],"race",8)) {
6233 scr
->SetBase(IE_RACE
, val
);
6236 if (!strnicmp(ObjectIDSTableNames
[i
],"class",8)) {
6237 scr
->SetBase(IE_CLASS
, val
);
6240 if (!strnicmp(ObjectIDSTableNames
[i
],"gender",8)) {
6241 scr
->SetBase(IE_SEX
, val
);
6244 if (!strnicmp(ObjectIDSTableNames
[i
],"specific",8)) {
6245 scr
->SetBase(IE_SPECIFIC
, val
);
6248 if (!strnicmp(ObjectIDSTableNames
[i
],"align",8)) {
6249 scr
->SetBase(IE_ALIGNMENT
, val
);
6255 void GameScript::Follow(Scriptable
* Sender
, Action
* parameters
)
6257 if (Sender
->Type
!=ST_ACTOR
) {
6261 Actor
*scr
= (Actor
*)Sender
;
6262 scr
->FollowOffset
= parameters
->pointParameter
;
6265 void GameScript::FollowCreature(Scriptable
* Sender
, Action
* parameters
)
6267 if (Sender
->Type
!=ST_ACTOR
) {
6268 Sender
->ReleaseCurrentAction();
6272 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6273 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6274 Sender
->ReleaseCurrentAction();
6277 Actor
*scr
= (Actor
*)Sender
;
6278 Actor
*actor
= (Actor
*)tar
;
6279 scr
->LastFollowed
= actor
->GetID();
6280 scr
->FollowOffset
.empty();
6281 if (!scr
->InMove() || scr
->Destination
!= actor
->Pos
) {
6282 scr
->WalkTo(actor
->Pos
, 0, 1);
6286 void GameScript::RunFollow(Scriptable
* Sender
, Action
* parameters
)
6288 if (Sender
->Type
!=ST_ACTOR
) {
6289 Sender
->ReleaseCurrentAction();
6293 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6294 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6295 Sender
->ReleaseCurrentAction();
6298 Actor
*scr
= (Actor
*)Sender
;
6299 Actor
*actor
= (Actor
*)tar
;
6300 scr
->LastFollowed
= actor
->GetID();
6301 scr
->FollowOffset
.empty();
6302 if (!scr
->InMove() || scr
->Destination
!= actor
->Pos
) {
6303 scr
->WalkTo(actor
->Pos
, IF_RUNNING
, 1);
6307 void GameScript::ProtectPoint(Scriptable
* Sender
, Action
* parameters
)
6309 if (Sender
->Type
!=ST_ACTOR
) {
6310 Sender
->ReleaseCurrentAction();
6313 Actor
*scr
= (Actor
*)Sender
;
6314 if (!scr
->InMove() || scr
->Destination
!= parameters
->pointParameter
) {
6315 scr
->WalkTo( parameters
->pointParameter
, 0, 1 );
6317 // we should handle 'Protect' here rather than just unblocking
6318 Sender
->ReleaseCurrentAction();
6321 void GameScript::ProtectObject(Scriptable
* Sender
, Action
* parameters
)
6323 if (Sender
->Type
!=ST_ACTOR
) {
6324 Sender
->ReleaseCurrentAction();
6328 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6329 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6330 Sender
->ReleaseCurrentAction();
6333 Actor
*scr
= (Actor
*)Sender
;
6334 Actor
*actor
= (Actor
*)tar
;
6335 scr
->LastFollowed
= actor
->GetID();
6336 scr
->LastProtected
= actor
->GetID();
6338 scr
->FollowOffset
.x
= parameters
->int0Parameter
;
6339 scr
->FollowOffset
.y
= parameters
->int0Parameter
;
6340 if (!scr
->InMove() || scr
->Destination
!= tar
->Pos
) {
6341 scr
->WalkTo( tar
->Pos
, 0, MAX_OPERATING_DISTANCE
);
6343 // we should handle 'Protect' here rather than just unblocking
6344 Sender
->ReleaseCurrentAction();
6347 //keeps following the object in formation
6348 void GameScript::FollowObjectFormation(Scriptable
* Sender
, Action
* parameters
)
6350 GameControl
*gc
= core
->GetGameControl();
6352 Sender
->ReleaseCurrentAction();
6355 if (Sender
->Type
!=ST_ACTOR
) {
6356 Sender
->ReleaseCurrentAction();
6360 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6361 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6362 Sender
->ReleaseCurrentAction();
6365 Actor
*scr
= (Actor
*)Sender
;
6366 Actor
*actor
= (Actor
*)tar
;
6367 scr
->LastFollowed
= actor
->GetID();
6368 ieDword formation
= parameters
->int0Parameter
;
6369 ieDword pos
= parameters
->int1Parameter
;
6370 scr
->FollowOffset
= gc
->GetFormationOffset(formation
, pos
);
6371 if (!scr
->InMove() || scr
->Destination
!= tar
->Pos
) {
6372 scr
->WalkTo( tar
->Pos
, 0, 1 );
6374 Sender
->ReleaseCurrentAction();
6377 //walks to a specific offset of target (quite like movetoobject)
6378 void GameScript::Formation(Scriptable
* Sender
, Action
* parameters
)
6380 GameControl
*gc
= core
->GetGameControl();
6382 Sender
->ReleaseCurrentAction();
6385 if (Sender
->Type
!=ST_ACTOR
) {
6386 Sender
->ReleaseCurrentAction();
6389 Scriptable
* tar
= GetStoredActorFromObject( Sender
, parameters
->objects
[1] );
6391 Sender
->ReleaseCurrentAction();
6394 Actor
*scr
= (Actor
*)Sender
;
6395 ieDword formation
= parameters
->int0Parameter
;
6396 ieDword pos
= parameters
->int1Parameter
;
6397 Point FollowOffset
= gc
->GetFormationOffset(formation
, pos
);
6398 FollowOffset
.x
+=tar
->Pos
.x
;
6399 FollowOffset
.y
+=tar
->Pos
.y
;
6400 if (!scr
->InMove() || scr
->Destination
!= FollowOffset
) {
6401 scr
->WalkTo( FollowOffset
, 0, 1 );
6405 void GameScript::TransformItem(Scriptable
* Sender
, Action
* parameters
)
6407 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6408 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6411 TransformItemCore((Actor
*)tar
, parameters
, true);
6414 void GameScript::TransformPartyItem(Scriptable
* /*Sender*/, Action
* parameters
)
6416 Game
*game
= core
->GetGame();
6417 int i
= game
->GetPartySize(false);
6419 Actor
*tar
= game
->GetPC(i
, false);
6420 TransformItemCore(tar
, parameters
, true);
6424 void GameScript::TransformItemAll(Scriptable
* Sender
, Action
* parameters
)
6426 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6427 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6430 TransformItemCore((Actor
*)tar
, parameters
, false);
6433 void GameScript::TransformPartyItemAll(Scriptable
* /*Sender*/, Action
* parameters
)
6435 Game
*game
= core
->GetGame();
6436 int i
= game
->GetPartySize(false);
6438 Actor
*tar
= game
->GetPC(i
, false);
6439 TransformItemCore(tar
, parameters
, false);
6443 void GameScript::GeneratePartyMember(Scriptable
* /*Sender*/, Action
* parameters
)
6445 AutoTable
pcs("bios");
6449 const char* string
= pcs
->QueryField( parameters
->int0Parameter
, 0 );
6450 int pos
= gamedata
->LoadCreature(string
,0,false);
6454 Actor
*actor
= core
->GetGame()->GetNPC(pos
);
6458 actor
->SetOrientation(parameters
->int1Parameter
, false);
6459 actor
->MoveTo(parameters
->pointParameter
);
6462 void GameScript::EnableFogDither(Scriptable
* /*Sender*/, Action
* /*parameters*/)
6464 core
->FogOfWar
|=FOG_DRAWFOG
;
6467 void GameScript::DisableFogDither(Scriptable
* /*Sender*/, Action
* /*parameters*/)
6469 core
->FogOfWar
&=~FOG_DRAWFOG
;
6472 void DeleteAllSpriteCovers()
6474 Game
*game
= core
->GetGame();
6475 int i
= game
->GetPartySize(false);
6477 Selectable
*tar
= (Selectable
*) game
->GetPC(i
, false);
6478 tar
->SetSpriteCover(NULL
);
6482 void GameScript::EnableSpriteDither(Scriptable
* /*Sender*/, Action
* /*parameters*/)
6484 core
->FogOfWar
&=~FOG_DITHERSPRITES
;
6485 DeleteAllSpriteCovers();
6488 void GameScript::DisableSpriteDither(Scriptable
* /*Sender*/, Action
* /*parameters*/)
6490 core
->FogOfWar
|=~FOG_DITHERSPRITES
;
6491 DeleteAllSpriteCovers();
6494 //the PST crew apparently loved hardcoding stuff
6495 ieResRef RebusResRef
={"DABUS1"};
6497 void GameScript::FloatRebus(Scriptable
* Sender
, Action
* parameters
)
6499 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6500 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6503 Actor
*actor
= (Actor
*)tar
;
6504 RebusResRef
[5]=(char) core
->Roll(1,5,'0');
6505 ScriptedAnimation
*vvc
= gamedata
->GetScriptedAnimation(RebusResRef
, 0);
6507 //setting the height
6508 vvc
->ZPos
=actor
->size
*20;
6510 //maybe this needs setting up some time
6511 vvc
->SetDefaultDuration(20);
6512 actor
->AddVVCell(vvc
);
6516 void GameScript::IncrementKillStat(Scriptable
* Sender
, Action
* parameters
)
6518 DataFileMgr
* ini
= core
->GetBeastsINI();
6523 sprintf(key
,"%d", parameters
->int0Parameter
);
6524 const char *variable
= ini
->GetKeyAsString( key
, "killvar", NULL
);
6528 ieDword value
= CheckVariable( Sender
, variable
, "GLOBAL" ) + 1;
6529 SetVariable( Sender
, variable
, "GLOBAL", value
);
6532 //this action plays a vvc animation over target
6533 //we simply apply the appropriate opcode on the target (see iwdopcodes)
6534 //the list of vvcs is in iwdshtab.2da
6535 EffectRef fx_iwd_visual_spell_hit_ref
={"IWDVisualSpellHit",NULL
,-1};
6537 void GameScript::SpellHitEffectSprite(Scriptable
* Sender
, Action
* parameters
)
6539 Scriptable
* src
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6543 Scriptable
* tar
= GetActorFromObject( Sender
, parameters
->objects
[2] );
6544 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6547 int opcode
= EffectQueue::ResolveEffect(fx_iwd_visual_spell_hit_ref
);
6548 Effect
*fx
= core
->GetEffect(opcode
);
6550 //invalid effect name didn't resolve to opcode
6555 fx
->Parameter2
= parameters
->int0Parameter
;
6556 //height (not sure if this is in the opcode, but seems acceptable)
6557 fx
->Parameter1
= parameters
->int1Parameter
;
6558 fx
->Probability1
=100;
6559 fx
->TimingMode
=FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES
;
6560 core
->ApplyEffect(fx
, (Actor
*) tar
, src
);
6563 void GameScript::SpellHitEffectPoint(Scriptable
* Sender
, Action
* parameters
)
6565 Scriptable
* src
= GetActorFromObject( Sender
, parameters
->objects
[1] );
6570 int opcode
= EffectQueue::ResolveEffect(fx_iwd_visual_spell_hit_ref
);
6571 Effect
*fx
= core
->GetEffect(opcode
);
6573 //invalid effect name didn't resolve to opcode
6578 fx
->Parameter2
= parameters
->int0Parameter
;
6579 //height (not sure if this is in the opcode, but seems acceptable)
6580 fx
->Parameter1
= parameters
->int1Parameter
;
6581 fx
->Probability1
=100;
6582 fx
->TimingMode
=FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES
;
6583 fx
->PosX
=parameters
->pointParameter
.x
;
6584 fx
->PosY
=parameters
->pointParameter
.y
;
6585 core
->ApplyEffect(fx
, NULL
, src
);
6589 void GameScript::ClickLButtonObject(Scriptable
* Sender
, Action
* parameters
)
6591 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6593 Sender
->ReleaseCurrentAction(); // this is blocking for some reason?
6596 ClickCore(Sender
, tar
->Pos
, GEM_MB_ACTION
, parameters
->int0Parameter
);
6599 void GameScript::ClickLButtonPoint(Scriptable
* Sender
, Action
* parameters
)
6601 ClickCore(Sender
, parameters
->pointParameter
, GEM_MB_ACTION
, parameters
->int0Parameter
);
6604 void GameScript::ClickRButtonObject(Scriptable
* Sender
, Action
* parameters
)
6606 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6608 Sender
->ReleaseCurrentAction(); // this is blocking for some reason?
6611 ClickCore(Sender
, tar
->Pos
, GEM_MB_MENU
, parameters
->int0Parameter
);
6614 void GameScript::ClickRButtonPoint(Scriptable
* Sender
, Action
* parameters
)
6616 ClickCore(Sender
, parameters
->pointParameter
, GEM_MB_MENU
, parameters
->int0Parameter
);
6619 void GameScript::DoubleClickLButtonObject(Scriptable
* Sender
, Action
* parameters
)
6621 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6623 Sender
->ReleaseCurrentAction(); // this is blocking for some reason?
6626 ClickCore(Sender
, tar
->Pos
, GEM_MB_ACTION
|GEM_MB_DOUBLECLICK
, parameters
->int0Parameter
);
6629 void GameScript::DoubleClickLButtonPoint(Scriptable
* Sender
, Action
* parameters
)
6631 ClickCore(Sender
, parameters
->pointParameter
, GEM_MB_ACTION
|GEM_MB_DOUBLECLICK
, parameters
->int0Parameter
);
6634 void GameScript::DoubleClickRButtonObject(Scriptable
* Sender
, Action
* parameters
)
6636 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6638 Sender
->ReleaseCurrentAction(); // this is blocking for some reason?
6641 ClickCore(Sender
, tar
->Pos
, GEM_MB_MENU
|GEM_MB_DOUBLECLICK
, parameters
->int0Parameter
);
6644 void GameScript::DoubleClickRButtonPoint(Scriptable
* Sender
, Action
* parameters
)
6646 ClickCore(Sender
, parameters
->pointParameter
, GEM_MB_MENU
|GEM_MB_DOUBLECLICK
, parameters
->int0Parameter
);
6649 //Picks 5 lines from wish.2da
6650 //Gets the 5 values (column is int0parameter) from the table.
6651 //Sets the five wishpowerNN to 1, while resets the rest to 0.
6652 //TODO: investigate what happens with * values
6653 void GameScript::SetupWish(Scriptable
* Sender
, Action
* parameters
)
6655 SetupWishCore(Sender
, parameters
->int0Parameter
, parameters
->int1Parameter
);
6658 //The same as the previous action, except that the column parameter comes from
6659 //the target object's wisdom directly (this action is not used in the original)
6660 void GameScript::SetupWishObject(Scriptable
* Sender
, Action
* parameters
)
6662 Scriptable
*tar
= GetActorFromObject(Sender
, parameters
->objects
[1] );
6663 if (!tar
|| tar
->Type
!=ST_ACTOR
) {
6666 SetupWishCore(Sender
, ((Actor
*)tar
)->GetStat(IE_WIS
), parameters
->int0Parameter
);
6669 //GemRB specific action
6670 //Sets up multiple tokens randomly (one per 2da row)
6671 //the row label column sets the token names
6672 void GameScript::SetToken2DA(Scriptable
* /*Sender*/, Action
* parameters
)
6676 ieVariable tokenname
;
6678 AutoTable
tm(parameters
->string0Parameter
);
6680 printStatus( "ERROR", LIGHT_RED
);
6681 printf( "Cannot find %s.2da.\n", parameters
->string0Parameter
);
6685 count
= tm
->GetRowCount();
6686 for(i
=0;i
<count
;i
++) {
6687 //roll a random number between 0 and column #
6688 j
= core
->Roll(1,tm
->GetColumnCount(i
),-1);
6689 strnuprcpy(tokenname
, tm
->GetRowName(i
), 32);
6690 core
->GetTokenDictionary()->SetAtCopy( tokenname
, tm
->QueryField(i
, j
) );
6694 //this is a gemrb extension for scriptable tracks
6695 void GameScript::SetTrackString(Scriptable
* Sender
, Action
* parameters
)
6697 Map
*map
= Sender
->GetCurrentArea();
6699 map
->SetTrackString(parameters
->int0Parameter
, parameters
->int1Parameter
, parameters
->int2Parameter
);
6702 void GameScript::StateOverrideFlag(Scriptable
* /*Sender*/, Action
* parameters
)
6704 core
->GetGame()->StateOverrideFlag
= parameters
->int0Parameter
;
6707 void GameScript::StateOverrideTime(Scriptable
* /*Sender*/, Action
* parameters
)
6709 core
->GetGame()->StateOverrideTime
= parameters
->int0Parameter
;
6712 void GameScript::BanterBlockFlag(Scriptable
* /*Sender*/, Action
* parameters
)
6714 core
->GetGame()->BanterBlockFlag
= parameters
->int0Parameter
;
6717 void GameScript::BanterBlockTime(Scriptable
* /*Sender*/, Action
* parameters
)
6719 core
->GetGame()->BanterBlockTime
= parameters
->int0Parameter
;