1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 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 "GUIScript.h"
23 #include "PythonHelpers.h"
27 #include "ControlAnimation.h"
28 #include "DataFileMgr.h"
29 #include "EffectQueue.h"
30 #include "GSUtils.h" //checkvariable
32 #include "GameControl.h"
34 #include "ImageFactory.h"
36 #include "Interface.h"
40 #include "MapControl.h"
43 #include "PalettedImageMgr.h"
44 #include "ResourceDesc.h"
45 #include "SaveGameIterator.h"
51 #include "WorldMapControl.h"
57 //this stuff is missing from Python 2.2
59 #define PyDoc_VAR(name) static char name[]
63 # ifdef WITH_DOC_STRINGS
64 # define PyDoc_STR(str) str
66 # define PyDoc_STR(str) ""
71 #define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
74 // a shorthand for declaring methods in method table
75 #define METHOD(name, args) {#name, GemRB_ ## name, args, GemRB_ ## name ## __doc}
77 static int SpecialItemsCount
= -1;
78 static int SpecialSpellsCount
= -1;
79 static int StoreSpellsCount
= -1;
80 static int UsedItemsCount
= -1;
81 static int ItemSoundsCount
= -1;
83 //#define UIT_ALLOW_REPLACE 1 //item is replaceable with another item on this list
87 ieVariable username
; //death variable
89 // int flags; //UIT flags
92 struct SpellDescType
{
97 typedef char EventNameType
[17];
101 typedef ieResRef ResRefPairs
[2];
103 #define UNINIT_IEDWORD 0xcccccccc
105 static SpellDescType
*SpecialItems
= NULL
;
106 static SpellDescType
*SpecialSpells
= NULL
;
108 #define SP_IDENTIFY 1 //any spell that cannot be cast from the menu
109 #define SP_SILENCE 2 //any spell that can be cast in silence
111 static SpellDescType
*StoreSpells
= NULL
;
112 static ItemExtHeader
*ItemArray
= NULL
;
113 static SpellExtHeader
*SpellArray
= NULL
;
114 static UsedItemType
*UsedItems
= NULL
;
115 static ResRefPairs
*ItemSounds
= NULL
;
117 static int ReputationIncrease
[20]={(int) UNINIT_IEDWORD
};
118 static int ReputationDonation
[20]={(int) UNINIT_IEDWORD
};
119 //4 action button indices are packed on a single ieDword, there are 32 actions max.
120 //there are additional fake action buttons
121 static ieDword GUIAction
[MAX_ACT_COUNT
]={UNINIT_IEDWORD
};
122 static ieDword GUITooltip
[MAX_ACT_COUNT
]={UNINIT_IEDWORD
};
123 static ieResRef GUIResRef
[MAX_ACT_COUNT
];
124 static EventNameType GUIEvent
[MAX_ACT_COUNT
];
125 static bool QuitOnError
= false;
127 // Natural screen size of currently loaded winpack
128 static int CHUWidth
= 0;
129 static int CHUHeight
= 0;
131 static EffectRef fx_learn_spell_ref
={"Spell:Learn",NULL
,-1};
133 // Like PyString_FromString(), but for ResRef
134 inline PyObject
* PyString_FromResRef(char* ResRef
)
136 unsigned int i
= strnlen(ResRef
,sizeof(ieResRef
));
137 return PyString_FromStringAndSize( ResRef
, i
);
140 // Like PyString_FromString(), but for ResRef
141 inline PyObject
* PyString_FromAnimID(const char* AnimID
)
143 unsigned int i
= strnlen(AnimID
,2);
144 return PyString_FromStringAndSize( AnimID
, i
);
147 /* Sets RuntimeError exception and returns NULL, so this function
148 * can be called in `return'.
150 inline PyObject
* RuntimeError(const char* msg
)
152 printMessage( "GUIScript", "Runtime Error:\n", LIGHT_RED
);
153 PyErr_SetString( PyExc_RuntimeError
, msg
);
160 /* Prints error msg for invalid function parameters and also the function's
161 * doc string (given as an argument). Then returns NULL, so this function
162 * can be called in `return'. The exception should be set by previous
163 * call to e.g. PyArg_ParseTuple()
165 inline PyObject
* AttributeError(const char* doc_string
)
167 printMessage( "GUIScript", "Syntax Error:\n", LIGHT_RED
);
168 PyErr_SetString(PyExc_AttributeError
, doc_string
);
175 inline Control
*GetControl( int wi
, int ci
, int ct
)
177 char errorbuffer
[256];
179 Window
* win
= core
->GetWindow( wi
);
181 snprintf(errorbuffer
, sizeof(errorbuffer
), "Cannot find window index #%d (unloaded?)", wi
);
182 RuntimeError(errorbuffer
);
185 Control
* ctrl
= win
->GetControl( ci
);
187 snprintf(errorbuffer
, sizeof(errorbuffer
), "Cannot find control #%d", ci
);
188 RuntimeError(errorbuffer
);
191 if ((ct
>=0) && (ctrl
->ControlType
!= ct
)) {
192 snprintf(errorbuffer
, sizeof(errorbuffer
), "Invalid control type: %d!=%d", ctrl
->ControlType
, ct
);
193 RuntimeError(errorbuffer
);
199 //sets tooltip with Fx key prepended
200 static inline void SetFunctionTooltip(int WindowIndex
, int ControlIndex
, char *txt
, int Function
)
204 char *txt2
= (char *) malloc(strlen(txt
)+10);
206 sprintf(txt2
,"F%d - %s",Function
,txt
);
208 sprintf(txt2
,"F%d - %s",ControlIndex
+1,txt
);
210 core
->FreeString(txt
);
211 core
->SetTooltip((ieWord
) WindowIndex
, (ieWord
) ControlIndex
, txt2
);
215 core
->FreeString(txt
);
217 core
->SetTooltip((ieWord
) WindowIndex
, (ieWord
) ControlIndex
, "");
220 static void ReadItemSounds()
222 int table
= gamedata
->LoadTable( "itemsnd" );
228 Holder
<TableMgr
> tab
= gamedata
->GetTable( table
);
229 ItemSoundsCount
= tab
->GetRowCount();
230 ItemSounds
= (ResRefPairs
*) malloc( sizeof(ResRefPairs
)*ItemSoundsCount
);
231 for (int i
= 0; i
< ItemSoundsCount
; i
++) {
232 strnlwrcpy(ItemSounds
[i
][0], tab
->QueryField(i
,0), 8);
233 strnlwrcpy(ItemSounds
[i
][1], tab
->QueryField(i
,1), 8);
235 gamedata
->DelTable( table
);
238 static void GetItemSound(ieResRef
&Sound
, ieDword ItemType
, const char *ID
, ieDword Col
)
245 if (ItemSoundsCount
<0) {
250 //the last 4 item sounds are used for '1A', '2A', '3A' and '4A'
251 //item animation types
252 ItemType
= ItemSoundsCount
-4+ID
[0]-'1';
255 if (ItemType
>=(ieDword
) ItemSoundsCount
) {
258 strnlwrcpy(Sound
, ItemSounds
[ItemType
][Col
], 8);
261 static int GetCreatureStrRef(Actor
*actor
, unsigned int Str
)
263 return actor
->StrRefs
[Str
];
266 static inline bool CheckStat(Actor
* actor
, ieDword stat
, ieDword value
, int op
)
268 int dc
= DiffCore(actor
->GetBase(stat
), value
, op
);
272 static int GetCreatureStat(Actor
*actor
, unsigned int StatID
, int Mod
)
275 return actor
->GetStat( StatID
);
277 return actor
->GetBase( StatID
);
280 static int SetCreatureStat(Actor
*actor
, unsigned int StatID
, int StatValue
)
282 actor
->SetBase( StatID
, StatValue
);
283 actor
->CreateDerivedStats();
287 /* create an item entry
288 TODO: this code snippet exists in many copies, maybe consolidate */
289 static CREItem
*CreateCreItem(const char *ItemResRef
, int Charge0
, int Charge1
, int Charge2
)
291 CREItem
*TmpItem
= new CREItem();
292 strnlwrcpy(TmpItem
->ItemResRef
, ItemResRef
, 8);
294 TmpItem
->Usages
[0]=(ieWord
) Charge0
;
295 TmpItem
->Usages
[1]=(ieWord
) Charge1
;
296 TmpItem
->Usages
[2]=(ieWord
) Charge2
;
298 if (core
->ResolveRandomItem(TmpItem
) && gamedata
->Exists(TmpItem
->ItemResRef
, IE_ITM_CLASS_ID
)) {
301 /* item couldn't be resolved */
306 PyDoc_STRVAR( GemRB_SetInfoTextColor__doc
,
307 "SetInfoTextColor(red, green, blue, [alpha])\n\n"
308 "Sets the color of Floating Messages in GameControl." );
310 static PyObject
* GemRB_SetInfoTextColor(PyObject
*, PyObject
* args
)
314 if (!PyArg_ParseTuple( args
, "iii|i", &r
, &g
, &b
, &a
)) {
315 return AttributeError( GemRB_SetInfoTextColor__doc
);
318 core
->SetInfoTextColor( c
);
319 Py_INCREF( Py_None
);
323 PyDoc_STRVAR( GemRB_UnhideGUI__doc
,
325 "Shows the Game GUI and redraws windows." );
327 static PyObject
* GemRB_UnhideGUI(PyObject
*, PyObject
* /*args*/)
329 GameControl
* gc
= (GameControl
*) GetControl( 0, 0, IE_GUI_GAMECONTROL
);
331 return RuntimeError("No gamecontrol!");
334 //this enables mouse in dialogs, which is wrong
335 //gc->SetCutSceneMode( false );
336 Py_INCREF( Py_None
);
340 PyDoc_STRVAR( GemRB_HideGUI__doc
,
341 "HideGUI()=>returns 1 if it did something\n\n"
342 "Hides the Game GUI." );
344 static PyObject
* GemRB_HideGUI(PyObject
*, PyObject
* /*args*/)
346 GameControl
* gc
= (GameControl
*) GetControl( 0, 0, IE_GUI_GAMECONTROL
);
348 return RuntimeError("No gamecontrol!");
350 int ret
= gc
->HideGUI();
352 return PyInt_FromLong( ret
);
355 PyDoc_STRVAR( GemRB_GetGameString__doc
,
356 "GetGameString(Index) => string\n\n"
357 "Returns various string attributes of the Game object, see the docs.");
359 static PyObject
* GemRB_GetGameString(PyObject
*, PyObject
* args
)
363 if (!PyArg_ParseTuple( args
, "i", &Index
)) {
364 return AttributeError( GemRB_GetGameString__doc
);
367 case 0: //game strings
368 Game
*game
= core
->GetGame();
370 return PyString_FromString("");
374 return PyString_FromString( game
->LoadMos
);
376 return PyString_FromString( game
->CurrentArea
);
380 return AttributeError( GemRB_GetGameString__doc
);
383 PyDoc_STRVAR( GemRB_LoadGame__doc
,
384 "LoadGame(Index)\n\n"
385 "Loads and enters the Game." );
387 static PyObject
* GemRB_LoadGame(PyObject
*, PyObject
* args
)
390 int VersionOverride
= 0;
392 if (!PyArg_ParseTuple( args
, "O|i", &obj
, &VersionOverride
)) {
393 return AttributeError( GemRB_LoadGame__doc
);
395 CObject
<SaveGame
> save(obj
);
396 core
->SetupLoadGame(save
.get(), VersionOverride
);
397 Py_INCREF( Py_None
);
401 PyDoc_STRVAR( GemRB_EnterGame__doc
,
403 "Starts new game and enters it." );
405 static PyObject
* GemRB_EnterGame(PyObject
*, PyObject
* /*args*/)
407 core
->QuitFlag
|=QF_ENTERGAME
;
409 Py_INCREF( Py_None
);
413 PyDoc_STRVAR( GemRB_QuitGame__doc
,
415 "Stops the current game.");
416 static PyObject
* GemRB_QuitGame(PyObject
*, PyObject
* /*args*/)
418 core
->QuitFlag
=QF_QUITGAME
;
419 Py_INCREF( Py_None
);
423 PyDoc_STRVAR( GemRB_TextArea_MoveText__doc
,
424 "MoveTAText(srcWin, srcCtrl, dstWin, dstCtrl)\n\n"
425 "Copies a TextArea content to another.");
427 static PyObject
* GemRB_TextArea_MoveText(PyObject
* /*self*/, PyObject
* args
)
429 int srcWin
, srcCtrl
, dstWin
, dstCtrl
;
431 if (!PyArg_ParseTuple( args
, "iiii", &srcWin
, &srcCtrl
, &dstWin
, &dstCtrl
)) {
432 return AttributeError( GemRB_TextArea_MoveText__doc
);
435 TextArea
* SrcTA
= ( TextArea
* ) GetControl( srcWin
, srcCtrl
, IE_GUI_TEXTAREA
);
440 TextArea
* DstTA
= ( TextArea
* ) GetControl( dstWin
, dstCtrl
, IE_GUI_TEXTAREA
);
445 SrcTA
->CopyTo( DstTA
);
447 Py_INCREF( Py_None
);
451 PyDoc_STRVAR( GemRB_TextArea_Rewind__doc
,
452 "RewindTA(Win, Ctrl, Ticks)\n\n"
453 "Sets up a TextArea for scrolling. Ticks is the delay between the steps in scrolling.");
455 static PyObject
* GemRB_TextArea_Rewind(PyObject
* /*self*/, PyObject
* args
)
457 int Win
, Ctrl
, Ticks
;
459 if (!PyArg_ParseTuple( args
, "iii", &Win
, &Ctrl
, &Ticks
)) {
460 return AttributeError( GemRB_TextArea_Rewind__doc
);
463 TextArea
* ctrl
= ( TextArea
* ) GetControl( Win
, Ctrl
, IE_GUI_TEXTAREA
);
468 ctrl
->SetupScroll(Ticks
);
469 Py_INCREF( Py_None
);
473 PyDoc_STRVAR( GemRB_TextArea_SetHistory__doc
,
474 "SetTAHistory(Win, Ctrl, KeepLines)\n\n"
475 "Sets up a TextArea to expire scrolled out lines.");
477 static PyObject
* GemRB_TextArea_SetHistory(PyObject
* /*self*/, PyObject
* args
)
481 if (!PyArg_ParseTuple( args
, "iii", &Win
, &Ctrl
, &Keep
)) {
482 return AttributeError( GemRB_TextArea_SetHistory__doc
);
485 TextArea
* ctrl
= ( TextArea
* ) GetControl( Win
, Ctrl
, IE_GUI_TEXTAREA
);
490 ctrl
->SetPreservedRow(Keep
);
491 Py_INCREF( Py_None
);
495 PyDoc_STRVAR( GemRB_StatComment__doc
,
496 "StatComment(Strref, X, Y) => string\n\n"
497 "Replaces values X and Y into an strref in place of %%d." );
499 static PyObject
* GemRB_StatComment(PyObject
* /*self*/, PyObject
* args
)
505 if (!PyArg_ParseTuple( args
, "iii", &Strref
, &X
, &Y
)) {
506 return AttributeError( GemRB_StatComment__doc
);
508 char* text
= core
->GetString( Strref
);
509 size_t bufflen
= strlen( text
) + 12;
511 return AttributeError( GemRB_StatComment__doc
);
513 char* newtext
= ( char* ) malloc( bufflen
);
514 //this could be DANGEROUS, not anymore (snprintf is your friend)
515 snprintf( newtext
, bufflen
, text
, X
, Y
);
516 core
->FreeString( text
);
517 ret
= PyString_FromString( newtext
);
522 PyDoc_STRVAR( GemRB_GetString__doc
,
523 "GetString(strref[,flags]) => string\n\n"
524 "Returns string for given strref. " );
526 static PyObject
* GemRB_GetString(PyObject
* /*self*/, PyObject
* args
)
532 if (!PyArg_ParseTuple( args
, "i|i", &strref
, &flags
)) {
533 return AttributeError( GemRB_GetString__doc
);
536 char *text
= core
->GetString( strref
, flags
);
537 ret
=PyString_FromString( text
);
538 core
->FreeString( text
);
542 PyDoc_STRVAR( GemRB_EndCutSceneMode__doc
,
543 "EndCutSceneMode()\n\n"
544 "Exits the CutScene Mode." );
546 static PyObject
* GemRB_EndCutSceneMode(PyObject
* /*self*/, PyObject
* /*args*/)
548 core
->SetCutSceneMode( false );
549 Py_INCREF( Py_None
);
553 PyDoc_STRVAR( GemRB_LoadWindowPack__doc
,
554 "LoadWindowPack(CHUIResRef, [Width=0, Height=0])\n\n"
555 "Loads a WindowPack into the Window Manager Module. "
556 "Width and Height set winpack's natural screen size if nonzero." );
558 static PyObject
* GemRB_LoadWindowPack(PyObject
* /*self*/, PyObject
* args
)
561 int width
= 0, height
= 0;
563 if (!PyArg_ParseTuple( args
, "s|ii", &string
, &width
, &height
)) {
564 return AttributeError( GemRB_LoadWindowPack__doc
);
567 if (!core
->LoadWindowPack( string
)) {
568 return RuntimeError("Can't find resource");
574 if ( (width
&& (width
>core
->Width
)) ||
575 (height
&& (height
>core
->Height
)) ) {
576 printMessage("GUIScript","Screen is too small!\n",LIGHT_RED
);
577 printf("This window requires %d x %d resolution.\n",width
,height
);
578 return RuntimeError("Please change your settings.");
580 Py_INCREF( Py_None
);
584 PyDoc_STRVAR( GemRB_LoadWindow__doc
,
585 "LoadWindow(WindowID) => WindowIndex\n\n"
586 "Returns a Window." );
588 static PyObject
* GemRB_LoadWindow(PyObject
* /*self*/, PyObject
* args
)
592 if (!PyArg_ParseTuple( args
, "i", &WindowID
)) {
593 return AttributeError( GemRB_LoadWindow__doc
);
596 int ret
= core
->LoadWindow( WindowID
);
599 snprintf( buf
, sizeof( buf
), "Can't find window #%d!", WindowID
);
600 return RuntimeError(buf
);
603 // If the current winpack windows are placed for screen resolution
604 // other than the current one, reposition them
605 Window
* win
= core
->GetWindow( ret
);
606 if (CHUWidth
&& CHUWidth
!= core
->Width
)
607 win
->XPos
+= (core
->Width
- CHUWidth
) / 2;
608 if (CHUHeight
&& CHUHeight
!= core
->Height
)
609 win
->YPos
+= (core
->Height
- CHUHeight
) / 2;
611 return gs
->ConstructObject("Window", ret
);
614 PyDoc_STRVAR( GemRB_Window_SetSize__doc
,
615 "SetWindowSize(WindowIndex, Width, Height)\n\n"
616 "Resizes a Window.");
618 static PyObject
* GemRB_Window_SetSize(PyObject
* /*self*/, PyObject
* args
)
620 int WindowIndex
, Width
, Height
;
622 if (!PyArg_ParseTuple( args
, "iii", &WindowIndex
, &Width
, &Height
)) {
623 return AttributeError( GemRB_Window_SetSize__doc
);
626 Window
* win
= core
->GetWindow( WindowIndex
);
628 return RuntimeError("Cannot find window!\n");
632 win
->Height
= Height
;
635 Py_INCREF( Py_None
);
639 PyDoc_STRVAR( GemRB_Window_SetFrame__doc
,
640 "SetWindowFrame(WindowIndex)\n\n"
641 "Sets Window frame used to fill screen on higher resolutions.");
643 static PyObject
* GemRB_Window_SetFrame(PyObject
* /*self*/, PyObject
* args
)
647 if (!PyArg_ParseTuple( args
, "i", &WindowIndex
)) {
648 return AttributeError( GemRB_Window_SetFrame__doc
);
651 Window
* win
= core
->GetWindow( WindowIndex
);
653 return RuntimeError("Cannot find window!\n");
658 Py_INCREF( Py_None
);
662 PyDoc_STRVAR( GemRB_LoadWindowFrame__doc
,
663 "LoadWindowFrame(MOSResRef_Left, MOSResRef_Right, MOSResRef_Top, MOSResRef_Bottom))\n\n"
664 "Load the parts of window frame used to decorate windows on higher resolutions." );
666 static PyObject
* GemRB_LoadWindowFrame(PyObject
* /*self*/, PyObject
* args
)
670 if (!PyArg_ParseTuple( args
, "ssss", &ResRef
[0], &ResRef
[1], &ResRef
[2], &ResRef
[3] )) {
671 return AttributeError( GemRB_LoadWindowFrame__doc
);
675 for (int i
= 0; i
< 4; i
++) {
676 if (ResRef
[i
] == 0) {
677 return AttributeError( GemRB_LoadWindowFrame__doc
);
680 ResourceHolder
<ImageMgr
> im(ResRef
[i
]);
685 Sprite2D
* Picture
= im
->GetSprite2D();
686 if (Picture
== NULL
) {
690 // FIXME: delete previous WindowFrames
691 //core->WindowFrames[i] = Picture;
692 core
->SetWindowFrame(i
, Picture
);
695 Py_INCREF( Py_None
);
700 PyDoc_STRVAR( GemRB_EnableCheatKeys__doc
,
701 "EnableCheatKeys(flag)\n\n"
702 "Sets CheatFlags." );
704 static PyObject
* GemRB_EnableCheatKeys(PyObject
* /*self*/, PyObject
* args
)
708 if (!PyArg_ParseTuple( args
, "i", &Flag
)) {
709 return AttributeError( GemRB_EnableCheatKeys__doc
);
712 core
->EnableCheatKeys( Flag
);
714 Py_INCREF( Py_None
);
718 PyDoc_STRVAR( GemRB_Window_SetPicture__doc
,
719 "SetWindowPicture(WindowIndex, MosResRef)\n\n"
720 "Changes the background of a Window." );
722 static PyObject
* GemRB_Window_SetPicture(PyObject
* /*self*/, PyObject
* args
)
727 if (!PyArg_ParseTuple( args
, "is", &WindowIndex
, &MosResRef
)) {
728 return AttributeError( GemRB_Window_SetPicture__doc
);
731 Window
* win
= core
->GetWindow( WindowIndex
);
733 return RuntimeError("Cannot find window!\n");
736 ResourceHolder
<ImageMgr
> mos(MosResRef
);
738 win
->SetBackGround( mos
->GetSprite2D(), true );
742 Py_INCREF( Py_None
);
746 PyDoc_STRVAR( GemRB_Window_SetPos__doc
,
747 "SetWindowPos(WindowIndex, X, Y, [Flags=WINDOW_TOPLEFT])\n\n"
748 "Moves a Window to pos. (X, Y).\n"
749 "Flags is a bitmask of WINDOW_(TOPLEFT|CENTER|ABSCENTER|RELATIVE|SCALE|BOUNDED) and "
750 "they are used to modify the meaning of X and Y.\n"
751 "TOPLEFT: X, Y are coordinates of upper-left corner.\n"
752 "CENTER: X, Y are coordinates of window's center.\n"
753 "ABSCENTER: window is placed at screen center, moved by X, Y.\n"
754 "RELATIVE: window is moved by X, Y.\n"
755 "SCALE: window is moved by diff of screen size and X, Y, divided by 2.\n"
756 "BOUNDED: the window is kept within screen boundaries." );
758 static PyObject
* GemRB_Window_SetPos(PyObject
* /*self*/, PyObject
* args
)
760 int WindowIndex
, X
, Y
, Flags
= WINDOW_TOPLEFT
;
762 if (!PyArg_ParseTuple( args
, "iii|i", &WindowIndex
, &X
, &Y
, &Flags
)) {
763 return AttributeError( GemRB_Window_SetPos__doc
);
766 Window
* win
= core
->GetWindow( WindowIndex
);
768 return RuntimeError("Cannot find window!\n");
771 if (Flags
& WINDOW_CENTER
) {
773 Y
-= win
->Height
/ 2;
775 else if (Flags
& WINDOW_ABSCENTER
) {
776 X
+= (core
->Width
- win
->Width
) / 2;
777 Y
+= (core
->Height
- win
->Height
) / 2;
779 else if (Flags
& WINDOW_RELATIVE
) {
783 else if (Flags
& WINDOW_SCALE
) {
784 X
= win
->XPos
+ (core
->Width
- X
) / 2;
785 Y
= win
->YPos
+ (core
->Height
- Y
) / 2;
788 // Keep window within screen
789 // FIXME: keep it within gamecontrol
790 if (Flags
& WINDOW_BOUNDED
) {
791 // FIXME: grrrr, should be < 0!!!
792 if (X
> 32767 || X
< 0)
794 if (Y
> 32767 || Y
< 0)
797 if (X
+ win
->Width
>= core
->Width
)
798 X
= core
->Width
- win
->Width
;
799 if (Y
+ win
->Height
>= core
->Height
)
800 Y
= core
->Height
- win
->Height
;
807 Py_INCREF( Py_None
);
811 PyDoc_STRVAR( GemRB_LoadTable__doc
,
812 "LoadTable(2DAResRef, [ignore_error=0]) => GTable\n\n"
813 "Loads a 2DA Table." );
815 static PyObject
* GemRB_LoadTable(PyObject
* /*self*/, PyObject
* args
)
820 if (!PyArg_ParseTuple( args
, "s|i", &tablename
, &noerror
)) {
821 return AttributeError( GemRB_LoadTable__doc
);
824 int ind
= gamedata
->LoadTable( tablename
);
825 if (!noerror
&& ind
== -1) {
826 return RuntimeError("Can't find resource");
828 return gs
->ConstructObject("Table", ind
);
831 PyDoc_STRVAR( GemRB_Table_Unload__doc
,
832 "UnloadTable(TableIndex)\n\n"
833 "Unloads a 2DA Table." );
835 static PyObject
* GemRB_Table_Unload(PyObject
* /*self*/, PyObject
* args
)
839 if (!PyArg_ParseTuple( args
, "i", &ti
)) {
840 return AttributeError( GemRB_Table_Unload__doc
);
843 int ind
= gamedata
->DelTable( ti
);
845 return RuntimeError("Can't find resource");
848 Py_INCREF( Py_None
);
852 PyDoc_STRVAR( GemRB_Table_GetValue__doc
,
853 "GetTableValue(TableIndex, RowIndex/RowString, ColIndex/ColString, type) => value\n\n"
854 "Returns a field of a 2DA Table. If Type is omitted the return type is the autodetected, "
855 "otherwise 0 means string, 1 means integer, 2 means stat symbol translation." );
857 static PyObject
* GemRB_Table_GetValue(PyObject
* /*self*/, PyObject
* args
)
859 PyObject
* ti
, * row
, * col
;
860 PyObject
* type
= NULL
;
863 if (!PyArg_UnpackTuple( args
, "ref", 3, 4, &ti
, &row
, &col
, &type
)) {
864 return AttributeError( GemRB_Table_GetValue__doc
);
867 if (!PyObject_TypeCheck( type
, &PyInt_Type
)) {
868 return AttributeError( GemRB_Table_GetValue__doc
);
870 which
= PyInt_AsLong( type
);
873 if (!PyObject_TypeCheck( ti
, &PyInt_Type
)) {
874 return AttributeError( GemRB_Table_GetValue__doc
);
876 long TableIndex
= PyInt_AsLong( ti
);
877 if (( !PyObject_TypeCheck( row
, &PyInt_Type
) ) &&
878 ( !PyObject_TypeCheck( row
, &PyString_Type
) )) {
879 return AttributeError( GemRB_Table_GetValue__doc
);
881 if (( !PyObject_TypeCheck( col
, &PyInt_Type
) ) &&
882 ( !PyObject_TypeCheck( col
, &PyString_Type
) )) {
883 return AttributeError( GemRB_Table_GetValue__doc
);
885 if (PyObject_TypeCheck( row
, &PyInt_Type
) &&
886 ( !PyObject_TypeCheck( col
, &PyInt_Type
) )) {
887 printMessage( "GUIScript",
888 "Type Error: RowIndex/RowString and ColIndex/ColString must be the same type\n",
892 if (PyObject_TypeCheck( row
, &PyString_Type
) &&
893 ( !PyObject_TypeCheck( col
, &PyString_Type
) )) {
894 printMessage( "GUIScript",
895 "Type Error: RowIndex/RowString and ColIndex/ColString must be the same type\n",
899 Holder
<TableMgr
> tm
= gamedata
->GetTable( TableIndex
);
901 return RuntimeError("Can't find resource");
904 if (PyObject_TypeCheck( row
, &PyString_Type
)) {
905 char* rows
= PyString_AsString( row
);
906 char* cols
= PyString_AsString( col
);
907 ret
= tm
->QueryField( rows
, cols
);
909 long rowi
= PyInt_AsLong( row
);
910 long coli
= PyInt_AsLong( col
);
911 ret
= tm
->QueryField( rowi
, coli
);
917 //if which = 0, then return string
919 return PyString_FromString( ret
);
921 //if which = 1 then return number
922 //if which = -1 (omitted) then return the best format
923 if (valid_number( ret
, val
) || (which
==1) ) {
924 return PyInt_FromLong( val
);
927 val
= core
->TranslateStat(ret
);
928 return PyInt_FromLong( val
);
930 return PyString_FromString( ret
);
933 PyDoc_STRVAR( GemRB_Table_FindValue__doc
,
934 "FindTableValue(TableIndex, ColumnIndex, Value[, StartRow]) => Row\n\n"
935 "Returns the first rowcount of a field of a 2DA Table." );
937 static PyObject
* GemRB_Table_FindValue(PyObject
* /*self*/, PyObject
* args
)
943 if (!PyArg_ParseTuple( args
, "iil|i", &ti
, &col
, &Value
, &start
)) {
944 return AttributeError( GemRB_Table_FindValue__doc
);
947 Holder
<TableMgr
> tm
= gamedata
->GetTable( ti
);
949 return RuntimeError("Can't find resource");
951 return PyInt_FromLong(tm
->FindTableValue(col
, Value
, start
));
954 PyDoc_STRVAR( GemRB_Table_GetRowIndex__doc
,
955 "GetTableRowIndex(TableIndex, RowName) => Row\n\n"
956 "Returns the Index of a Row in a 2DA Table." );
958 static PyObject
* GemRB_Table_GetRowIndex(PyObject
* /*self*/, PyObject
* args
)
963 if (!PyArg_ParseTuple( args
, "is", &ti
, &rowname
)) {
964 return AttributeError( GemRB_Table_GetRowIndex__doc
);
967 Holder
<TableMgr
> tm
= gamedata
->GetTable( ti
);
969 return RuntimeError("Can't find resource");
971 int row
= tm
->GetRowIndex( rowname
);
972 //no error if the row doesn't exist
973 return PyInt_FromLong( row
);
976 PyDoc_STRVAR( GemRB_Table_GetRowName__doc
,
977 "GetTableRowName(TableIndex, RowIndex) => string\n\n"
978 "Returns the Name of a Row in a 2DA Table." );
980 static PyObject
* GemRB_Table_GetRowName(PyObject
* /*self*/, PyObject
* args
)
984 if (!PyArg_ParseTuple( args
, "ii", &ti
, &row
)) {
985 return AttributeError( GemRB_Table_GetRowName__doc
);
988 Holder
<TableMgr
> tm
= gamedata
->GetTable( ti
);
990 return RuntimeError("Can't find resource");
992 const char* str
= tm
->GetRowName( row
);
997 return PyString_FromString( str
);
1000 PyDoc_STRVAR( GemRB_Table_GetColumnIndex__doc
,
1001 "GetTableColumnIndex(TableIndex, ColumnName) => Column\n\n"
1002 "Returns the Index of a Column in a 2DA Table." );
1004 static PyObject
* GemRB_Table_GetColumnIndex(PyObject
* /*self*/, PyObject
* args
)
1009 if (!PyArg_ParseTuple( args
, "is", &ti
, &colname
)) {
1010 return AttributeError( GemRB_Table_GetColumnIndex__doc
);
1013 Holder
<TableMgr
> tm
= gamedata
->GetTable( ti
);
1015 return RuntimeError("Can't find resource");
1017 int col
= tm
->GetColumnIndex( colname
);
1018 //no error if the column doesn't exist
1019 return PyInt_FromLong( col
);
1022 PyDoc_STRVAR( GemRB_Table_GetColumnName__doc
,
1023 "GetTableColumnName(TableIndex, ColumnIndex) => string\n\n"
1024 "Returns the Name of a Column in a 2DA Table." );
1026 static PyObject
* GemRB_Table_GetColumnName(PyObject
* /*self*/, PyObject
* args
)
1030 if (!PyArg_ParseTuple( args
, "ii", &ti
, &col
)) {
1031 return AttributeError( GemRB_Table_GetColumnName__doc
);
1034 Holder
<TableMgr
> tm
= gamedata
->GetTable( ti
);
1036 return RuntimeError("Can't find resource");
1038 const char* str
= tm
->GetColumnName( col
);
1043 return PyString_FromString( str
);
1046 PyDoc_STRVAR( GemRB_Table_GetRowCount__doc
,
1047 "GetTableRowCount(TableIndex) => RowCount\n\n"
1048 "Returns the number of rows in a 2DA Table." );
1050 static PyObject
* GemRB_Table_GetRowCount(PyObject
* /*self*/, PyObject
* args
)
1054 if (!PyArg_ParseTuple( args
, "i", &ti
)) {
1055 return AttributeError( GemRB_Table_GetRowCount__doc
);
1058 Holder
<TableMgr
> tm
= gamedata
->GetTable( ti
);
1060 return RuntimeError("Can't find resource");
1063 return PyInt_FromLong( tm
->GetRowCount() );
1066 PyDoc_STRVAR( GemRB_Table_GetColumnCount__doc
,
1067 "GetTableColumnCount(TableIndex[, Row]) => ColumnCount\n\n"
1068 "Returns the number of columns in the given row of a 2DA Table. Row may be omitted." );
1070 static PyObject
* GemRB_Table_GetColumnCount(PyObject
* /*self*/, PyObject
* args
)
1075 if (!PyArg_ParseTuple( args
, "i|i", &ti
, &row
)) {
1076 return AttributeError( GemRB_Table_GetColumnCount__doc
);
1079 Holder
<TableMgr
> tm
= gamedata
->GetTable( ti
);
1081 return RuntimeError("Can't find resource");
1084 return PyInt_FromLong( tm
->GetColumnCount(row
) );
1087 PyDoc_STRVAR( GemRB_LoadSymbol__doc
,
1088 "LoadSymbol(IDSResRef) => SymbolIndex\n\n"
1089 "Loads an IDS Symbol Table." );
1091 static PyObject
* GemRB_LoadSymbol(PyObject
* /*self*/, PyObject
* args
)
1095 if (!PyArg_ParseTuple( args
, "s", &string
)) {
1096 return AttributeError( GemRB_LoadSymbol__doc
);
1099 int ind
= core
->LoadSymbol( string
);
1104 return gs
->ConstructObject("Symbol", ind
);
1107 PyDoc_STRVAR( GemRB_Symbol_Unload__doc
,
1108 "UnloadSymbol(SymbolIndex)\n\n"
1109 "Unloads an IDS Symbol Table." );
1111 static PyObject
* GemRB_Symbol_Unload(PyObject
* /*self*/, PyObject
* args
)
1115 if (!PyArg_ParseTuple( args
, "i", &si
)) {
1116 return AttributeError( GemRB_Symbol_Unload__doc
);
1119 int ind
= core
->DelSymbol( si
);
1124 Py_INCREF( Py_None
);
1128 PyDoc_STRVAR( GemRB_Symbol_GetValue__doc
,
1129 "GetSymbolValue(SymbolIndex, StringVal) => int\n"
1130 "GetSymbolValue(SymbolIndex, IntVal) => string\n\n"
1131 "Returns a field of an IDS Symbol Table." );
1133 static PyObject
* GemRB_Symbol_GetValue(PyObject
* /*self*/, PyObject
* args
)
1135 PyObject
* si
, * sym
;
1137 if (PyArg_UnpackTuple( args
, "ref", 2, 2, &si
, &sym
)) {
1138 if (!PyObject_TypeCheck( si
, &PyInt_Type
)) {
1139 return AttributeError( GemRB_Symbol_GetValue__doc
);
1141 long SymbolIndex
= PyInt_AsLong( si
);
1142 if (PyObject_TypeCheck( sym
, &PyString_Type
)) {
1143 char* syms
= PyString_AsString( sym
);
1144 Holder
<SymbolMgr
> sm
= core
->GetSymbol( SymbolIndex
);
1147 long val
= sm
->GetValue( syms
);
1148 return PyInt_FromLong( val
);
1150 if (PyObject_TypeCheck( sym
, &PyInt_Type
)) {
1151 long symi
= PyInt_AsLong( sym
);
1152 Holder
<SymbolMgr
> sm
= core
->GetSymbol( SymbolIndex
);
1155 const char* str
= sm
->GetValue( symi
);
1156 return PyString_FromString( str
);
1159 return AttributeError( GemRB_Symbol_GetValue__doc
);
1162 PyDoc_STRVAR( GemRB_GetControl__doc
,
1163 "GetControl(WindowIndex, ControlID) => ControlIndex\n\n"
1164 "Returns a control in a Window." );
1166 static PyObject
* GemRB_GetControl(PyObject
* /*self*/, PyObject
* args
)
1168 int WindowIndex
, ControlID
;
1170 if (!PyArg_ParseTuple( args
, "ii", &WindowIndex
, &ControlID
)) {
1171 return AttributeError( GemRB_GetControl__doc
);
1175 int ret
= core
->GetControl( WindowIndex
, ControlID
);
1177 return RuntimeError( "Control is not found" );
1180 return PyInt_FromLong( ret
);
1183 PyDoc_STRVAR( GemRB_Window_GetControl__doc
,
1184 "GetControlObject(WindowID, ControlID) => GControl, or\n"
1185 "Window.GetControl(ControlID) => GControl\n\n"
1186 "Returns a control as an object." );
1188 static PyObject
* GemRB_Window_GetControl(PyObject
* self
, PyObject
* args
)
1190 int WindowIndex
, ControlID
;
1192 if (!PyArg_ParseTuple( args
, "ii", &WindowIndex
, &ControlID
)) {
1193 return AttributeError( GemRB_Window_GetControl__doc
);
1196 PyObject
* control
= GemRB_GetControl( self
, args
);
1197 if (!control
|| !PyObject_TypeCheck( control
, &PyInt_Type
))
1198 return control
; // exception
1200 PyObject
* ctrltuple
= PyTuple_New(2);
1201 PyTuple_SET_ITEM(ctrltuple
, 0, PyInt_FromLong(WindowIndex
));
1202 PyTuple_SET_ITEM(ctrltuple
, 1, control
);
1205 // TODO: get this from 'control' python variable
1206 int ctrlindex
= core
->GetControl(WindowIndex
, ControlID
);
1207 Control
*ctrl
= GetControl(WindowIndex
, ctrlindex
, -1);
1209 // GetControl will already have raised an exception
1212 const char* type
= "Control";
1213 switch(ctrl
->ControlType
) {
1220 case IE_GUI_SCROLLBAR
:
1223 case IE_GUI_TEXTAREA
:
1229 case IE_GUI_WORLDMAP
:
1235 ret
= gs
->ConstructObject(type
, ctrltuple
);
1236 Py_DECREF(ctrltuple
);
1240 snprintf( buf
, sizeof( buf
), "Couldn't construct Control object for control %d in window %d!", ControlID
, WindowIndex
);
1241 return RuntimeError(buf
);
1246 PyDoc_STRVAR( GemRB_Window_HasControl__doc
,
1247 "HasControl(WindowIndex, ControlID[, ControlType]) => bool\n\n"
1248 "Returns true if the control exists." );
1250 static PyObject
* GemRB_Window_HasControl(PyObject
* /*self*/, PyObject
* args
)
1252 int WindowIndex
, ControlID
;
1255 if (!PyArg_ParseTuple( args
, "ii|i", &WindowIndex
, &ControlID
, &Type
)) {
1256 return AttributeError( GemRB_Window_HasControl__doc
);
1258 int ret
= core
->GetControl( WindowIndex
, ControlID
);
1260 return PyInt_FromLong( 0 );
1264 Control
*ctrl
= GetControl(WindowIndex
, ControlID
, -1);
1265 if (ctrl
->ControlType
!=Type
) {
1266 return PyInt_FromLong( 0 );
1269 return PyInt_FromLong( 1 );
1272 PyDoc_STRVAR( GemRB_Control_QueryText__doc
,
1273 "QueryText(WindowIndex, ControlIndex) => string\n\n"
1274 "Returns the Text of a TextEdit control." );
1276 static PyObject
* GemRB_Control_QueryText(PyObject
* /*self*/, PyObject
* args
)
1280 if (!PyArg_ParseTuple( args
, "ii", &wi
, &ci
)) {
1281 return AttributeError( GemRB_Control_QueryText__doc
);
1284 Control
*ctrl
= GetControl(wi
, ci
, -1);
1288 switch(ctrl
->ControlType
) {
1290 return PyString_FromString(((Label
*) ctrl
)->QueryText() );
1292 return PyString_FromString(((TextEdit
*) ctrl
)->QueryText() );
1293 case IE_GUI_TEXTAREA
:
1294 return PyString_FromString(((TextArea
*) ctrl
)->QueryText() );
1296 return RuntimeError("Invalid control type");
1300 PyDoc_STRVAR( GemRB_TextEdit_SetBufferLength__doc
,
1301 "SetBufferLength(WindowIndex, ControlIndex, Length)\n\n"
1302 "Sets the maximum text length of a TextEdit Control. It cannot be more than 65535." );
1304 static PyObject
* GemRB_TextEdit_SetBufferLength(PyObject
* /*self*/, PyObject
* args
)
1306 int WindowIndex
, ControlIndex
, Length
;
1308 if (!PyArg_ParseTuple( args
, "iii", &WindowIndex
, &ControlIndex
, &Length
)) {
1309 return AttributeError( GemRB_TextEdit_SetBufferLength__doc
);
1312 TextEdit
* te
= (TextEdit
*) GetControl( WindowIndex
, ControlIndex
, IE_GUI_EDIT
);
1316 if ((ieDword
) Length
>0xffff) {
1317 return AttributeError( GemRB_Control_QueryText__doc
);
1320 te
->SetBufferLength((ieWord
) Length
);
1322 Py_INCREF( Py_None
);
1326 PyDoc_STRVAR( GemRB_Control_SetText__doc
,
1327 "SetText(WindowIndex, ControlIndex, String|Strref) => int\n\n"
1328 "Sets the Text of a control in a Window." );
1330 static PyObject
* GemRB_Control_SetText(PyObject
* /*self*/, PyObject
* args
)
1332 PyObject
* wi
, * ci
, * str
;
1333 long WindowIndex
, ControlIndex
, StrRef
;
1337 if (!PyArg_UnpackTuple( args
, "ref", 3, 3, &wi
, &ci
, &str
)) {
1338 return AttributeError( GemRB_Control_SetText__doc
);
1341 if (!PyObject_TypeCheck( wi
, &PyInt_Type
) ||
1342 !PyObject_TypeCheck( ci
, &PyInt_Type
) ||
1343 ( !PyObject_TypeCheck( str
, &PyString_Type
) &&
1344 !PyObject_TypeCheck( str
, &PyInt_Type
) )) {
1345 return AttributeError( GemRB_Control_SetText__doc
);
1348 WindowIndex
= PyInt_AsLong( wi
);
1349 ControlIndex
= PyInt_AsLong( ci
);
1350 if (PyObject_TypeCheck( str
, &PyString_Type
)) {
1351 string
= PyString_AsString( str
);
1352 if (string
== NULL
) {
1353 return RuntimeError("Null string received");
1355 ret
= core
->SetText( (ieWord
) WindowIndex
, (ieWord
) ControlIndex
, string
);
1357 return RuntimeError("Cannot set text");
1360 StrRef
= PyInt_AsLong( str
);
1362 ret
= core
->SetText( (ieWord
) WindowIndex
, (ieWord
) ControlIndex
, GEMRB_STRING
);
1364 char *tmpstr
= core
->GetString( StrRef
);
1365 ret
= core
->SetText( (ieWord
) WindowIndex
, (ieWord
) ControlIndex
, tmpstr
);
1366 core
->FreeString( tmpstr
);
1369 return RuntimeError("Cannot set text");
1372 return PyInt_FromLong( ret
);
1375 PyDoc_STRVAR( GemRB_TextArea_Append__doc
,
1376 "TextAreaAppend(WindowIndex, ControlIndex, String|Strref [, Row[, Flag]]) => int\n\n"
1377 "Appends the Text to the TextArea Control in the Window. "
1378 "If Row is given then it will insert the text after that row. "
1379 "If Flag is given, then it will use that value as a GetString flag.");
1381 static PyObject
* GemRB_TextArea_Append(PyObject
* /*self*/, PyObject
* args
)
1383 PyObject
* wi
, * ci
, * str
;
1384 PyObject
* row
= NULL
;
1385 PyObject
* flag
= NULL
;
1386 long WindowIndex
, ControlIndex
;
1387 long StrRef
, Row
, Flag
= 0;
1391 if (!PyArg_UnpackTuple( args
, "ref", 3, 5, &wi
, &ci
, &str
, &row
, &flag
)) {
1392 return AttributeError( GemRB_TextArea_Append__doc
);
1394 if (!PyObject_TypeCheck( wi
, &PyInt_Type
) ||
1395 !PyObject_TypeCheck( ci
, &PyInt_Type
) ||
1396 ( !PyObject_TypeCheck( str
, &PyString_Type
) &&
1397 !PyObject_TypeCheck( str
, &PyInt_Type
) )) {
1398 return AttributeError( GemRB_TextArea_Append__doc
);
1400 WindowIndex
= PyInt_AsLong( wi
);
1401 ControlIndex
= PyInt_AsLong( ci
);
1403 TextArea
* ta
= ( TextArea
* ) GetControl( WindowIndex
, ControlIndex
, IE_GUI_TEXTAREA
);
1408 if (!PyObject_TypeCheck( row
, &PyInt_Type
)) {
1409 printMessage( "GUIScript",
1410 "Syntax Error: AppendText row must be integer\n", LIGHT_RED
);
1413 Row
= PyInt_AsLong( row
);
1414 if (Row
> ta
->GetRowCount() - 1)
1417 Row
= ta
->GetRowCount() - 1;
1420 if (!PyObject_TypeCheck( flag
, &PyInt_Type
)) {
1421 printMessage( "GUIScript",
1422 "Syntax Error: GetString flag must be integer\n", LIGHT_RED
);
1425 Flag
= PyInt_AsLong( flag
);
1428 if (PyObject_TypeCheck( str
, &PyString_Type
)) {
1429 string
= PyString_AsString( str
);
1431 return RuntimeError("Null string received");
1432 ret
= ta
->AppendText( string
, Row
);
1434 StrRef
= PyInt_AsLong( str
);
1435 char* str
= core
->GetString( StrRef
, Flag
);
1436 ret
= ta
->AppendText( str
, Row
);
1437 core
->FreeString( str
);
1440 return PyInt_FromLong( ret
);
1443 PyDoc_STRVAR( GemRB_TextArea_Clear__doc
,
1444 "TextAreaClear(WindowIndex, ControlIndex)\n\n"
1445 "Clears the Text from the TextArea Control in the Window." );
1447 static PyObject
* GemRB_TextArea_Clear(PyObject
* /*self*/, PyObject
* args
)
1450 long WindowIndex
, ControlIndex
;
1452 if (!PyArg_UnpackTuple( args
, "ref", 2, 2, &wi
, &ci
)) {
1453 return AttributeError( GemRB_TextArea_Clear__doc
);
1455 if (!PyObject_TypeCheck( wi
, &PyInt_Type
) ||
1456 !PyObject_TypeCheck( ci
, &PyInt_Type
)) {
1457 return AttributeError( GemRB_TextArea_Clear__doc
);
1459 WindowIndex
= PyInt_AsLong( wi
);
1460 ControlIndex
= PyInt_AsLong( ci
);
1461 TextArea
* ta
= ( TextArea
* ) GetControl( WindowIndex
, ControlIndex
, IE_GUI_TEXTAREA
);
1467 Py_INCREF( Py_None
);
1471 PyDoc_STRVAR( GemRB_TextArea_Scroll__doc
,
1472 "TextAreaScroll(WindowIndex, ControlIndex, offset)\n\n"
1473 "Scrolls the textarea up or down by offset." );
1475 static PyObject
* GemRB_TextArea_Scroll(PyObject
* /*self*/, PyObject
* args
)
1477 int WindowIndex
, ControlIndex
, offset
;
1479 if (!PyArg_ParseTuple( args
, "iii", &WindowIndex
, &ControlIndex
, &offset
)) {
1480 return AttributeError( GemRB_TextArea_Scroll__doc
);
1482 TextArea
* ta
= ( TextArea
* ) GetControl( WindowIndex
, ControlIndex
, IE_GUI_TEXTAREA
);
1486 int row
= ta
->GetTopIndex()+offset
;
1492 Py_INCREF( Py_None
);
1496 PyDoc_STRVAR( GemRB_Control_SetTooltip__doc
,
1497 "SetTooltip(WindowIndex, ControlIndex, String|Strref) => int\n\n"
1498 "Sets control's tooltip." );
1500 static PyObject
* GemRB_Control_SetTooltip(PyObject
* /*self*/, PyObject
* args
)
1502 PyObject
* wi
, * ci
, * str
;
1503 long WindowIndex
, ControlIndex
, StrRef
;
1507 if (!PyArg_UnpackTuple( args
, "ref", 3, 3, &wi
, &ci
, &str
)) {
1508 return AttributeError( GemRB_Control_SetTooltip__doc
);
1510 if (!PyObject_TypeCheck( wi
, &PyInt_Type
) ||
1511 !PyObject_TypeCheck( ci
, &PyInt_Type
) ||
1512 ( !PyObject_TypeCheck( str
, &PyString_Type
) &&
1513 !PyObject_TypeCheck( str
, &PyInt_Type
) )) {
1514 return AttributeError( GemRB_Control_SetTooltip__doc
);
1517 WindowIndex
= PyInt_AsLong( wi
);
1518 ControlIndex
= PyInt_AsLong( ci
);
1519 if (PyObject_TypeCheck( str
, &PyString_Type
)) {
1520 string
= PyString_AsString( str
);
1521 if (string
== NULL
) {
1522 return RuntimeError("Null string received");
1524 ret
= core
->SetTooltip( (ieWord
) WindowIndex
, (ieWord
) ControlIndex
, string
);
1526 return RuntimeError("Cannot set tooltip");
1529 StrRef
= PyInt_AsLong( str
);
1531 ret
= core
->SetTooltip( (ieWord
) WindowIndex
, (ieWord
) ControlIndex
, GEMRB_STRING
);
1533 char* str
= core
->GetString( StrRef
);
1534 ret
= core
->SetTooltip( (ieWord
) WindowIndex
, (ieWord
) ControlIndex
, str
);
1535 core
->FreeString( str
);
1538 return RuntimeError("Cannot set tooltip");
1542 return PyInt_FromLong( ret
);
1545 PyDoc_STRVAR( GemRB_Window_SetVisible__doc
,
1546 "SetVisible(WindowIndex, Visible)\n\n"
1547 "Sets the Visibility Flag of a Window." );
1549 static PyObject
* GemRB_Window_SetVisible(PyObject
* /*self*/, PyObject
* args
)
1554 if (!PyArg_ParseTuple( args
, "ii", &WindowIndex
, &visible
)) {
1555 return AttributeError( GemRB_Window_SetVisible__doc
);
1558 int ret
= core
->SetVisible( WindowIndex
, visible
);
1560 return RuntimeError("Invalid window in SetVisible");
1563 core
->SetEventFlag(EF_CONTROL
);
1566 Py_INCREF( Py_None
);
1570 //useful only for ToB and HoW, sets masterscript/worldmap name
1571 PyDoc_STRVAR( GemRB_SetMasterScript__doc
,
1572 "SetMasterScript(ScriptResRef, WMPResRef)\n\n"
1573 "Sets the worldmap and masterscript names." );
1575 PyObject
* GemRB_SetMasterScript(PyObject
* /*self*/, PyObject
* args
)
1580 if (!PyArg_ParseTuple( args
, "ss", &script
, &worldmap
)) {
1581 return AttributeError( GemRB_SetMasterScript__doc
);
1583 strnlwrcpy( core
->GlobalScript
, script
, 8 );
1584 strnlwrcpy( core
->WorldMapName
, worldmap
, 8 );
1585 core
->UpdateMasterScript();
1586 Py_INCREF( Py_None
);
1590 PyDoc_STRVAR( GemRB_Window_ShowModal__doc
,
1591 "ShowModal(WindowIndex, [Shadow=MODAL_SHADOW_NONE])\n\n"
1592 "Show a Window on Screen setting the Modal Status. "
1593 "If Shadow is MODAL_SHADOW_GRAY, other windows are grayed. "
1594 "If Shadow is MODAL_SHADOW_BLACK, they are blacked out." );
1596 static PyObject
* GemRB_Window_ShowModal(PyObject
* /*self*/, PyObject
* args
)
1598 int WindowIndex
, Shadow
= MODAL_SHADOW_NONE
;
1600 if (!PyArg_ParseTuple( args
, "i|i", &WindowIndex
, &Shadow
)) {
1601 return AttributeError( GemRB_Window_ShowModal__doc
);
1604 int ret
= core
->ShowModal( WindowIndex
, Shadow
);
1609 core
->PlaySound(DS_WINDOW_OPEN
);
1610 Py_INCREF( Py_None
);
1614 PyDoc_STRVAR( GemRB_SetTimedEvent__doc
,
1615 "SetTimedEvent(Function, Rounds)\n\n"
1616 "Sets a timed event, the timing is handled by the game object\n"
1617 "if the game object doesn't exist, this command is ignored." );
1619 static PyObject
* GemRB_SetTimedEvent(PyObject
* /*self*/, PyObject
* args
)
1624 if (!PyArg_ParseTuple( args
, "Oi", &function
, &rounds
)) {
1625 return AttributeError( GemRB_SetTimedEvent__doc
);
1628 EventHandler handler
;
1629 if (function
== Py_None
) {
1630 handler
= new Callback();
1631 } else if (PyCallable_Check(function
)) {
1632 handler
= new PythonCallback(function
);
1635 // TODO: Print function name. (func.__name__)
1636 snprintf(buf
, sizeof(buf
), "Can't set timed event handler!");
1637 return RuntimeError(buf
);
1639 Game
*game
= core
->GetGame();
1641 game
->SetTimedEvent(handler
, rounds
);
1643 Py_INCREF( Py_None
);
1647 PyDoc_STRVAR( GemRB_SetTimedEventByName__doc
,
1648 "SetTimedEventByName(FunctionName, Rounds)\n\n"
1649 "Sets a timed event, the timing is handled by the game object\n"
1650 "if the game object doesn't exist, this command is ignored." );
1652 static PyObject
* GemRB_SetTimedEventByName(PyObject
* /*self*/, PyObject
* args
)
1657 if (!PyArg_ParseTuple( args
, "Oi", &funcName
, &rounds
)) {
1658 return AttributeError( GemRB_SetTimedEventByName__doc
);
1660 if (!PyString_Check(funcName
)) {
1661 return AttributeError( GemRB_SetTimedEventByName__doc
);
1664 Game
*game
= core
->GetGame();
1666 game
->SetTimedEvent(new StringCallback(funcName
), rounds
);
1668 Py_INCREF( Py_None
);
1672 PyDoc_STRVAR( GemRB_Control_SetEvent__doc
,
1673 "Control.SetEvent(EventMask, Function)\n\n"
1674 "Sets an event of a control on a window to a script defined function." );
1676 static PyObject
* GemRB_Control_SetEvent(PyObject
* /*self*/, PyObject
* args
)
1678 int WindowIndex
, ControlIndex
;
1682 if (!PyArg_ParseTuple(args
, "iiiO", &WindowIndex
, &ControlIndex
,
1684 return AttributeError(GemRB_Control_SetEvent__doc
);
1687 Control
* ctrl
= GetControl(WindowIndex
, ControlIndex
, -1);
1691 EventHandler handler
;
1692 if (func
== Py_None
) {
1693 handler
= new Callback();
1694 } else if (PyCallable_Check(func
)) {
1695 handler
= new PythonCallback(func
);
1697 if (!handler
|| !ctrl
->SetEvent(event
, handler
)) {
1699 // TODO: Print function name. (func.__name__)
1700 snprintf(buf
, sizeof(buf
), "Can't set event handler!");
1701 return RuntimeError(buf
);
1708 PyDoc_STRVAR( GemRB_Control_SetEventByName__doc
,
1709 "Control.SetEventByName(EventMask, FunctionName)\n\n"
1710 "Sets an event of a control on a window to a script defined function." );
1712 static PyObject
* GemRB_Control_SetEventByName(PyObject
* /*self*/, PyObject
* args
)
1714 int WindowIndex
, ControlIndex
;
1718 if (!PyArg_ParseTuple( args
, "iiiO", &WindowIndex
, &ControlIndex
, &event
,
1720 return AttributeError( GemRB_Control_SetEventByName__doc
);
1722 if (!PyString_Check(funcName
)) {
1723 return AttributeError( GemRB_Control_SetEventByName__doc
);
1726 Control
* ctrl
= GetControl( WindowIndex
, ControlIndex
, -1 );
1730 if (! ctrl
->SetEvent( event
, new StringCallback(funcName
) )) {
1732 snprintf( buf
, sizeof( buf
), "Can't set event handler: %s!", PyString_AsString(funcName
) );
1733 return RuntimeError( buf
);
1736 Py_INCREF( Py_None
);
1740 PyDoc_STRVAR( GemRB_SetNextScript__doc
,
1741 "SetNextScript(GUIScriptName)\n\n"
1742 "Sets the Next Script File to be loaded." );
1744 static PyObject
* GemRB_SetNextScript(PyObject
* /*self*/, PyObject
* args
)
1746 const char* funcName
;
1748 if (!PyArg_ParseTuple( args
, "s", &funcName
)) {
1749 return AttributeError( GemRB_SetNextScript__doc
);
1752 core
->SetNextScript(funcName
);
1754 Py_INCREF( Py_None
);
1758 PyDoc_STRVAR( GemRB_Control_SetStatus__doc
,
1759 "SetControlStatus(WindowIndex, ControlIndex, Status)\n\n"
1760 "Sets the status of a Control." );
1762 static PyObject
* GemRB_Control_SetStatus(PyObject
* /*self*/, PyObject
* args
)
1764 int WindowIndex
, ControlIndex
;
1767 if (!PyArg_ParseTuple( args
, "iii", &WindowIndex
, &ControlIndex
, &status
)) {
1768 return AttributeError( GemRB_Control_SetStatus__doc
);
1771 int ret
= core
->SetControlStatus( WindowIndex
, ControlIndex
, status
);
1776 Py_INCREF( Py_None
);
1780 PyDoc_STRVAR( GemRB_Control_AttachScrollBar__doc
,
1781 "AttachScrollBar(WindowIndex, ControlIndex, ScrollBarControlIndex)\n\n"
1782 "Attaches a ScrollBar to another control." );
1784 static PyObject
* GemRB_Control_AttachScrollBar(PyObject
* /*self*/, PyObject
* args
)
1786 int WindowIndex
, ControlIndex
, ScbControlIndex
;
1788 if (!PyArg_ParseTuple( args
, "iii", &WindowIndex
, &ControlIndex
, &ScbControlIndex
)) {
1789 return AttributeError( GemRB_Control_AttachScrollBar__doc
);
1792 Control
*ctrl
= GetControl(WindowIndex
, ControlIndex
, -1);
1797 Control
*scb
= NULL
;
1799 if (ScbControlIndex
!= -1) {
1800 scb
= GetControl(WindowIndex
, ScbControlIndex
, IE_GUI_SCROLLBAR
);
1806 int ret
= ctrl
->SetScrollBar( scb
);
1811 Py_INCREF( Py_None
);
1815 PyDoc_STRVAR( GemRB_Control_SetVarAssoc__doc
,
1816 "SetVarAssoc(WindowIndex, ControlIndex, VariableName, LongValue)\n\n"
1817 "Sets the name of the Variable associated with a control." );
1819 static PyObject
* GemRB_Control_SetVarAssoc(PyObject
* /*self*/, PyObject
* args
)
1821 int WindowIndex
, ControlIndex
;
1825 if (!PyArg_ParseTuple( args
, "iisi", &WindowIndex
, &ControlIndex
,
1826 &VarName
, &Value
)) {
1827 return AttributeError( GemRB_Control_SetVarAssoc__doc
);
1830 Control
* ctrl
= GetControl( WindowIndex
, ControlIndex
, -1 );
1835 //max variable length is not 32, but 40 (in guiscripts), but that includes zero terminator!
1836 strnlwrcpy( ctrl
->VarName
, VarName
, MAX_VARIABLE_LENGTH
-1 );
1837 ctrl
->Value
= Value
;
1838 /** setting the correct state for this control */
1839 /** it is possible to set up a default value, if Lookup returns false, use it */
1841 core
->GetDictionary()->Lookup( VarName
, Value
);
1842 Window
* win
= core
->GetWindow( WindowIndex
);
1843 win
->RedrawControls(VarName
, Value
);
1845 Py_INCREF( Py_None
);
1849 PyDoc_STRVAR( GemRB_Window_Unload__doc
,
1850 "UnloadWindow(WindowIndex)\n\n"
1851 "Unloads a previously Loaded Window." );
1853 static PyObject
* GemRB_Window_Unload(PyObject
* /*self*/, PyObject
* args
)
1857 if (!PyArg_ParseTuple( args
, "i", &WindowIndex
)) {
1858 return AttributeError( GemRB_Window_Unload__doc
);
1861 unsigned short arg
= (unsigned short) WindowIndex
;
1862 if (arg
== 0xffff) {
1863 return AttributeError( "Feature unsupported! ");
1865 int ret
= core
->DelWindow( arg
);
1867 return RuntimeError( "Can't unload window!" );
1870 core
->PlaySound(DS_WINDOW_CLOSE
);
1871 Py_INCREF( Py_None
);
1875 PyDoc_STRVAR( GemRB_Window_Invalidate__doc
,
1876 "InvalidateWindow(WindowIndex)\n\n"
1877 "Invalidates the given Window." );
1879 static PyObject
* GemRB_Window_Invalidate(PyObject
* /*self*/, PyObject
* args
)
1883 if (!PyArg_ParseTuple( args
, "i", &WindowIndex
)) {
1884 return AttributeError( GemRB_Window_Invalidate__doc
);
1887 Window
* win
= core
->GetWindow( WindowIndex
);
1889 return RuntimeError("Cannot find window!");
1893 Py_INCREF( Py_None
);
1897 PyDoc_STRVAR( GemRB_CreateWindow__doc
,
1898 "CreateWindow(WindowID, X, Y, Width, Height, MosResRef) => WindowIndex\n\n"
1899 "Creates a new empty window and returns its index.");
1901 static PyObject
* GemRB_CreateWindow(PyObject
* /*self*/, PyObject
* args
)
1903 int WindowID
, x
, y
, w
, h
;
1906 if (!PyArg_ParseTuple( args
, "iiiiis", &WindowID
, &x
, &y
,
1907 &w
, &h
, &Background
)) {
1908 return AttributeError( GemRB_CreateWindow__doc
);
1910 int WindowIndex
= core
->CreateWindow( WindowID
, x
, y
, w
, h
, Background
);
1911 if (WindowIndex
== -1) {
1912 return RuntimeError( "Can't create window" );
1915 return PyInt_FromLong( WindowIndex
);
1918 PyDoc_STRVAR( GemRB_Button_CreateLabelOnButton__doc
,
1919 "CreateLabelOnButton(WindowIndex, ControlIndex, NewControlID, font, align)"
1920 "Creates a label on top of a button, copying the button's size and position." );
1922 static PyObject
* GemRB_Button_CreateLabelOnButton(PyObject
* /*self*/, PyObject
* args
)
1924 int WindowIndex
, ControlIndex
, ControlID
, align
;
1927 if (!PyArg_ParseTuple( args
, "iiisi", &WindowIndex
, &ControlIndex
,
1928 &ControlID
, &font
, &align
)) {
1929 return AttributeError( GemRB_Button_CreateLabelOnButton__doc
);
1932 Window
* win
= core
->GetWindow( WindowIndex
);
1934 return RuntimeError("Cannot find window!");
1936 Control
*btn
= GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
1940 Label
* lbl
= new Label( core
->GetFont( font
) );
1941 lbl
->XPos
= btn
->XPos
;
1942 lbl
->YPos
= btn
->YPos
;
1943 lbl
->Width
= btn
->Width
;
1944 lbl
->Height
= btn
->Height
;
1945 lbl
->ControlID
= ControlID
;
1946 lbl
->ControlType
= IE_GUI_LABEL
;
1948 lbl
->SetAlignment( align
);
1949 win
->AddControl( lbl
);
1951 int ret
= core
->GetControl( WindowIndex
, ControlID
);
1956 return PyInt_FromLong( ret
);
1957 //Py_INCREF( Py_None );
1961 PyDoc_STRVAR( GemRB_Window_CreateLabel__doc
,
1962 "CreateLabel(WindowIndex, ControlID, x, y, w, h, font, text, align)\n\n"
1963 "Creates and adds a new Label to a Window." );
1965 static PyObject
* GemRB_Window_CreateLabel(PyObject
* /*self*/, PyObject
* args
)
1967 int WindowIndex
, ControlID
, x
, y
, w
, h
, align
;
1970 if (!PyArg_ParseTuple( args
, "iiiiiissi", &WindowIndex
, &ControlID
, &x
,
1971 &y
, &w
, &h
, &font
, &text
, &align
)) {
1972 return AttributeError( GemRB_Window_CreateLabel__doc
);
1975 Window
* win
= core
->GetWindow( WindowIndex
);
1977 return RuntimeError("Cannot find window!");
1979 Label
* lbl
= new Label( core
->GetFont( font
) );
1984 lbl
->ControlID
= ControlID
;
1985 lbl
->ControlType
= IE_GUI_LABEL
;
1987 lbl
->SetText( text
);
1988 lbl
->SetAlignment( align
);
1989 win
->AddControl( lbl
);
1991 int ret
= core
->GetControl( WindowIndex
, ControlID
);
1996 return PyInt_FromLong( ret
);
1997 //Py_INCREF( Py_None );
2001 PyDoc_STRVAR( GemRB_Label_SetTextColor__doc
,
2002 "SetLabelTextColor(WindowIndex, ControlIndex, red, green, blue)\n\n"
2003 "Sets the Text Color of a Label Control." );
2005 static PyObject
* GemRB_Label_SetTextColor(PyObject
* /*self*/, PyObject
* args
)
2007 int WindowIndex
, ControlIndex
, r
, g
, b
;
2009 if (!PyArg_ParseTuple( args
, "iiiii", &WindowIndex
, &ControlIndex
, &r
, &g
,
2011 return AttributeError( GemRB_Label_SetTextColor__doc
);
2014 Label
* lab
= ( Label
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_LABEL
);
2019 Color fore
= {r
,g
, b
, 0}, back
= {0, 0, 0, 0};
2020 lab
->SetColor( fore
, back
);
2022 Py_INCREF( Py_None
);
2026 PyDoc_STRVAR( GemRB_Window_CreateTextEdit__doc
,
2027 "CreateTextEdit(WindowIndex, ControlID, x, y, w, h, font, text)\n\n"
2028 "Creates and adds a new TextEdit to a Window." );
2030 static PyObject
* GemRB_Window_CreateTextEdit(PyObject
* /*self*/, PyObject
* args
)
2032 int WindowIndex
, ControlID
, x
, y
, w
, h
;
2035 if (!PyArg_ParseTuple( args
, "iiiiiiss", &WindowIndex
, &ControlID
, &x
,
2036 &y
, &w
, &h
, &font
, &text
)) {
2037 return AttributeError( GemRB_Window_CreateTextEdit__doc
);
2040 Window
* win
= core
->GetWindow( WindowIndex
);
2042 return RuntimeError("Cannot find window!");
2044 //there is no need to set these differently, currently
2045 TextEdit
* edit
= new TextEdit( 500, 0, 0);
2046 edit
->SetFont( core
->GetFont( font
) );
2051 edit
->ControlID
= ControlID
;
2052 edit
->ControlType
= IE_GUI_EDIT
;
2054 edit
->SetText( text
);
2056 Sprite2D
* spr
= core
->GetCursorSprite();
2058 edit
->SetCursor( spr
);
2060 return RuntimeError( "BAM not found" );
2062 win
->AddControl( edit
);
2064 int ret
= core
->GetControl( WindowIndex
, ControlID
);
2069 return PyInt_FromLong( ret
);
2070 //Py_INCREF( Py_None );
2074 PyDoc_STRVAR( GemRB_Window_CreateScrollBar__doc
,
2075 "CreateScrollBar(WindowIndex, ControlID, x, y, w, h) => ControlIndex\n\n"
2076 "Creates and adds a new ScrollBar to a Window.");
2078 static PyObject
* GemRB_Window_CreateScrollBar(PyObject
* /*self*/, PyObject
* args
)
2080 int WindowIndex
, ControlID
, x
, y
, w
, h
;
2082 if (!PyArg_ParseTuple( args
, "iiiiii", &WindowIndex
, &ControlID
, &x
, &y
,
2084 return AttributeError( GemRB_Window_CreateScrollBar__doc
);
2087 Window
* win
= core
->GetWindow( WindowIndex
);
2089 return RuntimeError("Cannot find window!");
2092 ScrollBar
* sb
= new ScrollBar( );
2097 sb
->ControlID
= ControlID
;
2098 sb
->ControlType
= IE_GUI_SCROLLBAR
;
2100 win
->AddControl( sb
);
2102 int ret
= core
->GetControl( WindowIndex
, ControlID
);
2107 return PyInt_FromLong( ret
);
2108 //Py_INCREF( Py_None );
2113 PyDoc_STRVAR( GemRB_Window_CreateButton__doc
,
2114 "CreateButton(WindowIndex, ControlID, x, y, w, h) => ControlIndex\n\n"
2115 "Creates and adds a new Button to a Window." );
2117 static PyObject
* GemRB_Window_CreateButton(PyObject
* /*self*/, PyObject
* args
)
2119 int WindowIndex
, ControlID
, x
, y
, w
, h
;
2121 if (!PyArg_ParseTuple( args
, "iiiiii", &WindowIndex
, &ControlID
, &x
, &y
,
2123 return AttributeError( GemRB_Window_CreateButton__doc
);
2126 Window
* win
= core
->GetWindow( WindowIndex
);
2128 return RuntimeError("Cannot find window!");
2131 Button
* btn
= new Button( );
2136 btn
->ControlID
= ControlID
;
2137 btn
->ControlType
= IE_GUI_BUTTON
;
2139 win
->AddControl( btn
);
2141 int ret
= core
->GetControl( WindowIndex
, ControlID
);
2146 return PyInt_FromLong( ret
);
2147 //Py_INCREF( Py_None );
2152 PyDoc_STRVAR( GemRB_TextEdit_ConvertEdit__doc
,
2153 "ConvertEdit(WindowIndex, ControlIndex, ScrollBarID) => ControlIndex\n\n"
2154 "Converts a simple Edit Control to a TextArea, keeping its ControlID." );
2156 static PyObject
* GemRB_TextEdit_ConvertEdit(PyObject
* /*self*/, PyObject
* args
)
2158 int WindowIndex
, ControlIndex
;
2159 Color fore
={255,255,255,0};
2160 Color init
={255,255,255,0};
2161 Color back
={0,0,0,0};
2164 if (!PyArg_ParseTuple( args
, "ii|i", &WindowIndex
, &ControlIndex
, &ScrollBarID
)) {
2165 return AttributeError( GemRB_TextEdit_ConvertEdit__doc
);
2168 Window
* win
= core
->GetWindow( WindowIndex
);
2170 return RuntimeError("Cannot find window!");
2173 TextEdit
*ctrl
= (TextEdit
*) GetControl(WindowIndex
, ControlIndex
, IE_GUI_EDIT
);
2177 TextArea
* ta
= new TextArea( fore
, init
, back
);
2178 ta
->XPos
= ctrl
->XPos
;
2179 ta
->YPos
= ctrl
->YPos
;
2180 ta
->Width
= ctrl
->Width
;
2181 ta
->Height
= ctrl
->Height
;
2182 ta
->ControlID
= ctrl
->ControlID
;
2183 ta
->ControlType
= IE_GUI_TEXTAREA
;
2185 ta
->SetFonts (ctrl
->GetFont(), ctrl
->GetFont() );
2186 ta
->Flags
|= IE_GUI_TEXTAREA_EDITABLE
;
2187 win
->AddControl( ta
);
2188 win
->Link( ScrollBarID
, ( unsigned short ) ta
->ControlID
);
2190 int ret
= core
->GetControl( WindowIndex
, ta
->ControlID
);
2195 return PyInt_FromLong( ret
);
2198 PyDoc_STRVAR( GemRB_ScrollBar_SetSprites__doc
,
2199 "SetScrollBarSprites(WindowIndex, ControlIndex, ResRef, Cycle, UpUnpressedFrame, UpPressedFrame, DownUnpressedFrame, DownPressedFrame, TroughFrame, SliderFrame)\n\n"
2200 "Sets a ScrollBar Sprites Images." );
2202 static PyObject
* GemRB_ScrollBar_SetSprites(PyObject
* /*self*/, PyObject
* args
)
2204 int WindowIndex
, ControlIndex
, cycle
, upunpressed
, uppressed
;
2205 int downunpressed
, downpressed
, trough
, knob
;
2208 if (!PyArg_ParseTuple( args
, "iisiiiiiii", &WindowIndex
, &ControlIndex
,
2209 &ResRef
, &cycle
, &upunpressed
, &uppressed
, &downunpressed
, &downpressed
, &trough
, &knob
)) {
2210 return AttributeError( GemRB_ScrollBar_SetSprites__doc
);
2213 ScrollBar
* sb
= ( ScrollBar
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_SCROLLBAR
);
2218 if (ResRef
[0] == 0) {
2219 sb
->SetImage( IE_GUI_SCROLLBAR_UP_UNPRESSED
, 0 );
2220 sb
->SetImage( IE_GUI_SCROLLBAR_UP_PRESSED
, 0 );
2221 sb
->SetImage( IE_GUI_SCROLLBAR_DOWN_UNPRESSED
, 0 );
2222 sb
->SetImage( IE_GUI_SCROLLBAR_DOWN_PRESSED
, 0 );
2223 sb
->SetImage( IE_GUI_SCROLLBAR_TROUGH
, 0 );
2224 sb
->SetImage( IE_GUI_SCROLLBAR_SLIDER
, 0 );
2225 Py_INCREF( Py_None
);
2229 AnimationFactory
* af
= ( AnimationFactory
* )
2230 gamedata
->GetFactoryResource( ResRef
,
2231 IE_BAM_CLASS_ID
, IE_NORMAL
);
2233 return RuntimeError( "BAM not found" );
2235 Sprite2D
*tspr
= af
->GetFrame(upunpressed
, (unsigned char)cycle
);
2236 sb
->SetImage( IE_GUI_SCROLLBAR_UP_UNPRESSED
, tspr
);
2237 tspr
= af
->GetFrame( uppressed
, (unsigned char) cycle
);
2238 sb
->SetImage( IE_GUI_SCROLLBAR_UP_PRESSED
, tspr
);
2239 tspr
= af
->GetFrame( downunpressed
, (unsigned char)cycle
);
2240 sb
->SetImage( IE_GUI_SCROLLBAR_DOWN_UNPRESSED
, tspr
);
2241 tspr
= af
->GetFrame( downpressed
, (unsigned char) cycle
);
2242 sb
->SetImage( IE_GUI_SCROLLBAR_DOWN_PRESSED
, tspr
);
2243 tspr
= af
->GetFrame( trough
, (unsigned char) cycle
);
2244 sb
->SetImage( IE_GUI_SCROLLBAR_TROUGH
, tspr
);
2245 tspr
= af
->GetFrame( knob
, (unsigned char) cycle
);
2246 sb
->SetImage( IE_GUI_SCROLLBAR_SLIDER
, tspr
);
2248 Py_INCREF( Py_None
);
2253 PyDoc_STRVAR( GemRB_Button_SetSprites__doc
,
2254 "SetButtonSprites(WindowIndex, ControlIndex, ResRef, Cycle, UnpressedFrame, PressedFrame, SelectedFrame, DisabledFrame)\n\n"
2255 "Sets a Button Sprites Images." );
2257 static PyObject
* GemRB_Button_SetSprites(PyObject
* /*self*/, PyObject
* args
)
2259 int WindowIndex
, ControlIndex
, cycle
, unpressed
, pressed
, selected
,
2263 if (!PyArg_ParseTuple( args
, "iisiiiii", &WindowIndex
, &ControlIndex
,
2264 &ResRef
, &cycle
, &unpressed
, &pressed
, &selected
, &disabled
)) {
2265 return AttributeError( GemRB_Button_SetSprites__doc
);
2268 Button
* btn
= ( Button
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
2273 if (ResRef
[0] == 0) {
2274 btn
->SetImage( IE_GUI_BUTTON_UNPRESSED
, 0 );
2275 btn
->SetImage( IE_GUI_BUTTON_PRESSED
, 0 );
2276 btn
->SetImage( IE_GUI_BUTTON_SELECTED
, 0 );
2277 btn
->SetImage( IE_GUI_BUTTON_DISABLED
, 0 );
2278 Py_INCREF( Py_None
);
2282 AnimationFactory
* af
= ( AnimationFactory
* )
2283 gamedata
->GetFactoryResource( ResRef
,
2284 IE_BAM_CLASS_ID
, IE_NORMAL
);
2286 return RuntimeError( "BAM not found" );
2288 Sprite2D
*tspr
= af
->GetFrame(unpressed
, (unsigned char)cycle
);
2289 btn
->SetImage( IE_GUI_BUTTON_UNPRESSED
, tspr
);
2290 tspr
= af
->GetFrame( pressed
, (unsigned char) cycle
);
2291 btn
->SetImage( IE_GUI_BUTTON_PRESSED
, tspr
);
2292 tspr
= af
->GetFrame( selected
, (unsigned char) cycle
);
2293 btn
->SetImage( IE_GUI_BUTTON_SELECTED
, tspr
);
2294 tspr
= af
->GetFrame( disabled
, (unsigned char) cycle
);
2295 btn
->SetImage( IE_GUI_BUTTON_DISABLED
, tspr
);
2297 Py_INCREF( Py_None
);
2301 PyDoc_STRVAR( GemRB_Button_SetOverlay__doc
,
2302 "SetButtonOverlay(WindowIndex, ControlIndex, Current, Max, r,g,b,a, r,g,b,a)\n\n"
2303 "Sets up a portrait button for hitpoint overlay" );
2305 static PyObject
* GemRB_Button_SetOverlay(PyObject
* /*self*/, PyObject
* args
)
2307 int WindowIndex
, ControlIndex
;
2312 if (!PyArg_ParseTuple( args
, "iidiiiiiiii", &WindowIndex
, &ControlIndex
,
2313 &Clipping
, &r1
, &g1
, &b1
, &a1
, &r2
, &g2
, &b2
, &a2
)) {
2314 return AttributeError( GemRB_Button_SetOverlay__doc
);
2317 Button
* btn
= ( Button
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
2322 const Color src
= { r1
, g1
, b1
, a1
};
2323 const Color dest
= { r2
, g2
, b2
, a2
};
2325 if (Clipping
<0.0) Clipping
= 0.0;
2326 else if (Clipping
>1.0) Clipping
= 1.0;
2327 //can't call clipping, because the change of ratio triggers color change
2328 btn
->SetHorizontalOverlay(Clipping
, src
, dest
);
2329 Py_INCREF( Py_None
);
2333 PyDoc_STRVAR( GemRB_Button_SetBorder__doc
,
2334 "SetButtonBorder(WindowIndex, ControlIndex, BorderIndex, dx1, dy1, dx2, dy2, R, G, B, A, [enabled, filled])\n\n"
2335 "Sets border/frame parameters for a button." );
2337 static PyObject
* GemRB_Button_SetBorder(PyObject
* /*self*/, PyObject
* args
)
2339 int WindowIndex
, ControlIndex
, BorderIndex
, dx1
, dy1
, dx2
, dy2
, r
, g
, b
, a
, enabled
= 0, filled
= 0;
2341 if (!PyArg_ParseTuple( args
, "iiiiiiiiiii|ii", &WindowIndex
, &ControlIndex
,
2342 &BorderIndex
, &dx1
, &dy1
, &dx2
, &dy2
, &r
, &g
, &b
, &a
, &enabled
, &filled
)) {
2343 return AttributeError( GemRB_Button_SetBorder__doc
);
2346 Button
* btn
= ( Button
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
2351 const Color color
= { r
, g
, b
, a
};
2352 btn
->SetBorder( BorderIndex
, dx1
, dy1
, dx2
, dy2
, color
, (bool)enabled
, (bool)filled
);
2354 Py_INCREF( Py_None
);
2358 PyDoc_STRVAR( GemRB_Button_EnableBorder__doc
,
2359 "EnableButtonBorder(WindowIndex, ControlIndex, BorderIndex, enabled)\n\n"
2360 "Enable or disable specified border/frame." );
2362 static PyObject
* GemRB_Button_EnableBorder(PyObject
* /*self*/, PyObject
* args
)
2364 int WindowIndex
, ControlIndex
, BorderIndex
, enabled
;
2366 if (!PyArg_ParseTuple( args
, "iiii", &WindowIndex
, &ControlIndex
,
2367 &BorderIndex
, &enabled
)) {
2368 return AttributeError( GemRB_Button_EnableBorder__doc
);
2371 Button
* btn
= ( Button
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
2376 btn
->EnableBorder( BorderIndex
, (bool)enabled
);
2378 Py_INCREF( Py_None
);
2382 PyDoc_STRVAR( GemRB_Button_SetFont__doc
,
2383 "SetButtonFont(WindowIndex, ControlIndex, FontResRef)\n\n"
2384 "Sets font used for drawing button label." );
2386 static PyObject
* GemRB_Button_SetFont(PyObject
* /*self*/, PyObject
* args
)
2388 int WindowIndex
, ControlIndex
;
2391 if (!PyArg_ParseTuple( args
, "iis", &WindowIndex
, &ControlIndex
,
2393 return AttributeError( GemRB_Button_SetFont__doc
);
2396 Button
* btn
= ( Button
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
2401 btn
->SetFont( core
->GetFont( FontResRef
));
2403 Py_INCREF( Py_None
);
2407 PyDoc_STRVAR( GemRB_Button_SetTextColor__doc
,
2408 "SetButtonTextColor(WindowIndex, ControlIndex, red, green, blue[, invert=false])\n\n"
2409 "Sets the Text Color of a Button Control. Invert is used for fonts with swapped background and text colors." );
2411 static PyObject
* GemRB_Button_SetTextColor(PyObject
* /*self*/, PyObject
* args
)
2413 int WindowIndex
, ControlIndex
, r
, g
, b
, swap
= 0;
2415 if (!PyArg_ParseTuple( args
, "iiiii|i", &WindowIndex
, &ControlIndex
, &r
, &g
, &b
, &swap
)) {
2416 return AttributeError( GemRB_Button_SetTextColor__doc
);
2419 Button
* but
= ( Button
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
2424 Color fore
= {r
,g
, b
, 0}, back
= {0, 0, 0, 0};
2426 // FIXME: swap is a hack for fonts which apparently have swapped f & B
2427 // colors. Maybe it depends on need_palette?
2429 but
->SetTextColor( fore
, back
);
2431 but
->SetTextColor( back
, fore
);
2434 Py_INCREF( Py_None
);
2438 PyDoc_STRVAR( GemRB_Window_DeleteControl__doc
,
2439 "DeleteControl(WindowIndex, ControlID)\n\n"
2440 "Deletes a control from a Window." );
2442 static PyObject
* GemRB_Window_DeleteControl(PyObject
* /*self*/, PyObject
* args
)
2444 int WindowIndex
, ControlID
;
2446 if (!PyArg_ParseTuple( args
, "ii", &WindowIndex
, &ControlID
)) {
2447 return AttributeError( GemRB_Window_DeleteControl__doc
);
2450 Window
* win
= core
->GetWindow( WindowIndex
);
2452 return RuntimeError("Cannot find window!");
2454 int CtrlIndex
= core
->GetControl( WindowIndex
, ControlID
);
2455 if (CtrlIndex
== -1) {
2456 return RuntimeError( "Control is not found" );
2458 win
-> DelControl( CtrlIndex
);
2460 Py_INCREF( Py_None
);
2464 PyDoc_STRVAR( GemRB_WorldMap_AdjustScrolling__doc
,
2465 "AdjustScrolling(WindowIndex, ControlIndex, x, y)\n\n"
2466 "Sets the scrolling offset of a WorldMapControl.");
2468 static PyObject
* GemRB_WorldMap_AdjustScrolling(PyObject
* /*self*/, PyObject
* args
)
2470 int WindowIndex
, ControlIndex
, x
, y
;
2472 if (!PyArg_ParseTuple( args
, "iiii", &WindowIndex
, &ControlIndex
, &x
, &y
)) {
2473 return AttributeError( GemRB_WorldMap_AdjustScrolling__doc
);
2476 core
->AdjustScrolling( WindowIndex
, ControlIndex
, x
, y
);
2477 Py_INCREF( Py_None
);
2481 PyDoc_STRVAR( GemRB_CreateMovement__doc
,
2482 "CreateMovement(Area, Entrance, Direction)\n\n"
2483 "Moves actors to a new area." );
2485 static PyObject
* GemRB_CreateMovement(PyObject
* /*self*/, PyObject
* args
)
2492 if (!PyArg_ParseTuple( args
, "ss|i", &area
, &entrance
, &direction
)) {
2493 return AttributeError( GemRB_CreateMovement__doc
);
2495 if (core
->HasFeature(GF_TEAM_MOVEMENT
) ) {
2496 everyone
= CT_WHOLE
;
2498 everyone
= CT_GO_CLOSER
;
2500 Game
*game
= core
->GetGame();
2502 return RuntimeError( "No game loaded!" );
2504 game
->GetCurrentArea()->MoveToNewArea(area
, entrance
, (unsigned int)direction
, everyone
, NULL
);
2505 Py_INCREF( Py_None
);
2509 PyDoc_STRVAR( GemRB_WorldMap_GetDestinationArea__doc
,
2510 "GetDestinationArea(WindowIndex, ControlID[, RndEncounter]) => WorldMap entry\n\n"
2511 "Returns the last area pointed on the worldmap.\n"
2512 "If the random encounter flag is set, the random encounters will be evaluated too." );
2514 static PyObject
* GemRB_WorldMap_GetDestinationArea(PyObject
* /*self*/, PyObject
* args
)
2516 int WindowIndex
, ControlIndex
;
2519 if (!PyArg_ParseTuple( args
, "ii|i", &WindowIndex
, &ControlIndex
, &eval
)) {
2520 return AttributeError( GemRB_WorldMap_GetDestinationArea__doc
);
2523 WorldMapControl
* wmc
= (WorldMapControl
*) GetControl(WindowIndex
, ControlIndex
, IE_GUI_WORLDMAP
);
2527 //no area was pointed on
2529 Py_INCREF( Py_None
);
2532 WorldMap
*wm
= core
->GetWorldMap();
2533 PyObject
* dict
= PyDict_New();
2534 //the area the user clicked on
2535 PyDict_SetItemString(dict
, "Target", PyString_FromString (wmc
->Area
->AreaName
) );
2537 WMPAreaLink
*wal
= wm
->GetEncounterLink(wmc
->Area
->AreaName
, encounter
);
2539 PyDict_SetItemString(dict
, "Distance", PyInt_FromLong (-1) );
2542 PyDict_SetItemString(dict
, "Destination", PyString_FromString (wmc
->Area
->AreaName
) );
2543 PyDict_SetItemString(dict
, "Entrance", PyString_FromString (wal
->DestEntryPoint
) );
2544 PyDict_SetItemString(dict
, "Direction", PyInt_FromLong (wal
->DirectionFlags
) );
2545 //the area the user will fall on
2546 if (encounter
&& eval
) {
2549 if(wal
->EncounterChance
>=100) {
2550 wal
->EncounterChance
-=100;
2552 for(int j
=0;j
<5;j
++) {
2553 if (wal
->EncounterAreaResRef
[(i
+j
)%5][0]) {
2554 PyDict_SetItemString(dict
, "Destination", PyString_FromString (wal
->EncounterAreaResRef
[(i
+j
)%5]) );
2555 PyDict_SetItemString(dict
, "Entrance", PyString_FromString ("") );
2556 // do we need to change Direction here?
2562 //the entrance the user will fall on
2563 PyDict_SetItemString(dict
, "Distance", PyInt_FromLong (wm
->GetDistance(wmc
->Area
->AreaName
)) );
2567 PyDoc_STRVAR( GemRB_Window_CreateWorldMapControl__doc
,
2568 "CreateWorldMapControl(WindowIndex, ControlID, x, y, w, h, direction[, font])\n\n"
2569 "Creates and adds a new WorldMap control to a Window." );
2571 static PyObject
* GemRB_Window_CreateWorldMapControl(PyObject
* /*self*/, PyObject
* args
)
2573 int WindowIndex
, ControlID
, x
, y
, w
, h
, direction
;
2576 if (!PyArg_ParseTuple( args
, "iiiiiii|s", &WindowIndex
, &ControlID
, &x
,
2577 &y
, &w
, &h
, &direction
, &font
)) {
2578 return AttributeError( GemRB_Window_CreateWorldMapControl__doc
);
2581 Window
* win
= core
->GetWindow( WindowIndex
);
2583 return RuntimeError("Cannot find window!");
2585 int CtrlIndex
= core
->GetControl( WindowIndex
, ControlID
);
2586 if (CtrlIndex
!= -1) {
2587 Control
*ctrl
= win
->GetControl( CtrlIndex
);
2592 //flags = ctrl->Value;
2593 win
->DelControl( CtrlIndex
);
2595 WorldMapControl
* wmap
= new WorldMapControl( font
?font
:"", direction
);
2600 wmap
->ControlID
= ControlID
;
2601 wmap
->ControlType
= IE_GUI_WORLDMAP
;
2603 win
->AddControl( wmap
);
2605 int ret
= core
->GetControl( WindowIndex
, ControlID
);
2610 return PyInt_FromLong( ret
);
2611 //Py_INCREF( Py_None );
2615 PyDoc_STRVAR( GemRB_WorldMap_SetTextColor__doc
,
2616 "SetWorldMapTextColor(WindowIndex, ControlIndex, which, red, green, blue)\n\n"
2617 "Sets the label colors of a WorldMap Control. WHICH selects color affected"
2618 "and is one of IE_GUI_WMAP_COLOR_(NORMAL|SELECTED|NOTVISITED)." );
2620 static PyObject
* GemRB_WorldMap_SetTextColor(PyObject
* /*self*/, PyObject
* args
)
2622 int WindowIndex
, ControlIndex
, which
, r
, g
, b
, a
;
2624 if (!PyArg_ParseTuple( args
, "iiiiiii", &WindowIndex
, &ControlIndex
, &which
, &r
, &g
, &b
, &a
)) {
2625 return AttributeError( GemRB_WorldMap_SetTextColor__doc
);
2628 WorldMapControl
* wmap
= ( WorldMapControl
* ) GetControl( WindowIndex
, ControlIndex
, IE_GUI_WORLDMAP
);
2633 Color color
= {r
, g
, b
, a
};
2634 wmap
->SetColor( which
, color
);
2636 Py_INCREF( Py_None
);
2641 PyDoc_STRVAR( GemRB_Window_CreateMapControl__doc
,
2642 "CreateMapControl(WindowIndex, ControlID, x, y, w, h, "
2643 "[LabelID, FlagResRef[, Flag2ResRef]])\n\n"
2644 "Creates and adds a new Area Map Control to a Window.\n"
2645 "Note: LabelID is an ID, not an index. "
2646 "If there are two flags given, they will be considered a BMP.");
2648 static PyObject
* GemRB_Window_CreateMapControl(PyObject
* /*self*/, PyObject
* args
)
2650 int WindowIndex
, ControlID
, x
, y
, w
, h
;
2655 if (!PyArg_ParseTuple( args
, "iiiiiiis|s", &WindowIndex
, &ControlID
,
2656 &x
, &y
, &w
, &h
, &LabelID
, &Flag
, &Flag2
)) {
2658 PyErr_Clear(); //clearing the exception
2659 if (!PyArg_ParseTuple( args
, "iiiiii", &WindowIndex
, &ControlID
,
2661 return AttributeError( GemRB_Window_CreateMapControl__doc
);
2664 Window
* win
= core
->GetWindow( WindowIndex
);
2666 return RuntimeError("Cannot find window!");
2668 int CtrlIndex
= core
->GetControl( WindowIndex
, ControlID
);
2669 if (CtrlIndex
!= -1) {
2670 Control
*ctrl
= win
->GetControl( CtrlIndex
);
2675 // do *not* delete the existing control, we want to replace
2676 // it in the sort order!
2677 //win->DelControl( CtrlIndex );
2680 MapControl
* map
= new MapControl( );
2685 map
->ControlID
= ControlID
;
2686 map
->ControlType
= IE_GUI_MAP
;
2688 if (Flag2
) { //pst flavour
2689 map
->convertToGame
= false;
2690 CtrlIndex
= core
->GetControl( WindowIndex
, LabelID
);
2691 Control
*lc
= win
->GetControl( CtrlIndex
);
2692 map
->LinkedLabel
= lc
;
2693 ResourceHolder
<ImageMgr
> anim(Flag
);
2695 map
->Flag
[0] = anim
->GetSprite2D();
2697 ResourceHolder
<ImageMgr
> anim2(Flag2
);
2699 map
->Flag
[1] = anim2
->GetSprite2D();
2704 CtrlIndex
= core
->GetControl( WindowIndex
, LabelID
);
2705 Control
*lc
= win
->GetControl( CtrlIndex
);
2706 map
->LinkedLabel
= lc
;
2707 AnimationFactory
* af
= ( AnimationFactory
* )
2708 gamedata
->GetFactoryResource( Flag
,
2709 IE_BAM_CLASS_ID
, IE_NORMAL
);
2711 for (int i
=0;i
<8;i
++) {
2712 map
->Flag
[i
] = af
->GetFrame(0,i
);
2718 win
->AddControl( map
);
2720 int ret
= core
->GetControl( WindowIndex
, ControlID
);
2725 return PyInt_FromLong( ret
);
2726 //Py_INCREF( Py_None );
2730 PyDoc_STRVAR( GemRB_Control_SetPos__doc
,
2731 "SetControlPos(WindowIndex, ControlIndex, X, Y)\n\n"
2732 "Moves a Control." );
2734 static PyObject
* GemRB_Control_SetPos(PyObject
* /*self*/, PyObject
* args
)
2736 int WindowIndex
, ControlIndex
, X
, Y
;
2738 if (!PyArg_ParseTuple( args
, "iiii", &WindowIndex
, &ControlIndex
, &X
, &Y
)) {
2739 return AttributeError( GemRB_Control_SetPos__doc
);
2742 Control
* ctrl
= GetControl(WindowIndex
, ControlIndex
, -1);
2750 Py_INCREF( Py_None
);
2754 PyDoc_STRVAR( GemRB_Control_SetSize__doc
,
2755 "SetControlSize(WindowIndex, ControlIndex, Width, Height)\n\n"
2756 "Resizes a Control." );
2758 static PyObject
* GemRB_Control_SetSize(PyObject
* /*self*/, PyObject
* args
)
2760 int WindowIndex
, ControlIndex
, Width
, Height
;
2762 if (!PyArg_ParseTuple( args
, "iiii", &WindowIndex
, &ControlIndex
, &Width
,
2764 return AttributeError( GemRB_Control_SetSize__doc
);
2767 Control
* ctrl
= GetControl(WindowIndex
, ControlIndex
, -1);
2772 ctrl
->Width
= Width
;
2773 ctrl
->Height
= Height
;
2775 Py_INCREF( Py_None
);
2779 PyDoc_STRVAR( GemRB_Label_SetUseRGB__doc
,
2780 "SetLabelUseRGB(WindowIndex, ControlIndex, status)\n\n"
2781 "Tells a Label to use the RGB colors with the text." );
2783 static PyObject
* GemRB_Label_SetUseRGB(PyObject
* /*self*/, PyObject
* args
)
2785 int WindowIndex
, ControlIndex
, status
;
2787 if (!PyArg_ParseTuple( args
, "iii", &WindowIndex
, &ControlIndex
, &status
)) {
2788 return AttributeError( GemRB_Label_SetUseRGB__doc
);
2791 Label
* lab
= (Label
*) GetControl(WindowIndex
, ControlIndex
, IE_GUI_LABEL
);
2796 lab
->useRGB
= ( status
!= 0 );
2798 Py_INCREF( Py_None
);
2802 PyDoc_STRVAR( GemRB_GameSetPartySize__doc
,
2803 "GameSetPartySize(size)\n\n"
2804 "Sets the maximum party size." );
2806 static PyObject
* GemRB_GameSetPartySize(PyObject
* /*self*/, PyObject
* args
)
2810 if (!PyArg_ParseTuple( args
, "i", &Flags
)) {
2811 return AttributeError( GemRB_GameSetPartySize__doc
);
2814 Game
*game
= core
->GetGame();
2816 return RuntimeError( "No game loaded!" );
2819 game
->SetPartySize( Flags
);
2821 Py_INCREF( Py_None
);
2825 PyDoc_STRVAR( GemRB_GameSetProtagonistMode__doc
,
2826 "GameSetProtagonistMode(PM)\n\n"
2827 "Sets the protagonist mode, 0-no check, 1-protagonist, 2-team." );
2829 static PyObject
* GemRB_GameSetProtagonistMode(PyObject
* /*self*/, PyObject
* args
)
2833 if (!PyArg_ParseTuple( args
, "i", &Flags
)) {
2834 return AttributeError( GemRB_GameSetProtagonistMode__doc
);
2837 Game
*game
= core
->GetGame();
2839 return RuntimeError( "No game loaded!" );
2842 game
->SetProtagonistMode( Flags
);
2844 Py_INCREF( Py_None
);
2848 PyDoc_STRVAR( GemRB_GameSetExpansion__doc
,
2849 "GameSetExpansion(expmode)\n\n"
2850 "Sets the expansion mode, 0-no expansion, 1-expansion." );
2852 static PyObject
* GemRB_GameSetExpansion(PyObject
* /*self*/, PyObject
* args
)
2856 if (!PyArg_ParseTuple( args
, "i", &Flags
)) {
2857 return AttributeError( GemRB_GameSetExpansion__doc
);
2860 Game
*game
= core
->GetGame();
2862 game
->SetExpansion( Flags
);
2865 Py_INCREF( Py_None
);
2869 PyDoc_STRVAR( GemRB_GameSetScreenFlags__doc
,
2870 "GameSetScreenFlags(Flags, Operation)\n\n"
2871 "Sets the Display Flags of the main game screen (pane status, dialog textarea size)." );
2873 static PyObject
* GemRB_GameSetScreenFlags(PyObject
* /*self*/, PyObject
* args
)
2875 int Flags
, Operation
;
2877 if (!PyArg_ParseTuple( args
, "ii", &Flags
, &Operation
)) {
2878 return AttributeError( GemRB_GameSetScreenFlags__doc
);
2880 if (Operation
< BM_SET
|| Operation
> BM_NAND
) {
2881 printMessage( "GUIScript",
2882 "Syntax Error: operation must be 0-4\n", LIGHT_RED
);
2886 Game
*game
= core
->GetGame();
2888 return RuntimeError( "No game loaded!" );
2891 game
->SetControlStatus( Flags
, Operation
);
2893 Py_INCREF( Py_None
);
2897 PyDoc_STRVAR( GemRB_GameControlSetScreenFlags__doc
,
2898 "GameControlSetScreenFlags(Flags, Operation)\n\n"
2899 "Sets the Display Flags of the main game screen control (centeronactor,...)." );
2901 static PyObject
* GemRB_GameControlSetScreenFlags(PyObject
* /*self*/, PyObject
* args
)
2903 int Flags
, Operation
;
2905 if (!PyArg_ParseTuple( args
, "ii", &Flags
, &Operation
)) {
2906 return AttributeError( GemRB_GameControlSetScreenFlags__doc
);
2908 if (Operation
< BM_SET
|| Operation
> BM_NAND
) {
2909 printMessage( "GUIScript",
2910 "Syntax Error: operation must be 0-4\n", LIGHT_RED
);
2914 GameControl
*gc
= core
->GetGameControl();
2916 printMessage ("GUIScript", "Flag cannot be set!\n",LIGHT_RED
);
2920 gc
->SetScreenFlags( Flags
, Operation
);
2922 Py_INCREF( Py_None
);
2927 PyDoc_STRVAR( GemRB_GameControlSetTargetMode__doc
,
2928 "GameControlSetTargetMode(Mode, Types)\n\n"
2929 "Sets the targetting mode of the main game screen control (attack, cast spell,...) and type of target (ally, enemy and/or neutral; all by default)" );
2931 static PyObject
* GemRB_GameControlSetTargetMode(PyObject
* /*self*/, PyObject
* args
)
2934 int Types
= GA_SELECT
| GA_NO_DEAD
| GA_NO_HIDDEN
;
2936 if (!PyArg_ParseTuple( args
, "i|i", &Mode
, &Types
)) {
2937 return AttributeError( GemRB_GameControlSetTargetMode__doc
);
2940 GameControl
*gc
= core
->GetGameControl();
2942 return RuntimeError("Can't find GameControl!");
2945 //target mode is only the low bits (which is a number)
2946 gc
->target_mode
= Mode
&GA_ACTION
;
2947 //target type is all the bits
2948 gc
->target_types
= (Mode
&GA_ACTION
)|Types
;
2950 Py_INCREF( Py_None
);
2954 PyDoc_STRVAR( GemRB_GameControlGetTargetMode__doc
,
2955 "GameControlGetTargetMode() => Mode\n\n"
2956 "Returns the targetting mode of the main game screen control (attack, cast spell,...)." );
2958 static PyObject
* GemRB_GameControlGetTargetMode(PyObject
* /*self*/, PyObject
* /*args*/)
2960 GameControl
*gc
= core
->GetGameControl();
2962 return RuntimeError("Can't find GameControl!");
2965 return PyInt_FromLong(gc
->target_mode
);
2968 PyDoc_STRVAR( GemRB_Button_SetFlags__doc
,
2969 "SetButtonFlags(WindowIndex, ControlIndex, Flags, Operation)\n\n"
2970 "Sets the Display Flags of a Button." );
2972 static PyObject
* GemRB_Button_SetFlags(PyObject
* /*self*/, PyObject
* args
)
2974 int WindowIndex
, ControlIndex
, Flags
, Operation
;
2976 if (!PyArg_ParseTuple( args
, "iiii", &WindowIndex
, &ControlIndex
, &Flags
, &Operation
)) {
2977 return AttributeError( GemRB_Button_SetFlags__doc
);
2979 if (Operation
< BM_SET
|| Operation
> BM_NAND
) {
2980 printMessage( "GUIScript",
2981 "Syntax Error: operation must be 0-4\n", LIGHT_RED
);
2985 Control
* btn
= ( Control
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
2990 if (btn
->SetFlags( Flags
, Operation
) ) {
2991 printMessage ("GUIScript", "Flag cannot be set!\n",LIGHT_RED
);
2995 Py_INCREF( Py_None
);
2999 PyDoc_STRVAR( GemRB_Control_TextArea_SetFlags__doc
,
3000 "SetTextAreaFlags(WindowIndex, ControlIndex, Flags, Operation)\n\n"
3001 "Sets the Display Flags of a TextArea. Flags are: IE_GUI_TA_SELECTABLE, IE_GUI_TA_AUTOSCROLL, IE_GUI_TA_SMOOTHSCROLL. Operation defaults to OP_SET." );
3003 static PyObject
* GemRB_Control_TextArea_SetFlags(PyObject
* /*self*/, PyObject
* args
)
3005 int WindowIndex
, ControlIndex
, Flags
;
3008 if (!PyArg_ParseTuple( args
, "iii|i", &WindowIndex
, &ControlIndex
, &Flags
, &Operation
)) {
3009 return AttributeError( GemRB_Control_TextArea_SetFlags__doc
);
3011 if (Operation
< BM_SET
|| Operation
> BM_NAND
) {
3012 printMessage( "GUIScript",
3013 "Syntax Error: operation must be 0-4\n", LIGHT_RED
);
3017 Control
* ta
= ( Control
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_TEXTAREA
);
3022 if (ta
->SetFlags( Flags
, Operation
)) {
3023 printMessage ("GUIScript", "Flag cannot be set!\n",LIGHT_RED
);
3027 Py_INCREF( Py_None
);
3031 PyDoc_STRVAR( GemRB_ScrollBar_SetDefaultScrollBar__doc
,
3032 "SetDefaultScrollBar(WindowIndex, ControlIndex)\n\n"
3033 "Sets the ScrollBar control as default." );
3035 static PyObject
* GemRB_ScrollBar_SetDefaultScrollBar(PyObject
* /*self*/, PyObject
* args
)
3037 int WindowIndex
, ControlIndex
;
3039 if (!PyArg_ParseTuple( args
, "ii", &WindowIndex
, &ControlIndex
)) {
3040 return AttributeError( GemRB_ScrollBar_SetDefaultScrollBar__doc
);
3043 Control
* sb
= ( Control
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_SCROLLBAR
);
3048 sb
->SetFlags( (IE_GUI_SCROLLBAR
<<24) | IE_GUI_SCROLLBAR_DEFAULT
, BM_OR
);
3050 Py_INCREF( Py_None
);
3054 PyDoc_STRVAR( GemRB_Button_SetState__doc
,
3055 "SetButtonState(WindowIndex, ControlIndex, State)\n\n"
3056 "Sets the state of a Button Control." );
3058 static PyObject
* GemRB_Button_SetState(PyObject
* /*self*/, PyObject
* args
)
3060 int WindowIndex
, ControlIndex
, state
;
3062 if (!PyArg_ParseTuple( args
, "iii", &WindowIndex
, &ControlIndex
, &state
)) {
3063 return AttributeError( GemRB_Button_SetState__doc
);
3066 Button
* btn
= ( Button
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
3071 btn
->SetState( state
);
3073 Py_INCREF( Py_None
);
3077 PyDoc_STRVAR( GemRB_Button_SetPictureClipping__doc
,
3078 "SetButtonPictureClipping(Window, Button, ClippingPercent)\n\n"
3079 "Sets percent (0-1.0) of width to which button picture will be clipped." );
3081 static PyObject
* GemRB_Button_SetPictureClipping(PyObject
* /*self*/, PyObject
* args
)
3083 int WindowIndex
, ControlIndex
;
3086 if (!PyArg_ParseTuple( args
, "iid", &WindowIndex
, &ControlIndex
, &Clipping
)) {
3087 return AttributeError( GemRB_Button_SetPictureClipping__doc
);
3090 Button
* btn
= ( Button
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
3095 if (Clipping
<0.0) Clipping
= 0.0;
3096 else if (Clipping
>1.0) Clipping
= 1.0;
3097 btn
->SetPictureClipping( Clipping
);
3099 Py_INCREF( Py_None
);
3103 PyDoc_STRVAR( GemRB_Button_SetPicture__doc
,
3104 "SetButtonPicture(WindowIndex, ControlIndex, PictureResRef, DefaultResRef)\n\n"
3105 "Sets the Picture of a Button Control from a BMP file. You can also supply a default picture." );
3107 static PyObject
* GemRB_Button_SetPicture(PyObject
* /*self*/, PyObject
* args
)
3109 int WindowIndex
, ControlIndex
;
3111 char *DefResRef
= NULL
;
3113 if (!PyArg_ParseTuple( args
, "iis|s", &WindowIndex
, &ControlIndex
, &ResRef
, &DefResRef
)) {
3114 return AttributeError( GemRB_Button_SetPicture__doc
);
3117 Button
* btn
= ( Button
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
3122 if (ResRef
[0] == 0) {
3123 btn
->SetPicture( NULL
);
3124 Py_INCREF( Py_None
);
3128 ImageFactory
* fact
= ( ImageFactory
* )
3129 gamedata
->GetFactoryResource( ResRef
, IE_BMP_CLASS_ID
, IE_NORMAL
);
3131 //if the resource doesn't exist, but we have a default resource
3133 if (!fact
&& DefResRef
) {
3134 fact
= ( ImageFactory
* )
3135 gamedata
->GetFactoryResource( DefResRef
, IE_BMP_CLASS_ID
, IE_NORMAL
);
3142 Sprite2D
* Picture
= fact
->GetSprite2D();
3143 if (Picture
== NULL
) {
3147 btn
->SetPicture( Picture
);
3149 Py_INCREF( Py_None
);
3153 PyDoc_STRVAR( GemRB_Button_SetSprite2D__doc
,
3154 "Button.SetSprite2D(WindowIndex, ControlIndex, Sprite2D)\n\n"
3155 "Sets a Sprite2D onto a button as picture." );
3157 static PyObject
* GemRB_Button_SetSprite2D(PyObject
* /*self*/, PyObject
* args
)
3162 if (!PyArg_ParseTuple( args
, "iiO", &wi
, &ci
, &obj
)) {
3163 return AttributeError( GemRB_Button_SetSprite2D__doc
);
3165 Button
* btn
= ( Button
* ) GetControl( wi
, ci
, IE_GUI_BUTTON
);
3170 CObject
<Sprite2D
> spr(obj
);
3174 btn
->SetPicture( spr
.get() );
3176 Py_INCREF( Py_None
);
3180 PyDoc_STRVAR( GemRB_Button_SetMOS__doc
,
3181 "SetButtonMOS(WindowIndex, ControlIndex, MOSResRef)\n\n"
3182 "Sets the Picture of a Button Control from a MOS file." );
3184 static PyObject
* GemRB_Button_SetMOS(PyObject
* /*self*/, PyObject
* args
)
3186 int WindowIndex
, ControlIndex
;
3189 if (!PyArg_ParseTuple( args
, "iis", &WindowIndex
, &ControlIndex
, &ResRef
)) {
3190 return AttributeError( GemRB_Button_SetMOS__doc
);
3193 Button
* btn
= ( Button
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
3198 if (ResRef
[0] == 0) {
3199 btn
->SetPicture( NULL
);
3200 Py_INCREF( Py_None
);
3204 ResourceHolder
<ImageMgr
> im(ResRef
);
3209 Sprite2D
* Picture
= im
->GetSprite2D();
3210 if (Picture
== NULL
) {
3214 btn
->SetPicture( Picture
);
3216 Py_INCREF( Py_None
);
3220 PyDoc_STRVAR( GemRB_Button_SetPLT__doc
,
3221 "SetButtonPLT(WindowIndex, ControlIndex, PLTResRef, col1, col2, col3, col4, col5, col6, col7, col8, type)\n\n"
3222 "Sets the Picture of a Button Control from a PLT file." );
3224 static PyObject
* GemRB_Button_SetPLT(PyObject
* /*self*/, PyObject
* args
)
3226 int WindowIndex
, ControlIndex
;
3231 memset(col
,-1,sizeof(col
));
3232 if (!PyArg_ParseTuple( args
, "iisiiiiiiii|i", &WindowIndex
, &ControlIndex
,
3233 &ResRef
, &(col
[0]), &(col
[1]), &(col
[2]), &(col
[3]),
3234 &(col
[4]), &(col
[5]), &(col
[6]), &(col
[7]), &type
) ) {
3235 return AttributeError( GemRB_Button_SetPLT__doc
);
3238 Button
* btn
= ( Button
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
3244 if (ResRef
[0] == 0 || ResRef
[0]=='*') {
3245 btn
->SetPicture( NULL
);
3246 Py_INCREF( Py_None
);
3251 Sprite2D
*Picture2
=NULL
;
3253 ResourceHolder
<PalettedImageMgr
> im(ResRef
);
3256 AnimationFactory
* af
= ( AnimationFactory
* )
3257 gamedata
->GetFactoryResource( ResRef
,
3258 IE_BAM_CLASS_ID
, IE_NORMAL
);
3260 printMessage("GUISCript","PLT/BAM not found for ref: ",YELLOW
);
3261 printf("%s\n", ResRef
);
3266 Py_INCREF( Py_None
);
3271 Picture
= af
->GetPaperdollImage(col
[0]==0xFFFFFFFF?0:col
, Picture2
,(unsigned int)type
);
3272 if (Picture
== NULL
) {
3273 printf ("Picture == NULL\n");
3277 Picture
= im
->GetSprite2D(type
, col
);
3278 if (Picture
== NULL
) {
3279 printf ("Picture == NULL\n");
3285 btn
->ClearPictureList();
3286 btn
->StackPicture(Picture
);
3288 btn
->SetFlags ( IE_GUI_BUTTON_BG1_PAPERDOLL
, BM_OR
);
3289 btn
->StackPicture( Picture2
);
3290 } else if (type
== 0) {
3291 btn
->SetFlags ( ~IE_GUI_BUTTON_BG1_PAPERDOLL
, BM_AND
);
3294 Py_INCREF( Py_None
);
3298 PyDoc_STRVAR( GemRB_Button_SetBAM__doc
,
3299 "SetButtonBAM(WindowIndex, ControlIndex, BAMResRef, CycleIndex, FrameIndex, col1)\n\n"
3300 "Sets the Picture of a Button Control from a BAM file. If col1 is >= 0, changes palette picture's palette to one specified by col1. Since it uses 12 colors palette, it has issues in PST." );
3302 static PyObject
* SetButtonBAM(int wi
, int ci
, const char *ResRef
, int CycleIndex
, int FrameIndex
, int col1
)
3304 Button
* btn
= ( Button
* ) GetControl(wi
, ci
, IE_GUI_BUTTON
);
3309 if (ResRef
[0] == 0) {
3310 btn
->SetPicture( NULL
);
3311 //no incref! (happens in caller if necessary)
3315 AnimationFactory
* af
= ( AnimationFactory
* )
3316 gamedata
->GetFactoryResource( ResRef
,
3317 IE_BAM_CLASS_ID
, IE_NORMAL
);
3320 Sprite2D
* Picture
= af
->GetFrame ( FrameIndex
, CycleIndex
);
3322 if (Picture
== NULL
) {
3327 Sprite2D
* old
= Picture
;
3328 Picture
= core
->GetVideoDriver()->DuplicateSprite(old
);
3329 core
->GetVideoDriver()->FreeSprite(old
);
3331 Palette
* newpal
= Picture
->GetPalette()->Copy();
3332 core
->GetPalette( col1
, 12, &newpal
->col
[4]);
3333 Picture
->SetPalette( newpal
);
3337 btn
->SetPicture( Picture
);
3339 //no incref! (happens in caller if necessary)
3343 static PyObject
* GemRB_Button_SetBAM(PyObject
* /*self*/, PyObject
* args
)
3345 int wi
, ci
, CycleIndex
, FrameIndex
, col1
= -1;
3348 if (!PyArg_ParseTuple( args
, "iisii|i", &wi
, &ci
,
3349 &ResRef
, &CycleIndex
, &FrameIndex
, &col1
)) {
3350 return AttributeError( GemRB_Button_SetBAM__doc
);
3353 PyObject
*ret
= SetButtonBAM(wi
,ci
, ResRef
, CycleIndex
, FrameIndex
,col1
);
3360 PyDoc_STRVAR( GemRB_Control_SetAnimationPalette__doc
,
3361 "SetAnimationPalette(WindowIndex, ControlIndex, col1, col2, col3, col4, col5, col6, col7, col8)\n\n"
3362 "Sets the palette of an animation already assigned to the button.");
3364 static PyObject
* GemRB_Control_SetAnimationPalette(PyObject
* /*self*/, PyObject
* args
)
3369 memset(col
,-1,sizeof(col
));
3370 if (!PyArg_ParseTuple( args
, "iiiiiiiiii", &wi
, &ci
,
3371 &(col
[0]), &(col
[1]), &(col
[2]), &(col
[3]),
3372 &(col
[4]), &(col
[5]), &(col
[6]), &(col
[7])) ) {
3373 return AttributeError( GemRB_Control_SetAnimationPalette__doc
);
3376 Control
* ctl
= GetControl(wi
, ci
, -1);
3381 ControlAnimation
* anim
= ctl
->animation
;
3383 return RuntimeError("No animation!");
3386 anim
->SetPaletteGradients(col
);
3387 Py_INCREF( Py_None
);
3391 PyDoc_STRVAR( GemRB_Control_SetAnimation__doc
,
3392 "SetAnimation(WindowIndex, ControlIndex, BAMResRef[, Cycle])\n\n"
3393 "Sets the animation of a Control (usually a Button) from a BAM file. Optionally an animation cycle could be set too.");
3395 static PyObject
* GemRB_Control_SetAnimation(PyObject
* /*self*/, PyObject
* args
)
3401 if (!PyArg_ParseTuple( args
, "iis|i", &wi
, &ci
, &ResRef
, &Cycle
)) {
3402 return AttributeError( GemRB_Control_SetAnimation__doc
);
3405 Control
* ctl
= GetControl(wi
, ci
, -1);
3410 //who knows, there might have been an active animation lurking
3411 if (ctl
->animation
) {
3412 //if this control says the resource is the same
3413 //we wanted to set, we don't reset it
3414 if(ctl
->animation
->SameResource(ResRef
, Cycle
)) {
3415 Py_INCREF( Py_None
);
3418 delete ctl
->animation
;
3419 ctl
->animation
= NULL
;
3422 if (ResRef
[0] == 0) {
3423 ctl
->SetAnimPicture( NULL
);
3424 Py_INCREF( Py_None
);
3428 ControlAnimation
* anim
= new ControlAnimation( ctl
, ResRef
, Cycle
);
3430 anim
->UpdateAnimation();
3432 Py_INCREF( Py_None
);
3437 PyDoc_STRVAR( GemRB_PlaySound__doc
,
3438 "PlaySound(SoundResource, xpos, ypos, type)\n\n"
3441 static PyObject
* GemRB_PlaySound(PyObject
* /*self*/, PyObject
* args
)
3446 unsigned int flags
= 1; //GEM_SND_RELATIVE
3448 if (!PyArg_ParseTuple( args
, "z|iii", &ResRef
, &xpos
, &ypos
, &flags
)) {
3449 return AttributeError( GemRB_PlaySound__doc
);
3452 core
->GetAudioDrv()->Play( ResRef
, xpos
, ypos
, flags
);
3454 Py_INCREF( Py_None
);
3458 PyDoc_STRVAR( GemRB_DrawWindows__doc
,
3460 "Refreshes the User Interface." );
3462 static PyObject
* GemRB_DrawWindows(PyObject
* /*self*/, PyObject
* /*args*/)
3464 core
->DrawWindows();
3466 Py_INCREF( Py_None
);
3470 PyDoc_STRVAR( GemRB_Quit__doc
,
3474 static PyObject
* GemRB_Quit(PyObject
* /*self*/, PyObject
* /*args*/)
3476 bool ret
= core
->Quit();
3481 Py_INCREF( Py_None
);
3485 PyDoc_STRVAR( GemRB_LoadMusicPL__doc
,
3486 "LoadMusicPL(MusicPlayListResource, HardEnd)\n\n"
3487 "Loads and starts a Music PlayList." );
3489 static PyObject
* GemRB_LoadMusicPL(PyObject
* /*self*/, PyObject
* args
)
3494 if (!PyArg_ParseTuple( args
, "s|i", &ResRef
, &HardEnd
)) {
3495 return AttributeError( GemRB_LoadMusicPL__doc
);
3498 core
->GetMusicMgr()->SwitchPlayList( ResRef
, (bool) HardEnd
);
3500 Py_INCREF( Py_None
);
3504 PyDoc_STRVAR( GemRB_SoftEndPL__doc
,
3506 "Ends a Music Playlist softly." );
3508 static PyObject
* GemRB_SoftEndPL(PyObject
* /*self*/, PyObject
* /*args*/)
3510 core
->GetMusicMgr()->End();
3512 Py_INCREF( Py_None
);
3516 PyDoc_STRVAR( GemRB_HardEndPL__doc
,
3518 "Ends a Music Playlist immediately." );
3520 static PyObject
* GemRB_HardEndPL(PyObject
* /*self*/, PyObject
* /*args*/)
3522 core
->GetMusicMgr()->HardEnd();
3524 Py_INCREF( Py_None
);
3528 PyDoc_STRVAR( GemRB_SetToken__doc
,
3529 "SetToken(VariableName, Value)\n\n"
3530 "Set/Create a token to be replaced in StrRefs." );
3532 static PyObject
* GemRB_SetToken(PyObject
* /*self*/, PyObject
* args
)
3537 if (!PyArg_ParseTuple( args
, "ss", &Variable
, &value
)) {
3538 return AttributeError( GemRB_SetToken__doc
);
3540 core
->GetTokenDictionary()->SetAtCopy( Variable
, value
);
3542 Py_INCREF( Py_None
);
3546 PyDoc_STRVAR( GemRB_SetVar__doc
,
3547 "SetVar(VariableName, Value)\n\n"
3548 "Set/Create a Variable in the Global Dictionary." );
3550 static PyObject
* GemRB_SetVar(PyObject
* /*self*/, PyObject
* args
)
3553 //this should be 32 bits, always, but i cannot tell that to Python
3554 unsigned long value
;
3556 if (!PyArg_ParseTuple( args
, "sl", &Variable
, &value
)) {
3557 return AttributeError( GemRB_SetVar__doc
);
3560 core
->GetDictionary()->SetAt( Variable
, (ieDword
) value
);
3562 Py_INCREF( Py_None
);
3566 PyDoc_STRVAR( GemRB_GetMessageWindowSize__doc
,
3567 "GetMessageWindowSize() => int\n\n"
3568 "Returns current MessageWindowSize, it works only when a game is loaded." );
3570 static PyObject
* GemRB_GetMessageWindowSize(PyObject
* /*self*/, PyObject
* /*args*/)
3572 Game
*game
= core
->GetGame();
3574 return RuntimeError( "No game loaded!" );
3576 return PyInt_FromLong( game
->ControlStatus
);
3579 PyDoc_STRVAR( GemRB_GetToken__doc
,
3580 "GetToken(VariableName) => string\n\n"
3581 "Get a Variable value from the Token Dictionary." );
3583 static PyObject
* GemRB_GetToken(PyObject
* /*self*/, PyObject
* args
)
3585 const char *Variable
;
3588 if (!PyArg_ParseTuple( args
, "s", &Variable
)) {
3589 return AttributeError( GemRB_GetToken__doc
);
3592 //returns only the pointer
3593 if (!core
->GetTokenDictionary()->Lookup( Variable
, value
)) {
3594 return PyString_FromString( "" );
3597 return PyString_FromString( value
);
3600 PyDoc_STRVAR( GemRB_GetVar__doc
,
3601 "GetVar(VariableName) => int\n\n"
3602 "Get a Variable value from the Global Dictionary." );
3604 static PyObject
* GemRB_GetVar(PyObject
* /*self*/, PyObject
* args
)
3606 const char *Variable
;
3609 if (!PyArg_ParseTuple( args
, "s", &Variable
)) {
3610 return AttributeError( GemRB_GetVar__doc
);
3613 if (!core
->GetDictionary()->Lookup( Variable
, value
)) {
3614 return PyInt_FromLong( 0 );
3617 // A PyInt is internally (probably) a long. Since we sometimes set
3618 // variables to -1, cast value to a signed integer first, so it is
3619 // sign-extended into a long if long is larger than int.
3620 return PyInt_FromLong( (int)value
);
3623 PyDoc_STRVAR( GemRB_CheckVar__doc
,
3624 "CheckVar(VariableName, Context) => long\n\n"
3625 "Return (and output on terminal) the value of a Game Variable." );
3627 static PyObject
* GemRB_CheckVar(PyObject
* /*self*/, PyObject
* args
)
3632 if (!PyArg_ParseTuple( args
, "ss", &Variable
, &Context
)) {
3633 return AttributeError( GemRB_CheckVar__doc
);
3635 GameControl
*gc
= core
->GetGameControl();
3637 return RuntimeError("Can't find GameControl!");
3639 Scriptable
*Sender
= (Scriptable
*) gc
->GetLastActor();
3641 Sender
= (Scriptable
*) core
->GetGame()->GetCurrentArea();
3644 printMessage("GUIScript","No Game!\n", LIGHT_RED
);
3647 long value
=(long) CheckVariable(Sender
, Variable
, Context
);
3648 printMessage("GUISCript"," ",YELLOW
);
3649 printf("%s %s=%ld\n",Context
, Variable
, value
);
3651 return PyInt_FromLong( value
);
3654 PyDoc_STRVAR( GemRB_SetGlobal__doc
,
3655 "SetGlobal(VariableName, Context, Value)\n\n"
3656 "Sets a gamescript variable to the specificed numeric value." );
3658 static PyObject
* GemRB_SetGlobal(PyObject
* /*self*/, PyObject
* args
)
3664 if (!PyArg_ParseTuple( args
, "ssi", &Variable
, &Context
, &Value
)) {
3665 return AttributeError( GemRB_SetGlobal__doc
);
3668 Scriptable
*Sender
= NULL
;
3669 Game
*game
= core
->GetGame();
3671 printMessage("GUIScript","No Game!\n", LIGHT_RED
);
3674 if (!strnicmp(Context
, "MYAREA", 6) || !strnicmp(Context
, "LOCALS", 6)) {
3675 GameControl
*gc
= core
->GetGameControl();
3677 return RuntimeError("Can't find GameControl!");
3679 Sender
= (Scriptable
*) gc
->GetLastActor();
3681 Sender
= (Scriptable
*) game
->GetCurrentArea();
3684 printMessage("GUIScript","No Sender!\n", LIGHT_RED
);
3687 } // else GLOBAL, area name or KAPUTZ
3689 SetVariable(Sender
, Variable
, Context
, (ieDword
) Value
);
3690 Py_INCREF( Py_None
);
3694 PyDoc_STRVAR( GemRB_GetGameVar__doc
,
3695 "GetGameVar(VariableName) => long\n\n"
3696 "Get a Variable value from the Game Global Dictionary." );
3698 static PyObject
* GemRB_GetGameVar(PyObject
* /*self*/, PyObject
* args
)
3700 const char *Variable
;
3703 if (!PyArg_ParseTuple( args
, "s", &Variable
)) {
3704 return AttributeError( GemRB_GetGameVar__doc
);
3707 if (!core
->GetGame()->locals
->Lookup( Variable
, value
)) {
3708 return PyInt_FromLong( ( unsigned long ) 0 );
3711 return PyInt_FromLong( (unsigned long) value
);
3714 PyDoc_STRVAR( GemRB_PlayMovie__doc
,
3715 "PlayMovie(MOVResRef[, flag]) => int\n\n"
3716 "Plays the movie named. If flag is set to 1, it won't play it if it was already played once (set in .ini). It returns 0 if it played the movie." );
3718 static PyObject
* GemRB_PlayMovie(PyObject
* /*self*/, PyObject
* args
)
3723 if (!PyArg_ParseTuple( args
, "s|i", &string
, &flag
)) {
3724 return AttributeError( GemRB_PlayMovie__doc
);
3729 //Lookup will leave the flag untouched if it doesn't exist yet
3730 core
->GetDictionary()->Lookup(string
, ind
);
3734 ind
= core
->PlayMovie( string
);
3737 return PyInt_FromLong( ind
);
3740 PyDoc_STRVAR( GemRB_SaveCharacter__doc
,
3741 "SaveCharacter(PartyID, CharName)\n\n"
3742 "Exports the character from party.");
3744 static PyObject
* GemRB_SaveCharacter(PyObject
* /*self*/, PyObject
* args
)
3749 if (!PyArg_ParseTuple( args
, "is", &PartyID
, &name
)) {
3750 return AttributeError( GemRB_SaveCharacter__doc
);
3753 return AttributeError( GemRB_SaveCharacter__doc
);
3756 Game
*game
= core
->GetGame();
3758 return RuntimeError( "No game loaded!" );
3760 Actor
*actor
= game
->FindPC(PartyID
);
3762 return RuntimeError( "Actor not found" );
3764 return PyInt_FromLong(core
->WriteCharacter(name
, actor
) );
3767 PyDoc_STRVAR( GemRB_SaveGame__doc
,
3768 "SaveGame(SlotCount, GameName[,version])\n\n"
3769 "Dumps the save game, if version is given, it will save a specific version.");
3771 static PyObject
* GemRB_SaveGame(PyObject
* /*self*/, PyObject
* args
)
3777 if (!PyArg_ParseTuple( args
, "Os|i", &obj
, &folder
, &Version
)) {
3778 return AttributeError( GemRB_SaveGame__doc
);
3781 CObject
<SaveGame
> save(obj
);
3783 Game
*game
= core
->GetGame();
3785 return RuntimeError( "No game loaded!" );
3788 SaveGameIterator
*sgi
= core
->GetSaveGameIterator();
3790 return RuntimeError("No savegame iterator");
3794 game
->version
= Version
;
3796 return PyInt_FromLong(sgi
->CreateSaveGame(save
.get(), folder
) );
3799 PyDoc_STRVAR( GemRB_GetSaveGames__doc
,
3800 "GetSaveGameCount() => int\n\n"
3801 "Returns the list of saved games." );
3803 static PyObject
* GemRB_GetSaveGames(PyObject
* /*self*/, PyObject
* /*args*/)
3805 return MakePyList
<SaveGame
>(core
->GetSaveGameIterator()->GetSaveGames());
3808 PyDoc_STRVAR( GemRB_DeleteSaveGame__doc
,
3809 "DeleteSaveGame(Slot)\n\n"
3810 "Deletes a saved game folder completely." );
3812 static PyObject
* GemRB_DeleteSaveGame(PyObject
* /*self*/, PyObject
* args
)
3816 if (!PyArg_ParseTuple( args
, "O", &Slot
)) {
3817 return AttributeError( GemRB_DeleteSaveGame__doc
);
3820 CObject
<SaveGame
> game(Slot
);
3821 core
->GetSaveGameIterator()->DeleteSaveGame( game
.get() );
3822 Py_INCREF( Py_None
);
3826 PyDoc_STRVAR( GemRB_SaveGame_GetName__doc
,
3827 "SaveGame.GetName() => string/int\n\n"
3828 "Returns name of the saved game." );
3830 static PyObject
* GemRB_SaveGame_GetName(PyObject
* /*self*/, PyObject
* args
)
3834 if (!PyArg_ParseTuple( args
, "O", &Slot
)) {
3835 return AttributeError( GemRB_SaveGame_GetName__doc
);
3838 CObject
<SaveGame
> save(Slot
);
3839 return PyString_FromString(save
->GetName());
3842 PyDoc_STRVAR( GemRB_SaveGame_GetDate__doc
,
3843 "SaveGame.GetDate() => string/int\n\n"
3844 "Returns date of the saved game." );
3846 static PyObject
* GemRB_SaveGame_GetDate(PyObject
* /*self*/, PyObject
* args
)
3850 if (!PyArg_ParseTuple( args
, "O", &Slot
)) {
3851 return AttributeError( GemRB_SaveGame_GetDate__doc
);
3854 CObject
<SaveGame
> save(Slot
);
3855 return PyString_FromString(save
->GetDate());
3858 PyDoc_STRVAR( GemRB_SaveGame_GetGameDate__doc
,
3859 "SaveGame.GetGameDate() => string/int\n\n"
3860 "Returns game date of the saved game." );
3862 static PyObject
* GemRB_SaveGame_GetGameDate(PyObject
* /*self*/, PyObject
* args
)
3866 if (!PyArg_ParseTuple( args
, "O", &Slot
)) {
3867 return AttributeError( GemRB_SaveGame_GetGameDate__doc
);
3870 CObject
<SaveGame
> save(Slot
);
3871 return PyString_FromString(save
->GetGameDate());
3874 PyDoc_STRVAR( GemRB_SaveGame_GetSaveID__doc
,
3875 "SaveGame.GetSaveID() => string/int\n\n"
3876 "Returns ID of the saved game." );
3878 static PyObject
* GemRB_SaveGame_GetSaveID(PyObject
* /*self*/, PyObject
* args
)
3882 if (!PyArg_ParseTuple( args
, "O", &Slot
)) {
3883 return AttributeError( GemRB_SaveGame_GetSaveID__doc
);
3886 CObject
<SaveGame
> save(Slot
);
3887 return PyInt_FromLong(save
->GetSaveID());
3890 PyDoc_STRVAR( GemRB_SaveGame_GetPreview__doc
,
3891 "SaveGame.GetPreview() => string/int\n\n"
3892 "Returns preview of the saved game." );
3894 static PyObject
* GemRB_SaveGame_GetPreview(PyObject
* /*self*/, PyObject
* args
)
3898 if (!PyArg_ParseTuple( args
, "O", &Slot
)) {
3899 return AttributeError( GemRB_SaveGame_GetPreview__doc
);
3902 CObject
<SaveGame
> save(Slot
);
3903 return CObject
<Sprite2D
>(save
->GetPreview());
3906 PyDoc_STRVAR( GemRB_SaveGame_GetPortrait__doc
,
3907 "SaveGame.GetPortrait(int index) => string/int\n\n"
3908 "Returns portrait of the saved game." );
3910 static PyObject
* GemRB_SaveGame_GetPortrait(PyObject
* /*self*/, PyObject
* args
)
3915 if (!PyArg_ParseTuple( args
, "Oi", &Slot
, &index
)) {
3916 return AttributeError( GemRB_SaveGame_GetPortrait__doc
);
3919 CObject
<SaveGame
> save(Slot
);
3920 return CObject
<Sprite2D
>(save
->GetPortrait(index
));
3923 PyDoc_STRVAR( GemRB_GetGamePreview__doc
,
3924 "GetGamePreview()\n\n"
3925 "Gets current game area preview." );
3927 static PyObject
* GemRB_GetGamePreview(PyObject
* /*self*/, PyObject
* args
)
3929 if (!PyArg_ParseTuple( args
, "" )) {
3930 return AttributeError( GemRB_GetGamePreview__doc
);
3933 return CObject
<Sprite2D
>(core
->GetGameControl()->GetPreview());
3936 PyDoc_STRVAR( GemRB_GetGamePortraitPreview__doc
,
3937 "GetGamePortraitPreview(PCSlotCount)\n\n"
3938 "Gets a current game PC portrait." );
3940 static PyObject
* GemRB_GetGamePortraitPreview(PyObject
* /*self*/, PyObject
* args
)
3944 if (!PyArg_ParseTuple( args
, "i", &PCSlotCount
)) {
3945 return AttributeError( GemRB_GetGamePreview__doc
);
3948 return CObject
<Sprite2D
>(core
->GetGameControl()->GetPortraitPreview(PCSlotCount
));
3951 PyDoc_STRVAR( GemRB_Roll__doc
,
3952 "Roll(Dice, Size, Add) => int\n\n"
3953 "Calls traditional dice roll." );
3955 static PyObject
* GemRB_Roll(PyObject
* /*self*/, PyObject
* args
)
3957 int Dice
, Size
, Add
;
3959 if (!PyArg_ParseTuple( args
, "iii", &Dice
, &Size
, &Add
)) {
3960 return AttributeError( GemRB_Roll__doc
);
3962 return PyInt_FromLong( core
->Roll( Dice
, Size
, Add
) );
3965 PyDoc_STRVAR( GemRB_TextArea_GetPortraits__doc
,
3966 "GetPortraits(WindowIndex, ControlIndex, SmallOrLarge) => int\n\n"
3967 "Reads in the contents of the portraits subfolder." );
3969 static PyObject
* GemRB_TextArea_GetPortraits(PyObject
* /*self*/, PyObject
* args
)
3974 if (!PyArg_ParseTuple( args
, "iii", &wi
, &ci
, &suffix
)) {
3975 return AttributeError( GemRB_TextArea_GetPortraits__doc
);
3977 TextArea
* ta
= ( TextArea
* ) GetControl( wi
, ci
, IE_GUI_TEXTAREA
);
3981 return PyInt_FromLong( core
->GetPortraits( ta
, suffix
) );
3984 PyDoc_STRVAR( GemRB_TextArea_GetCharSounds__doc
,
3985 "GetCharSounds(WindowIndex, ControlIndex) => int\n\n"
3986 "Reads in the contents of the sounds subfolder." );
3988 static PyObject
* GemRB_TextArea_GetCharSounds(PyObject
* /*self*/, PyObject
* args
)
3992 if (!PyArg_ParseTuple( args
, "ii", &wi
, &ci
)) {
3993 return AttributeError( GemRB_TextArea_GetCharSounds__doc
);
3995 TextArea
* ta
= ( TextArea
* ) GetControl( wi
, ci
, IE_GUI_TEXTAREA
);
3999 return PyInt_FromLong( core
->GetCharSounds( ta
) );
4002 PyDoc_STRVAR( GemRB_TextArea_GetCharacters__doc
,
4003 "GetCharacters(WindowIndex, ControlIndex) => int\n\n"
4004 "Reads in the contents of the characters subfolder." );
4006 static PyObject
* GemRB_TextArea_GetCharacters(PyObject
* /*self*/, PyObject
* args
)
4010 if (!PyArg_ParseTuple( args
, "ii", &wi
, &ci
)) {
4011 return AttributeError( GemRB_TextArea_GetCharacters__doc
);
4013 TextArea
* ta
= ( TextArea
* ) GetControl( wi
, ci
, IE_GUI_TEXTAREA
);
4017 return PyInt_FromLong( core
->GetCharacters( ta
) );
4020 PyDoc_STRVAR( GemRB_GetPartySize__doc
,
4021 "GetPartySize() => int\n\n"
4022 "Returns the number of PCs." );
4024 static PyObject
* GemRB_GetPartySize(PyObject
* /*self*/, PyObject
* /*args*/)
4026 Game
*game
= core
->GetGame();
4028 return RuntimeError( "No game loaded!" );
4030 return PyInt_FromLong( game
->GetPartySize(0) );
4033 PyDoc_STRVAR( GemRB_GetGameTime__doc
,
4034 "GetGameTime() => int\n\n"
4035 "Returns current game time." );
4037 static PyObject
* GemRB_GetGameTime(PyObject
* /*self*/, PyObject
* /*args*/)
4039 unsigned long GameTime
= core
->GetGame()->GameTime
/AI_UPDATE_TIME
;
4040 return PyInt_FromLong( GameTime
);
4043 PyDoc_STRVAR( GemRB_GameGetReputation__doc
,
4044 "GameGetReputation() => int\n\n"
4045 "Returns party reputation." );
4047 static PyObject
* GemRB_GameGetReputation(PyObject
* /*self*/, PyObject
* /*args*/)
4049 int Reputation
= (int) core
->GetGame()->Reputation
;
4050 return PyInt_FromLong( Reputation
);
4053 PyDoc_STRVAR( GemRB_GameSetReputation__doc
,
4054 "GameSetReputation(Reputation)\n\n"
4055 "Sets current party reputation." );
4057 static PyObject
* GemRB_GameSetReputation(PyObject
* /*self*/, PyObject
* args
)
4061 if (!PyArg_ParseTuple( args
, "i", &Reputation
)) {
4062 return AttributeError( GemRB_GameSetReputation__doc
);
4064 core
->GetGame()->SetReputation( (unsigned int) Reputation
);
4066 Py_INCREF( Py_None
);
4070 void ReadReputation()
4072 int table
= gamedata
->LoadTable( "reputati" );
4074 memset(ReputationIncrease
,0,sizeof(ReputationIncrease
) );
4075 memset(ReputationDonation
,0,sizeof(ReputationDonation
) );
4078 Holder
<TableMgr
> tab
= gamedata
->GetTable( table
);
4079 for (int i
= 0; i
< 20; i
++) {
4080 ReputationIncrease
[i
] = atoi( tab
->QueryField(i
,4) );
4081 ReputationDonation
[i
] = atoi( tab
->QueryField(i
,8) );
4083 gamedata
->DelTable( table
);
4086 PyDoc_STRVAR( GemRB_IncreaseReputation__doc
,
4087 "IncreaseReputation( donation ) => int\n\n"
4088 "Increases party reputation according to the donation. (See reputati.2da)" );
4090 static PyObject
* GemRB_IncreaseReputation(PyObject
* /*self*/, PyObject
* args
)
4095 if (!PyArg_ParseTuple( args
, "i", &Donation
)) {
4096 return AttributeError( GemRB_IncreaseReputation__doc
);
4099 Game
*game
= core
->GetGame();
4101 return RuntimeError( "No game loaded!" );
4103 int Row
= (game
->Reputation
-9)/10;
4107 if (ReputationDonation
[0]==(int) UNINIT_IEDWORD
) {
4110 int Limit
= ReputationDonation
[Row
];
4111 if (Limit
<=Donation
) {
4112 Increase
= ReputationIncrease
[Row
];
4114 game
->SetReputation( game
->Reputation
+ Increase
);
4117 return PyInt_FromLong ( Increase
);
4120 PyDoc_STRVAR( GemRB_GameGetPartyGold__doc
,
4121 "GameGetPartyGold() => int\n\n"
4122 "Returns current party gold." );
4124 static PyObject
* GemRB_GameGetPartyGold(PyObject
* /*self*/, PyObject
* /*args*/)
4126 Game
*game
= core
->GetGame();
4128 return RuntimeError( "No game loaded!" );
4130 int Gold
= game
->PartyGold
;
4131 return PyInt_FromLong( Gold
);
4134 PyDoc_STRVAR( GemRB_GameSetPartyGold__doc
,
4135 "GameSetPartyGold(Gold)\n\n"
4136 "Sets current party gold." );
4138 static PyObject
* GemRB_GameSetPartyGold(PyObject
* /*self*/, PyObject
* args
)
4142 if (!PyArg_ParseTuple( args
, "i|i", &Gold
, &flag
)) {
4143 return AttributeError( GemRB_GameSetPartyGold__doc
);
4145 Game
*game
= core
->GetGame();
4147 return RuntimeError( "No game loaded!" );
4150 game
->AddGold((ieDword
) Gold
);
4152 game
->PartyGold
=Gold
;
4155 Py_INCREF( Py_None
);
4159 PyDoc_STRVAR( GemRB_GameGetFormation__doc
,
4160 "GameGetFormation([Which]) => int\n\n"
4161 "Returns current party formation. If Which was supplied, it returns one of the preset formations." );
4163 static PyObject
* GemRB_GameGetFormation(PyObject
* /*self*/, PyObject
* args
)
4168 if (!PyArg_ParseTuple( args
, "|i", &Which
)) {
4169 return AttributeError( GemRB_GameGetFormation__doc
);
4172 Formation
= core
->GetGame()->WhichFormation
;
4175 return AttributeError( GemRB_GameGetFormation__doc
);
4177 Formation
= core
->GetGame()->Formations
[Which
];
4179 return PyInt_FromLong( Formation
);
4182 PyDoc_STRVAR( GemRB_GameSetFormation__doc
,
4183 "GameSetFormation(Formation[, Which])\n\n"
4184 "Sets party formation. If Which was supplied, it sets one of the preset formations." );
4186 static PyObject
* GemRB_GameSetFormation(PyObject
* /*self*/, PyObject
* args
)
4188 int Formation
, Which
=-1;
4190 if (!PyArg_ParseTuple( args
, "i|i", &Formation
, &Which
)) {
4191 return AttributeError( GemRB_GameSetFormation__doc
);
4194 core
->GetGame()->WhichFormation
= Formation
;
4197 return AttributeError( GemRB_GameSetFormation__doc
);
4199 core
->GetGame()->Formations
[Which
] = Formation
;
4202 Py_INCREF( Py_None
);
4206 PyDoc_STRVAR( GemRB_GetJournalSize__doc
,
4207 "GetJournalSize(chapter[, section]) => int\n\n"
4208 "Returns the number of entries in the given section of journal." );
4210 static PyObject
* GemRB_GetJournalSize(PyObject
* /*self*/, PyObject
* args
)
4215 if (!PyArg_ParseTuple( args
, "i|i", &chapter
, §ion
)) {
4216 return AttributeError( GemRB_GetJournalSize__doc
);
4220 for (unsigned int i
= 0; i
< core
->GetGame()->GetJournalCount(); i
++) {
4221 GAMJournalEntry
* je
= core
->GetGame()->GetJournalEntry( i
);
4222 //printf ("JE: sec: %d; text: %d, time: %d, chapter: %d, un09: %d, un0b: %d\n", je->Section, je->Text, je->GameTime, je->Chapter, je->unknown09, je->unknown0B);
4223 if ((section
== -1 || section
== je
->Section
) && (chapter
==je
->Chapter
) )
4227 return PyInt_FromLong( count
);
4230 PyDoc_STRVAR( GemRB_GetJournalEntry__doc
,
4231 "GetJournalEntry(chapter, index[, section]) => JournalEntry\n\n"
4232 "Returns dictionary representing journal entry w/ given chapter, section and index." );
4234 static PyObject
* GemRB_GetJournalEntry(PyObject
* /*self*/, PyObject
* args
)
4236 int section
=-1, index
, chapter
;
4238 if (!PyArg_ParseTuple( args
, "ii|i", &chapter
, &index
, §ion
)) {
4239 return AttributeError( GemRB_GetJournalEntry__doc
);
4243 for (unsigned int i
= 0; i
< core
->GetGame()->GetJournalCount(); i
++) {
4244 GAMJournalEntry
* je
= core
->GetGame()->GetJournalEntry( i
);
4245 if ((section
== -1 || section
== je
->Section
) && (chapter
== je
->Chapter
)) {
4246 if (index
== count
) {
4247 PyObject
* dict
= PyDict_New();
4248 PyDict_SetItemString(dict
, "Text", PyInt_FromLong ((signed) je
->Text
));
4249 PyDict_SetItemString(dict
, "GameTime", PyInt_FromLong (je
->GameTime
));
4250 PyDict_SetItemString(dict
, "Section", PyInt_FromLong (je
->Section
));
4251 PyDict_SetItemString(dict
, "Chapter", PyInt_FromLong (je
->Chapter
));
4259 Py_INCREF( Py_None
);
4263 PyDoc_STRVAR( GemRB_GameIsBeastKnown__doc
,
4264 "GameIsBeastKnown(index) => int\n\n"
4265 "Returns whether beast with given index is known to PCs (works only on PST)." );
4267 static PyObject
* GemRB_GameIsBeastKnown(PyObject
* /*self*/, PyObject
* args
)
4270 if (!PyArg_ParseTuple( args
, "i", &index
)) {
4271 return AttributeError( GemRB_GameIsBeastKnown__doc
);
4274 return PyInt_FromLong( core
->GetGame()->IsBeastKnown( index
));
4277 PyDoc_STRVAR( GemRB_GetINIPartyCount__doc
,
4278 "GetINIPartyCount() =>int\n\n"
4279 "Returns the Number of Party defined in Party.ini (works only on IWD2)." );
4281 static PyObject
* GemRB_GetINIPartyCount(PyObject
* /*self*/,
4282 PyObject
* /*args*/)
4284 if (!core
->GetPartyINI()) {
4285 return RuntimeError( "INI resource not found!" );
4287 return PyInt_FromLong( core
->GetPartyINI()->GetTagsCount() );
4290 PyDoc_STRVAR( GemRB_GetINIQuestsKey__doc
,
4291 "GetINIQuestsKey(Tag, Key, Default) => string\n\n"
4292 "Returns a Value from the quests.ini File (works only on PST)." );
4294 static PyObject
* GemRB_GetINIQuestsKey(PyObject
* /*self*/, PyObject
* args
)
4296 char *Tag
, *Key
, *Default
;
4298 if (!PyArg_ParseTuple( args
, "sss", &Tag
, &Key
, &Default
)) {
4299 return AttributeError( GemRB_GetINIQuestsKey__doc
);
4301 if (!core
->GetQuestsINI()) {
4302 return RuntimeError( "INI resource not found!" );
4304 return PyString_FromString(
4305 core
->GetQuestsINI()->GetKeyAsString( Tag
, Key
, Default
) );
4308 PyDoc_STRVAR( GemRB_GetINIBeastsKey__doc
,
4309 "GetINIBeastsKey(Tag, Key, Default) => string\n\n"
4310 "Returns a Value from the beasts.ini File (works only on PST)." );
4312 static PyObject
* GemRB_GetINIBeastsKey(PyObject
* /*self*/, PyObject
* args
)
4314 char *Tag
, *Key
, *Default
;
4316 if (!PyArg_ParseTuple( args
, "sss", &Tag
, &Key
, &Default
)) {
4317 return AttributeError( GemRB_GetINIBeastsKey__doc
);
4319 if (!core
->GetBeastsINI()) {
4322 return PyString_FromString(
4323 core
->GetBeastsINI()->GetKeyAsString( Tag
, Key
, Default
) );
4326 PyDoc_STRVAR( GemRB_GetINIPartyKey__doc
,
4327 "GetINIPartyKey(Tag, Key, Default) => string\n\n"
4328 "Returns a Value from the Party.ini File (works only on IWD2)." );
4330 static PyObject
* GemRB_GetINIPartyKey(PyObject
* /*self*/, PyObject
* args
)
4332 const char *Tag
, *Key
, *Default
;
4334 if (!PyArg_ParseTuple( args
, "sss", &Tag
, &Key
, &Default
)) {
4335 return AttributeError( GemRB_GetINIPartyKey__doc
);
4337 if (!core
->GetPartyINI()) {
4338 return RuntimeError( "INI resource not found!" );
4340 return PyString_FromString(
4341 core
->GetPartyINI()->GetKeyAsString( Tag
, Key
, Default
) );
4344 PyDoc_STRVAR( GemRB_CreatePlayer__doc
,
4345 "CreatePlayer(CREResRef, Slot [,Import] ) => PlayerSlot\n\n"
4346 "Creates or removes a player character in a given party slot. If import is nonzero, then reads a CHR instead of a CRE." );
4348 static PyObject
* GemRB_CreatePlayer(PyObject
* /*self*/, PyObject
* args
)
4350 const char *CreResRef
;
4351 int PlayerSlot
, Slot
;
4354 if (!PyArg_ParseTuple( args
, "si|i", &CreResRef
, &PlayerSlot
, &Import
)) {
4355 return AttributeError( GemRB_CreatePlayer__doc
);
4357 //PlayerSlot is zero based
4358 Slot
= ( PlayerSlot
& 0x7fff );
4359 Game
*game
= core
->GetGame();
4361 return RuntimeError( "No game loaded!" );
4363 //FIXME:overwriting original slot
4364 //is dangerous if the game is already loaded
4365 //maybe the actor should be removed from the area first
4366 if (PlayerSlot
& 0x8000) {
4367 PlayerSlot
= game
->FindPlayer( Slot
);
4368 if (PlayerSlot
>= 0) {
4369 game
->DelPC(PlayerSlot
, true);
4372 PlayerSlot
= game
->FindPlayer( PlayerSlot
);
4373 if (PlayerSlot
>= 0) {
4374 return RuntimeError("Slot is already filled!");
4378 PlayerSlot
= gamedata
->LoadCreature( CreResRef
, Slot
, (bool) Import
);
4380 //just destroyed the previous actor, not going to create one
4383 if (PlayerSlot
< 0) {
4384 return RuntimeError("File not found!");
4386 return PyInt_FromLong( PlayerSlot
);
4389 PyDoc_STRVAR( GemRB_GetPlayerStates__doc
,
4390 "GetPlayerStates(PartyID) => string\n\n"
4391 "Returns the state string for the player.");
4393 static PyObject
* GemRB_GetPlayerStates(PyObject
* /*self*/, PyObject
* args
)
4397 if (!PyArg_ParseTuple( args
, "i", &PartyID
)) {
4398 return AttributeError( GemRB_GetPlayerStates__doc
);
4400 Game
*game
= core
->GetGame();
4402 return RuntimeError( "No game loaded!" );
4404 Actor
* MyActor
= game
->FindPC( PartyID
);
4406 return RuntimeError( "Actor not found" );
4408 return PyString_FromString((const char *) MyActor
->GetStateString() );
4411 PyDoc_STRVAR( GemRB_GetPlayerName__doc
,
4412 "GetPlayerName(PartyID[, LongOrShort]) => string\n\n"
4413 "Queries the player name." );
4415 static PyObject
* GemRB_GetPlayerName(PyObject
* /*self*/, PyObject
* args
)
4420 if (!PyArg_ParseTuple( args
, "i|i", &PartyID
, &Which
)) {
4421 return AttributeError( GemRB_GetPlayerName__doc
);
4423 Game
*game
= core
->GetGame();
4425 return RuntimeError( "No game loaded!" );
4427 Actor
* MyActor
= game
->FindPC( PartyID
);
4429 return RuntimeError( "Actor not found" );
4431 return PyString_FromString( MyActor
->GetName(Which
) );
4434 PyDoc_STRVAR( GemRB_SetPlayerName__doc
,
4435 "SetPlayerName(Slot, Name[, LongOrShort])\n\n"
4436 "Sets the player name." );
4438 static PyObject
* GemRB_SetPlayerName(PyObject
* /*self*/, PyObject
* args
)
4440 const char *Name
=NULL
;
4441 int PlayerSlot
, Which
;
4444 if (!PyArg_ParseTuple( args
, "is|i", &PlayerSlot
, &Name
, &Which
)) {
4445 return AttributeError( GemRB_SetPlayerName__doc
);
4447 Game
*game
= core
->GetGame();
4449 return RuntimeError( "No game loaded!" );
4451 Actor
* MyActor
= game
->FindPC( PlayerSlot
);
4453 return RuntimeError( "Actor not found!" );
4455 MyActor
->SetName(Name
, Which
);
4456 MyActor
->SetMCFlag(MC_EXPORTABLE
,BM_OR
);
4457 Py_INCREF( Py_None
);
4461 PyDoc_STRVAR( GemRB_CreateString__doc
,
4462 "CreateString( Text )->StrRef\n\n"
4463 "Creates a custom string." );
4465 static PyObject
* GemRB_CreateString(PyObject
* /*self*/, PyObject
* args
)
4470 if (!PyArg_ParseTuple( args
, "is", &strref
, &Text
)) {
4471 return AttributeError( GemRB_CreateString__doc
);
4473 Game
*game
= core
->GetGame();
4475 return RuntimeError( "No game loaded!" );
4478 strref
= core
->UpdateString(strref
, Text
);
4479 return PyInt_FromLong( strref
);
4482 PyDoc_STRVAR( GemRB_SetPlayerString__doc
,
4483 "SetPlayerString(PlayerSlot, StringSlot, StrRef)\n\n"
4484 "Sets one of the player character's verbal constants. Mostly useful for setting biography." );
4486 static PyObject
* GemRB_SetPlayerString(PyObject
* /*self*/, PyObject
* args
)
4488 int PlayerSlot
, StringSlot
, StrRef
;
4490 if (!PyArg_ParseTuple( args
, "iii", &PlayerSlot
, &StringSlot
, &StrRef
)) {
4491 return AttributeError( GemRB_SetPlayerString__doc
);
4493 Game
*game
= core
->GetGame();
4495 return RuntimeError( "No game loaded!" );
4497 Actor
* MyActor
= game
->FindPC( PlayerSlot
);
4499 return RuntimeError( "Actor not found!" );
4502 if (StringSlot
>=VCONST_COUNT
) {
4503 return AttributeError( "StringSlot is out of range!" );
4506 MyActor
->StrRefs
[StringSlot
]=StrRef
;
4508 Py_INCREF( Py_None
);
4512 PyDoc_STRVAR( GemRB_SetPlayerSound__doc
,
4513 "SetPlayerSound(Slot, SoundFolder)\n\n"
4514 "Sets the player character's sound set." );
4516 static PyObject
* GemRB_SetPlayerSound(PyObject
* /*self*/, PyObject
* args
)
4518 const char *Sound
=NULL
;
4521 if (!PyArg_ParseTuple( args
, "is", &PlayerSlot
, &Sound
)) {
4522 return AttributeError( GemRB_SetPlayerSound__doc
);
4524 Game
*game
= core
->GetGame();
4526 return RuntimeError( "No game loaded!" );
4528 Actor
* MyActor
= game
->FindPC( PlayerSlot
);
4530 return RuntimeError( "Actor not found!" );
4532 MyActor
->SetSoundFolder(Sound
);
4533 Py_INCREF( Py_None
);
4537 PyDoc_STRVAR( GemRB_GetSlotType__doc
,
4538 "GetSlotType(idx[, PartyID]) => dict\n\n"
4539 "Returns dictionary of an itemslot type (slottype.2da).");
4541 static PyObject
* GemRB_GetSlotType(PyObject
* /*self*/, PyObject
* args
)
4545 Actor
*actor
= NULL
;
4547 if (!PyArg_ParseTuple( args
, "i|i", &idx
, &PartyID
)) {
4548 return AttributeError( GemRB_GetSlotType__doc
);
4552 Game
*game
= core
->GetGame();
4554 return RuntimeError( "No game loaded!" );
4556 actor
= game
->FindPC( PartyID
);
4559 PyObject
* dict
= PyDict_New();
4561 PyDict_SetItemString(dict
, "Count", PyInt_FromLong(core
->GetInventorySize()));
4564 int tmp
= core
->QuerySlot(idx
);
4565 if (core
->QuerySlotEffects(idx
)==0xffffffffu
) {
4569 PyDict_SetItemString(dict
, "Slot", PyInt_FromLong(tmp
));
4570 PyDict_SetItemString(dict
, "Type", PyInt_FromLong((int)core
->QuerySlotType(tmp
)));
4571 PyDict_SetItemString(dict
, "ID", PyInt_FromLong((int)core
->QuerySlotID(tmp
)));
4572 PyDict_SetItemString(dict
, "Tip", PyInt_FromLong((int)core
->QuerySlottip(tmp
)));
4573 //see if the actor shouldn't have some slots displayed
4574 if (!actor
|| !actor
->PCStats
) {
4577 //WARNING:idx isn't used any more, recycling it
4578 idx
= actor
->inventory
.GetWeaponSlot();
4579 if (tmp
<idx
|| tmp
>idx
+3) {
4582 if (actor
->GetQuickSlot(tmp
-idx
)==0xffff) {
4583 PyDict_SetItemString(dict
, "ResRef", PyString_FromString (""));
4584 goto continue_quest
;
4587 PyDict_SetItemString(dict
, "ResRef", PyString_FromString (core
->QuerySlotResRef(tmp
)));
4589 PyDict_SetItemString(dict
, "Effects", PyInt_FromLong (core
->QuerySlotEffects(tmp
)));
4593 PyDoc_STRVAR( GemRB_GetPCStats__doc
,
4594 "GetPCStats(PartyID) => dict\n\n"
4595 "Returns dictionary of PC's performance stats." );
4597 static PyObject
* GemRB_GetPCStats(PyObject
* /*self*/, PyObject
* args
)
4601 if (!PyArg_ParseTuple( args
, "i", &PartyID
)) {
4602 return AttributeError( GemRB_GetPCStats__doc
);
4604 Game
*game
= core
->GetGame();
4606 return RuntimeError( "No game loaded!" );
4608 Actor
* MyActor
= game
->FindPC( PartyID
);
4609 if (!MyActor
|| !MyActor
->PCStats
) {
4610 Py_INCREF( Py_None
);
4614 PyObject
* dict
= PyDict_New();
4615 PCStatsStruct
* ps
= MyActor
->PCStats
;
4617 PyDict_SetItemString(dict
, "BestKilledName", PyInt_FromLong ((signed) ps
->BestKilledName
));
4618 PyDict_SetItemString(dict
, "BestKilledXP", PyInt_FromLong (ps
->BestKilledXP
));
4619 PyDict_SetItemString(dict
, "AwayTime", PyInt_FromLong (ps
->AwayTime
));
4620 PyDict_SetItemString(dict
, "JoinDate", PyInt_FromLong (ps
->JoinDate
));
4621 PyDict_SetItemString(dict
, "KillsChapterXP", PyInt_FromLong (ps
->KillsChapterXP
));
4622 PyDict_SetItemString(dict
, "KillsChapterCount", PyInt_FromLong (ps
->KillsChapterCount
));
4623 PyDict_SetItemString(dict
, "KillsTotalXP", PyInt_FromLong (ps
->KillsTotalXP
));
4624 PyDict_SetItemString(dict
, "KillsTotalCount", PyInt_FromLong (ps
->KillsTotalCount
));
4627 if (ps
->FavouriteSpells
[0][0]) {
4630 for (int i
= 1; i
< 4; ++i
) {
4631 if (ps
->FavouriteSpellsCount
[i
] > ps
->FavouriteSpellsCount
[largest
]) {
4636 Spell
* spell
= gamedata
->GetSpell(ps
->FavouriteSpells
[largest
]);
4637 if (spell
== NULL
) {
4641 PyDict_SetItemString(dict
, "FavouriteSpell", PyInt_FromLong ((signed) spell
->SpellName
));
4643 gamedata
->FreeSpell( spell
, ps
->FavouriteSpells
[largest
], false );
4645 PyDict_SetItemString(dict
, "FavouriteSpell", PyString_FromString (""));
4651 if (ps
->FavouriteWeapons
[0][0]) {
4654 for (int i
= 1; i
< 4; ++i
) {
4655 if (ps
->FavouriteWeaponsCount
[i
] > ps
->FavouriteWeaponsCount
[largest
]) {
4660 Item
* item
= gamedata
->GetItem(ps
->FavouriteWeapons
[largest
]);
4662 return RuntimeError( "Item not found!" );
4665 PyDict_SetItemString(dict
, "FavouriteWeapon", PyInt_FromLong ((signed) item
->GetItemName(false)));
4667 gamedata
->FreeItem( item
, ps
->FavouriteWeapons
[largest
], false );
4669 PyDict_SetItemString(dict
, "FavouriteWeapon", PyString_FromString (""));
4676 PyDoc_STRVAR( GemRB_GameSelectPC__doc
,
4677 "GameSelectPC(PartyID, Selected, [Flags = SELECT_NORMAL])\n\n"
4678 "Selects or deselects PC."
4679 "if PartyID=0, (De)selects all PC."
4680 "Flags is combination of SELECT_REPLACE and SELECT_QUIET."
4681 "SELECT_REPLACE: when selecting other party members, unselect the others." );
4683 static PyObject
* GemRB_GameSelectPC(PyObject
* /*self*/, PyObject
* args
)
4685 int PartyID
, Select
;
4686 int Flags
= SELECT_NORMAL
;
4688 if (!PyArg_ParseTuple( args
, "ii|i", &PartyID
, &Select
, &Flags
)) {
4689 return AttributeError( GemRB_GameSelectPC__doc
);
4691 Game
*game
= core
->GetGame();
4693 return RuntimeError( "No game loaded!" );
4698 actor
= game
->FindPC( PartyID
);
4700 Py_INCREF( Py_None
);
4707 game
->SelectActor( actor
, (bool) Select
, Flags
);
4709 Py_INCREF( Py_None
);
4713 PyDoc_STRVAR( GemRB_GameIsPCSelected__doc
,
4714 "GameIsPCSelected(Slot) => bool\n\n"
4715 "Returns true if the PC is selected." );
4717 static PyObject
* GemRB_GameIsPCSelected(PyObject
* /*self*/, PyObject
* args
)
4721 if (!PyArg_ParseTuple( args
, "i", &PlayerSlot
)) {
4722 return AttributeError( GemRB_GameIsPCSelected__doc
);
4724 Game
*game
= core
->GetGame();
4726 return RuntimeError( "No game loaded!" );
4728 Actor
* MyActor
= game
->FindPC( PlayerSlot
);
4730 return PyInt_FromLong( 0 );
4732 return PyInt_FromLong( MyActor
->IsSelected() );
4736 PyDoc_STRVAR( GemRB_GameSelectPCSingle__doc
,
4737 "GameSelectPCSingle(index)\n\n"
4738 "Selects one PC in non-walk environment (i.e. in shops, inventory,...)"
4739 "Index must be greater than zero." );
4741 static PyObject
* GemRB_GameSelectPCSingle(PyObject
* /*self*/, PyObject
* args
)
4745 if (!PyArg_ParseTuple( args
, "i", &index
)) {
4746 return AttributeError( GemRB_GameSelectPCSingle__doc
);
4749 core
->GetGame()->SelectPCSingle( index
);
4751 Py_INCREF( Py_None
);
4755 PyDoc_STRVAR( GemRB_GameGetSelectedPCSingle__doc
,
4756 "GameGetSelectedPCSingle(flag) => int\n\n"
4757 "Returns index of the selected PC in non-walk environment (i.e. in shops, inventory,...). Index should be greater than zero. If flag is set, then this function will return the PC currently talking." );
4759 static PyObject
* GemRB_GameGetSelectedPCSingle(PyObject
* /*self*/, PyObject
* args
)
4763 if (!PyArg_ParseTuple( args
, "|i", &flag
)) {
4764 return AttributeError( GemRB_GameGetSelectedPCSingle__doc
);
4766 Game
*game
= core
->GetGame();
4768 return RuntimeError( "No game loaded!" );
4771 GameControl
*gc
= core
->GetGameControl();
4773 return RuntimeError("Can't find GameControl!");
4775 Actor
*ac
= gc
->GetSpeaker();
4780 return PyInt_FromLong( ret
);
4782 return PyInt_FromLong( game
->GetSelectedPCSingle() );
4785 PyDoc_STRVAR( GemRB_GameGetFirstSelectedPC__doc
,
4786 "GameGetFirstSelectedPC() => int\n\n"
4787 "Returns index of the first selected PC or 0 if none." );
4789 static PyObject
* GemRB_GameGetFirstSelectedPC(PyObject
* /*self*/, PyObject
* /*args*/)
4791 Actor
*actor
= core
->GetFirstSelectedPC(false);
4793 return PyInt_FromLong( actor
->InParty
);
4796 return PyInt_FromLong( 0 );
4799 PyDoc_STRVAR( GemRB_ActOnPC__doc
,
4800 "ActOnPC(player)\n\n"
4801 "Targets the selected PC for an action (cast spell, attack, ...)" );
4803 static PyObject
* GemRB_ActOnPC(PyObject
* /*self*/, PyObject
* args
)
4807 if (!PyArg_ParseTuple( args
, "i", &PartyID
)) {
4808 return AttributeError( GemRB_ActOnPC__doc
);
4810 Game
*game
= core
->GetGame();
4812 return RuntimeError( "No game loaded!" );
4814 Actor
* MyActor
= game
->FindPC( PartyID
);
4816 GameControl
* gc
= core
->GetGameControl();
4818 gc
->PerformActionOn(MyActor
);
4821 Py_INCREF(Py_None
) ;
4825 PyDoc_STRVAR( GemRB_GetPlayerPortrait__doc
,
4826 "GetPlayerPortrait(Slot[, SmallOrLarge]) => string\n\n"
4827 "Queries the player portrait." );
4829 static PyObject
* GemRB_GetPlayerPortrait(PyObject
* /*self*/, PyObject
* args
)
4831 int PlayerSlot
, Which
;
4834 if (!PyArg_ParseTuple( args
, "i|i", &PlayerSlot
, &Which
)) {
4835 return AttributeError( GemRB_GetPlayerPortrait__doc
);
4837 Game
*game
= core
->GetGame();
4839 return RuntimeError( "No game loaded!" );
4841 Actor
* MyActor
= game
->FindPC( PlayerSlot
);
4843 return PyString_FromString( "");
4845 return PyString_FromString( MyActor
->GetPortrait(Which
) );
4848 PyDoc_STRVAR( GemRB_GetPlayerString__doc
,
4849 "GetPlayerString(Slot, ID) => int\n\n"
4850 "Queries a string reference (verbal constant) from the actor." );
4852 static PyObject
* GemRB_GetPlayerString(PyObject
* /*self*/, PyObject
* args
)
4854 int PlayerSlot
, Index
, StatValue
;
4856 if (!PyArg_ParseTuple( args
, "ii", &PlayerSlot
, &Index
)) {
4857 return AttributeError( GemRB_GetPlayerString__doc
);
4859 Actor
* MyActor
= core
->GetGame()->FindPC( PlayerSlot
);
4861 return RuntimeError("Cannot find actor!\n");
4863 if (Index
>=VCONST_COUNT
) {
4864 return RuntimeError("String reference too high!\n");
4866 StatValue
= GetCreatureStrRef( MyActor
, Index
);
4867 return PyInt_FromLong( StatValue
);
4870 PyDoc_STRVAR( GemRB_GetPlayerStat__doc
,
4871 "GetPlayerStat(Slot, ID[, BaseStat]) => int\n\n"
4872 "Queries a stat." );
4874 static PyObject
* GemRB_GetPlayerStat(PyObject
* /*self*/, PyObject
* args
)
4876 int PlayerSlot
, StatID
, StatValue
, BaseStat
;
4879 if (!PyArg_ParseTuple( args
, "ii|i", &PlayerSlot
, &StatID
, &BaseStat
)) {
4880 return AttributeError( GemRB_GetPlayerStat__doc
);
4882 Actor
* MyActor
= core
->GetGame()->FindPC( PlayerSlot
);
4884 return RuntimeError("Cannot find actor!\n");
4886 //returning the modified stat if BaseStat was 0 (default)
4887 StatValue
= GetCreatureStat( MyActor
, StatID
, !BaseStat
);
4888 return PyInt_FromLong( StatValue
);
4891 PyDoc_STRVAR( GemRB_SetPlayerStat__doc
,
4892 "SetPlayerStat(Slot, ID, Value)\n\n"
4893 "Changes a stat." );
4895 static PyObject
* GemRB_SetPlayerStat(PyObject
* /*self*/, PyObject
* args
)
4897 int PlayerSlot
, StatID
, StatValue
;
4899 if (!PyArg_ParseTuple( args
, "iii", &PlayerSlot
, &StatID
, &StatValue
)) {
4900 return AttributeError( GemRB_SetPlayerStat__doc
);
4902 Actor
* MyActor
= core
->GetGame()->FindPC( PlayerSlot
);
4904 return RuntimeError("Cannot find actor!\n");
4906 //Setting the creature's base stat
4907 SetCreatureStat( MyActor
, StatID
, StatValue
);
4908 Py_INCREF( Py_None
);
4912 PyDoc_STRVAR( GemRB_GetPlayerScript__doc
,
4913 "GetPlayerScript(Slot[, Index])\n\n"
4914 "Retrieves the script resource for a player. If index is omitted, it will default to "
4915 "the class script slot (customisable by players)." );
4917 static PyObject
* GemRB_GetPlayerScript(PyObject
* /*self*/, PyObject
* args
)
4919 //class script is the custom slot for player scripts
4920 int PlayerSlot
, Index
= SCR_CLASS
;
4922 if (!PyArg_ParseTuple( args
, "i|i", &PlayerSlot
, &Index
)) {
4923 return AttributeError( GemRB_GetPlayerScript__doc
);
4925 Actor
*actor
= core
->GetGame()->FindPC(PlayerSlot
);
4927 return RuntimeError("Cannot find actor!\n");
4929 const char *scr
= actor
->GetScript(Index
);
4933 return PyString_FromString( scr
);
4936 PyDoc_STRVAR( GemRB_SetPlayerScript__doc
,
4937 "SetPlayerScript(Slot, Resource[, Index])\n\n"
4938 "Sets the script resource for a player. If index is omitted, it will default to "
4939 "the class script slot (customisable by players)." );
4941 static PyObject
* GemRB_SetPlayerScript(PyObject
* /*self*/, PyObject
* args
)
4943 const char *ScriptName
;
4944 int PlayerSlot
, Index
= SCR_CLASS
;
4946 if (!PyArg_ParseTuple( args
, "is|i", &PlayerSlot
, &ScriptName
, &Index
)) {
4947 return AttributeError( GemRB_SetPlayerScript__doc
);
4949 Actor
*actor
= core
->GetGame()->FindPC(PlayerSlot
);
4951 return RuntimeError("Cannot find actor!\n");
4953 actor
->SetScript(ScriptName
, Index
, true);
4954 Py_INCREF( Py_None
);
4958 PyDoc_STRVAR( GemRB_FillPlayerInfo__doc
,
4959 "FillPlayerInfo(Slot[, Portrait1, Portrait2])\n\n"
4960 "Fills basic character info, that is not stored in stats." );
4962 static PyObject
* GemRB_FillPlayerInfo(PyObject
* /*self*/, PyObject
* args
)
4965 const char *Portrait1
=NULL
, *Portrait2
=NULL
;
4967 if (!PyArg_ParseTuple( args
, "i|ss", &PlayerSlot
, &Portrait1
, &Portrait2
)) {
4968 return AttributeError( GemRB_FillPlayerInfo__doc
);
4970 // here comes some code to transfer icon/name to the PC sheet
4973 Game
*game
= core
->GetGame();
4975 return RuntimeError( "No game loaded!" );
4978 Actor
* MyActor
= game
->FindPC( PlayerSlot
);
4980 return RuntimeError( "Actor not found!" );
4983 MyActor
->SetPortrait( Portrait1
, 1);
4986 MyActor
->SetPortrait( Portrait2
, 2);
4988 int mastertable
= gamedata
->LoadTable( "avprefix" );
4989 Holder
<TableMgr
> mtm
= gamedata
->GetTable( mastertable
);
4990 int count
= mtm
->GetRowCount();
4991 if (count
< 1 || count
>8) {
4992 return RuntimeError("Table is invalid." );
4994 const char *poi
= mtm
->QueryField( 0 );
4995 int AnimID
= strtoul( poi
, NULL
, 0 );
4996 for (int i
= 1; i
< count
; i
++) {
4997 poi
= mtm
->QueryField( i
);
4998 int table
= gamedata
->LoadTable( poi
);
4999 Holder
<TableMgr
> tm
= gamedata
->GetTable( table
);
5000 int StatID
= atoi( tm
->QueryField() );
5001 StatID
= MyActor
->GetBase( StatID
);
5002 poi
= tm
->QueryField( StatID
);
5003 AnimID
+= strtoul( poi
, NULL
, 0 );
5004 gamedata
->DelTable( table
);
5006 MyActor
->SetBase(IE_ANIMATION_ID
, AnimID
);
5007 //setting PST's starting stance to 18
5008 poi
= mtm
->QueryField( 0, 1 );
5010 MyActor
->SetStance( atoi( poi
) );
5012 gamedata
->DelTable( mastertable
);
5013 MyActor
->SetOver( false );
5014 MyActor
->InitButtons(MyActor
->GetStat(IE_CLASS
), true); //force re-init of actor's buttons
5015 Py_INCREF( Py_None
);
5019 PyDoc_STRVAR( GemRB_Button_SetSpellIcon__doc
,
5020 "SetSpellIcon(WindowIndex, ControlIndex, SPLResRef[, type, tooltip, function])\n\n"
5021 "Sets Spell icon image on a button. Type is the icon's type." );
5023 PyObject
*SetSpellIcon(int wi
, int ci
, const ieResRef SpellResRef
, int type
, int tooltip
, int Function
)
5025 Button
* btn
= (Button
*) GetControl( wi
, ci
, IE_GUI_BUTTON
);
5030 if (!SpellResRef
[0]) {
5031 btn
->SetPicture( NULL
);
5036 Spell
* spell
= gamedata
->GetSpell( SpellResRef
, 1 );
5037 if (spell
== NULL
) {
5038 btn
->SetPicture( NULL
);
5039 printMessage( "GUIScript", " ", LIGHT_RED
);
5040 printf("Spell not found :%.8s", SpellResRef
);
5045 const char* IconResRef
;
5047 IconResRef
= spell
->ext_headers
[0].MemorisedIcon
;
5050 IconResRef
= spell
->SpellbookIcon
;
5052 AnimationFactory
* af
= ( AnimationFactory
* )
5053 gamedata
->GetFactoryResource( IconResRef
,
5054 IE_BAM_CLASS_ID
, IE_NORMAL
, 1 );
5056 printf("Searched for: %s\n", IconResRef
);
5057 return RuntimeError( "BAM not found" );
5059 //small difference between pst and others
5060 if (af
->GetCycleSize(0)!=4) { //non-pst
5061 btn
->SetPicture( af
->GetFrame(0, 0));
5064 btn
->SetImage( IE_GUI_BUTTON_UNPRESSED
, af
->GetFrame(0, 0));
5065 btn
->SetImage( IE_GUI_BUTTON_PRESSED
, af
->GetFrame(1, 0));
5066 btn
->SetImage( IE_GUI_BUTTON_SELECTED
, af
->GetFrame(2, 0));
5067 btn
->SetImage( IE_GUI_BUTTON_DISABLED
, af
->GetFrame(3, 0));
5070 char *str
= core
->GetString(spell
->SpellName
,0);
5071 SetFunctionTooltip(wi
, ci
, str
, Function
); //will free str
5073 gamedata
->FreeSpell( spell
, SpellResRef
, false );
5078 static PyObject
* GemRB_Button_SetSpellIcon(PyObject
* /*self*/, PyObject
* args
)
5081 const char *SpellResRef
;
5086 if (!PyArg_ParseTuple( args
, "iis|iii", &wi
, &ci
, &SpellResRef
, &type
, &tooltip
, &Function
)) {
5087 return AttributeError( GemRB_Button_SetSpellIcon__doc
);
5089 PyObject
*ret
= SetSpellIcon(wi
, ci
, SpellResRef
, type
, tooltip
, Function
);
5097 static Sprite2D
* GetUsedWeaponIcon(Item
*item
, int which
)
5099 ITMExtHeader
*ieh
= item
->GetWeaponHeader(false);
5101 ieh
= item
->GetWeaponHeader(true);
5104 return gamedata
->GetBAMSprite(ieh
->UseIcon
, -1, which
);
5106 return gamedata
->GetBAMSprite(item
->ItemIcon
, -1, which
);
5109 static void SetItemText(int wi
, int ci
, int charges
, bool oneisnone
)
5111 Button
* btn
= (Button
*) GetControl( wi
, ci
, IE_GUI_BUTTON
);
5117 if (charges
&& (charges
>1 || !oneisnone
) ) {
5118 sprintf(tmp
,"%d",charges
);
5125 PyDoc_STRVAR( GemRB_Button_SetItemIcon__doc
,
5126 "SetItemIcon(WindowIndex, ControlIndex, ITMResRef[, type, tooltip, Function, ITM2ResRef])\n\n"
5127 "Sets Item icon image on a button. 0/1 - Inventory Icons, 2 - Description Icon, 3 - No icon,\n"
5128 " 4/5 - Weapon icons, 6 and above - Extended header icons." );
5130 PyObject
*SetItemIcon(int wi
, int ci
, const char *ItemResRef
, int Which
, int tooltip
, int Function
, const char *Item2ResRef
)
5132 Button
* btn
= (Button
*) GetControl( wi
, ci
, IE_GUI_BUTTON
);
5137 if (!ItemResRef
[0]) {
5138 btn
->SetPicture( NULL
);
5142 Item
* item
= gamedata
->GetItem(ItemResRef
);
5144 btn
->SetPicture(NULL
);
5149 btn
->SetFlags( IE_GUI_BUTTON_PICTURE
, BM_OR
);
5151 bool setpicture
= true;
5155 Picture
= gamedata
->GetBAMSprite(item
->ItemIcon
, -1, Which
);
5158 btn
->SetPicture( NULL
); // also calls ClearPictureList
5160 Picture
= gamedata
->GetBAMSprite(item
->DescriptionIcon
, -1, i
);
5162 btn
->StackPicture(Picture
);
5170 Picture
= GetUsedWeaponIcon(item
, Which
-4);
5172 btn
->SetPicture( NULL
); // also calls ClearPictureList
5173 Item
* item2
= gamedata
->GetItem(Item2ResRef
);
5176 Picture2
= gamedata
->GetBAMSprite(item2
->ItemIcon
, -1, Which
-4);
5177 if (Picture2
) btn
->StackPicture(Picture2
);
5178 gamedata
->FreeItem( item2
, Item2ResRef
, false );
5180 if (Picture
) btn
->StackPicture(Picture
);
5185 ITMExtHeader
*eh
= item
->GetExtHeader(Which
-6);
5187 Picture
= gamedata
->GetBAMSprite(eh
->UseIcon
, -1, 0);
5195 btn
->SetPicture( Picture
);
5197 //later getitemname could also return tooltip stuff
5198 char *str
= core
->GetString(item
->GetItemName(tooltip
==2),0);
5199 //this will free str, no need of freeing it
5200 SetFunctionTooltip(wi
, ci
, str
, Function
);
5203 gamedata
->FreeItem( item
, ItemResRef
, false );
5208 static PyObject
* GemRB_Button_SetItemIcon(PyObject
* /*self*/, PyObject
* args
)
5211 const char *ItemResRef
;
5215 const char *Item2ResRef
= NULL
;
5217 if (!PyArg_ParseTuple( args
, "iis|iiis", &wi
, &ci
, &ItemResRef
, &Which
, &tooltip
, &Function
, &Item2ResRef
)) {
5218 return AttributeError( GemRB_Button_SetItemIcon__doc
);
5221 PyObject
*ret
= SetItemIcon(wi
, ci
, ItemResRef
, Which
, tooltip
, Function
, Item2ResRef
);
5228 PyDoc_STRVAR( GemRB_EnterStore__doc
,
5229 "EnterStore(STOResRef)\n\n"
5230 "Loads the store referenced and opens the store window." );
5232 static PyObject
* GemRB_EnterStore(PyObject
* /*self*/, PyObject
* args
)
5234 const char* StoreResRef
;
5236 if (!PyArg_ParseTuple( args
, "s", &StoreResRef
)) {
5237 return AttributeError( GemRB_EnterStore__doc
);
5240 //stores are cached, bags could be opened while in shops
5241 //so better just switch to the requested store silently
5242 //the core will be intelligent enough to not do excess work
5243 core
->SetCurrentStore( StoreResRef
, NULL
);
5245 //the error flag is not optional, we should open a store now
5246 //core->GetGUIScriptEngine()->RunFunction( "OpenStoreWindow", true);
5247 core
->SetEventFlag(EF_OPENSTORE
);
5248 Py_INCREF( Py_None
);
5252 PyDoc_STRVAR( GemRB_LeaveStore__doc
,
5253 "LeaveStore(STOResRef)\n\n"
5254 "Saves the current store to the Cache folder and frees it from memory." );
5256 static PyObject
* GemRB_LeaveStore(PyObject
* /*self*/, PyObject
* /*args*/)
5258 if (core
->CloseCurrentStore() ) {
5259 return RuntimeError("Cannot save store!");
5261 Py_INCREF( Py_None
);
5265 PyDoc_STRVAR( GemRB_LeaveContainer__doc
,
5266 "LeaveContainer()\n\n"
5267 "Clears the current container variable and initiates the 'CloseContainerWindow' guiscript call in the next window update cycle.");
5269 static PyObject
* GemRB_LeaveContainer(PyObject
* /*self*/, PyObject
* /*args*/)
5271 core
->CloseCurrentContainer();
5272 Py_INCREF( Py_None
);
5276 PyDoc_STRVAR( GemRB_GetContainer__doc
,
5277 "GetContainer( PartyID, autoselect ) => dictionary\n\n"
5278 "Returns relevant data of the container used by the selected actor. Use autoselect if the container is an item pile at the feet of the actor. It will create the container if required." );
5280 static PyObject
* GemRB_GetContainer(PyObject
* /*self*/, PyObject
* args
)
5285 if (!PyArg_ParseTuple( args
, "i|i", &PartyID
, &autoselect
)) {
5286 return AttributeError( GemRB_GetContainer__doc
);
5291 Game
*game
= core
->GetGame();
5293 return RuntimeError( "No game loaded!" );
5296 actor
= game
->FindPC( PartyID
);
5298 actor
= core
->GetFirstSelectedPC(false);
5301 return RuntimeError( "Actor not found" );
5303 Container
*container
= NULL
;
5304 if (autoselect
) { //autoselect works only with piles
5305 Map
*map
= actor
->GetCurrentArea();
5306 //GetContainer should create an empty container
5307 container
= map
->GetPile(actor
->Pos
);
5309 container
= core
->GetCurrentContainer();
5312 return RuntimeError("No current container!");
5315 PyObject
* dict
= PyDict_New();
5316 PyDict_SetItemString(dict
, "Type", PyInt_FromLong( container
->Type
));
5317 PyDict_SetItemString(dict
, "ItemCount", PyInt_FromLong( container
->inventory
.GetSlotCount() ));
5322 PyDoc_STRVAR( GemRB_GetContainerItem__doc
,
5323 "GetContainerItem(PartyID, idx) => dictionary\n\n"
5324 "Returns the container item referenced by the index. If PartyID is 0 then the container was opened manually and should be the current container. If PartyID is not 0 then the container is autoselected and should be at the feet of the player." );
5326 static PyObject
* GemRB_GetContainerItem(PyObject
* /*self*/, PyObject
* args
)
5331 if (!PyArg_ParseTuple( args
, "ii", &PartyID
, &index
)) {
5332 return AttributeError( GemRB_GetContainerItem__doc
);
5334 Container
*container
;
5337 Game
*game
= core
->GetGame();
5339 return RuntimeError( "No game loaded!" );
5341 Actor
*actor
= game
->FindPC( PartyID
);
5343 return RuntimeError( "Actor not found" );
5345 Map
*map
= actor
->GetCurrentArea();
5346 container
= map
->TMap
->GetContainer(actor
->Pos
, IE_CONTAINER_PILE
);
5348 container
= core
->GetCurrentContainer();
5351 return RuntimeError("No current container!");
5353 if (index
>=(int) container
->inventory
.GetSlotCount()) {
5354 Py_INCREF( Py_None
);
5357 PyObject
* dict
= PyDict_New();
5359 CREItem
*ci
=container
->inventory
.GetSlotItem( index
);
5361 PyDict_SetItemString(dict
, "ItemResRef", PyString_FromResRef( ci
->ItemResRef
));
5362 PyDict_SetItemString(dict
, "Usages0", PyInt_FromLong (ci
->Usages
[0]));
5363 PyDict_SetItemString(dict
, "Usages1", PyInt_FromLong (ci
->Usages
[1]));
5364 PyDict_SetItemString(dict
, "Usages2", PyInt_FromLong (ci
->Usages
[2]));
5365 PyDict_SetItemString(dict
, "Flags", PyInt_FromLong (ci
->Flags
));
5367 Item
*item
= gamedata
->GetItem( ci
->ItemResRef
);
5369 bool identified
= ci
->Flags
& IE_INV_ITEM_IDENTIFIED
;
5370 PyDict_SetItemString(dict
, "ItemName", PyInt_FromLong( (signed) item
->GetItemName( identified
)) );
5371 PyDict_SetItemString(dict
, "ItemDesc", PyInt_FromLong( (signed) item
->GetItemDesc( identified
)) );
5372 gamedata
->FreeItem( item
, ci
->ItemResRef
, false );
5376 PyDoc_STRVAR( GemRB_ChangeContainerItem__doc
,
5377 "ChangeContainerItem(PartyID, slot, action)\n\n"
5378 "Takes an item from a container, or puts it there. "
5379 "If PC is 0 then it uses the first selected PC and the current container, "
5380 "if it is not 0 then it autoselects the container. "
5381 "action=0: move item from PC to container."
5382 "action=1: move item from container to PC.");
5384 static PyObject
* GemRB_ChangeContainerItem(PyObject
* /*self*/, PyObject
* args
)
5389 if (!PyArg_ParseTuple( args
, "iii", &PartyID
, &Slot
, &action
)) {
5390 return AttributeError( GemRB_ChangeContainerItem__doc
);
5392 Game
*game
= core
->GetGame();
5394 return RuntimeError( "No game loaded!" );
5397 Container
*container
;
5399 actor
= game
->FindPC( PartyID
);
5401 return RuntimeError( "Actor not found" );
5403 Map
*map
= actor
->GetCurrentArea();
5404 container
= map
->TMap
->GetContainer(actor
->Pos
, IE_CONTAINER_PILE
);
5406 actor
= core
->GetFirstSelectedPC(false);
5408 return RuntimeError( "Actor not found" );
5410 container
= core
->GetCurrentContainer();
5413 return RuntimeError("No current container!");
5421 if (action
) { //get stuff from container
5422 if (Slot
<0 || Slot
>=(int) container
->inventory
.GetSlotCount()) {
5423 return RuntimeError("Invalid Container slot!");
5426 res
= core
->CanMoveItem(container
->inventory
.GetSlotItem(Slot
) );
5427 if (!res
) { //cannot move
5428 printMessage("GUIScript","Cannot move item, it is undroppable!\n", GREEN
);
5429 Py_INCREF( Py_None
);
5433 //this will update the container
5434 si
= container
->RemoveItem(Slot
,0);
5436 printMessage("GUIScript","Cannot move item, there is something weird!\n", YELLOW
);
5437 Py_INCREF( Py_None
);
5440 Item
*item
= gamedata
->GetItem(si
->ItemResRef
);
5442 if (core
->HasFeature(GF_HAS_PICK_SOUND
) && item
->ReplacementItem
[0]) {
5443 memcpy(Sound
,item
->ReplacementItem
,sizeof(ieResRef
));
5445 GetItemSound(Sound
, item
->ItemType
, item
->AnimationType
, IS_DROP
);
5447 gamedata
->FreeItem(item
, si
->ItemResRef
,0);
5449 if (res
!=-1) { //it is gold!
5450 game
->PartyGold
+= res
;
5453 res
= actor
->inventory
.AddSlotItem(si
, SLOT_ONLYINVENTORY
);
5454 if (res
!=ASI_SUCCESS
) { //putting it back
5455 container
->AddItem(si
);
5458 } else { //put stuff in container, simple!
5459 res
= core
->CanMoveItem(actor
->inventory
.GetSlotItem(core
->QuerySlot(Slot
) ) );
5460 if (!res
) { //cannot move
5461 printMessage("GUIScript","Cannot move item, it is undroppable!\n", GREEN
);
5462 Py_INCREF( Py_None
);
5466 si
= actor
->inventory
.RemoveItem(core
->QuerySlot(Slot
));
5468 printMessage("GUIScript","Cannot move item, there is something weird!\n", YELLOW
);
5469 Py_INCREF( Py_None
);
5472 Item
*item
= gamedata
->GetItem(si
->ItemResRef
);
5474 if (core
->HasFeature(GF_HAS_PICK_SOUND
) && item
->DescriptionIcon
[0]) {
5475 memcpy(Sound
,item
->DescriptionIcon
,sizeof(ieResRef
));
5477 GetItemSound(Sound
, item
->ItemType
, item
->AnimationType
, IS_GET
);
5479 gamedata
->FreeItem(item
, si
->ItemResRef
,0);
5481 actor
->ReinitQuickSlots();
5483 if (res
!=-1) { //it is gold!
5484 game
->PartyGold
+= res
;
5487 container
->AddItem(si
);
5492 core
->GetAudioDrv()->Play(Sound
);
5495 Py_INCREF( Py_None
);
5499 PyDoc_STRVAR( GemRB_GetStore__doc
,
5500 "GetStore() => dictionary\n\n"
5501 "Returns relevant data of the current store." );
5503 #define STORETYPE_COUNT 7
5504 static int storebuttons
[STORETYPE_COUNT
][4]={
5506 {STA_BUYSELL
,STA_IDENTIFY
|STA_OPTIONAL
,STA_STEAL
|STA_OPTIONAL
,STA_CURE
|STA_OPTIONAL
},
5508 {STA_DRINK
,STA_BUYSELL
|STA_OPTIONAL
,STA_IDENTIFY
|STA_OPTIONAL
,STA_STEAL
|STA_OPTIONAL
},
5510 {STA_ROOMRENT
,STA_BUYSELL
|STA_OPTIONAL
,STA_DRINK
|STA_OPTIONAL
,STA_STEAL
|STA_OPTIONAL
},
5512 {STA_CURE
, STA_DONATE
|STA_OPTIONAL
,STA_BUYSELL
|STA_OPTIONAL
,STA_IDENTIFY
|STA_OPTIONAL
},
5514 {STA_BUYSELL
,-1,-1,-1,},
5515 //no need to steal from your own container (original engine had STEAL instead of DRINK)
5516 {STA_BUYSELL
,STA_IDENTIFY
|STA_OPTIONAL
,STA_DRINK
|STA_OPTIONAL
,STA_CURE
|STA_OPTIONAL
},
5517 //gemrb specific store type: (temple 2), added steal, removed identify
5518 {STA_BUYSELL
,STA_STEAL
|STA_OPTIONAL
,STA_DONATE
|STA_OPTIONAL
,STA_CURE
|STA_OPTIONAL
} };
5520 //buy/sell, identify, steal, cure, donate, drink, rent
5521 static int storebits
[7]={IE_STORE_BUY
|IE_STORE_SELL
,IE_STORE_ID
,IE_STORE_STEAL
,
5522 IE_STORE_CURE
,IE_STORE_DONATE
,IE_STORE_DRINK
,IE_STORE_RENT
};
5524 static PyObject
* GemRB_GetStore(PyObject
* /*self*/, PyObject
* args
)
5526 if (!PyArg_ParseTuple( args
, "" )) {
5527 return AttributeError( GemRB_GetStore__doc
);
5530 Store
*store
= core
->GetCurrentStore();
5532 Py_INCREF( Py_None
);
5535 if (store
->Type
>STORETYPE_COUNT
-1) {
5536 store
->Type
=STORETYPE_COUNT
-1;
5538 PyObject
* dict
= PyDict_New();
5539 PyDict_SetItemString(dict
, "StoreType", PyInt_FromLong( store
->Type
));
5540 PyDict_SetItemString(dict
, "StoreName", PyInt_FromLong( (signed) store
->StoreName
));
5541 PyDict_SetItemString(dict
, "StoreDrinkCount", PyInt_FromLong( store
->DrinksCount
));
5542 PyDict_SetItemString(dict
, "StoreCureCount", PyInt_FromLong( store
->CuresCount
));
5543 PyDict_SetItemString(dict
, "StoreItemCount", PyInt_FromLong( store
->GetRealStockSize() ));
5544 PyDict_SetItemString(dict
, "StoreCapacity", PyInt_FromLong( store
->Capacity
));
5545 PyObject
* p
= PyTuple_New( 4 );
5550 for (i
= 0; i
< 4; i
++) {
5551 if (store
->AvailableRooms
&j
) {
5552 k
= store
->RoomPrices
[i
];
5555 PyTuple_SetItem( p
, i
, PyInt_FromLong( k
) );
5558 PyDict_SetItemString(dict
, "StoreRoomPrices", p
);
5560 p
= PyTuple_New( 4 );
5562 for (i
= 0; i
< 4; i
++) {
5563 k
= storebuttons
[store
->Type
][i
];
5564 if (k
&STA_OPTIONAL
) {
5566 //check if the type was disabled
5567 if (!(store
->Flags
& storebits
[k
]) ) {
5571 PyTuple_SetItem( p
, j
++, PyInt_FromLong( k
) );
5574 PyTuple_SetItem( p
, j
, PyInt_FromLong( -1 ) );
5576 PyDict_SetItemString(dict
, "StoreButtons", p
);
5577 PyDict_SetItemString(dict
, "StoreFlags", PyInt_FromLong( store
->Flags
) );
5578 PyDict_SetItemString(dict
, "TavernRumour", PyString_FromResRef( store
->RumoursTavern
));
5579 PyDict_SetItemString(dict
, "TempleRumour", PyString_FromResRef( store
->RumoursTemple
));
5580 PyDict_SetItemString(dict
, "IDPrice", PyInt_FromLong( store
->IDPrice
) );
5581 PyDict_SetItemString(dict
, "Lore", PyInt_FromLong( store
->Lore
) );
5582 PyDict_SetItemString(dict
, "Depreciation", PyInt_FromLong( store
->DepreciationRate
) );
5583 PyDict_SetItemString(dict
, "SellMarkup", PyInt_FromLong( store
->SellMarkup
) );
5584 PyDict_SetItemString(dict
, "BuyMarkup", PyInt_FromLong( store
->BuyMarkup
) );
5585 PyDict_SetItemString(dict
, "StealFailure", PyInt_FromLong( store
->StealFailureChance
) );
5591 PyDoc_STRVAR( GemRB_IsValidStoreItem__doc
,
5592 "IsValidStoreItem(pc, idx[, type]) => int\n\n"
5593 "Returns if a pc's inventory item or a store item is valid for buying, selling, identifying or stealing. It also has a flag for selected items. "
5594 "Type is 1 for store items and 0 for PC items." );
5596 static PyObject
* GemRB_IsValidStoreItem(PyObject
* /*self*/, PyObject
* args
)
5598 int PartyID
, Slot
, ret
;
5601 if (!PyArg_ParseTuple( args
, "ii|i", &PartyID
, &Slot
, &type
)) {
5602 return AttributeError( GemRB_IsValidStoreItem__doc
);
5604 Game
*game
= core
->GetGame();
5606 return RuntimeError( "No game loaded!" );
5608 Actor
* actor
= game
->FindPC( PartyID
);
5610 return RuntimeError( "Actor not found" );
5613 Store
*store
= core
->GetCurrentStore();
5615 return RuntimeError("No current store!");
5618 const char *ItemResRef
;
5622 STOItem
* si
= store
->GetItem( Slot
);
5624 return PyInt_FromLong(0);
5626 ItemResRef
= si
->ItemResRef
;
5629 CREItem
* si
= actor
->inventory
.GetSlotItem( core
->QuerySlot(Slot
) );
5631 return PyInt_FromLong(0);
5633 ItemResRef
= si
->ItemResRef
;
5636 Item
*item
= gamedata
->GetItem( ItemResRef
);
5638 printMessage("GUIScript", " ", LIGHT_RED
);
5639 printf("Invalid resource reference: %s\n", ItemResRef
);
5640 return PyInt_FromLong(0);
5643 ret
= store
->AcceptableItemType( item
->ItemType
, Flags
, !type
);
5645 //don't allow putting a bag into itself
5646 if (!strnicmp(ItemResRef
, store
->Name
, sizeof(ieResRef
)) ) {
5647 ret
&= ~IE_STORE_SELL
;
5649 //this is a hack to report on selected items
5650 if (Flags
& IE_INV_ITEM_SELECTED
) {
5651 ret
|= IE_STORE_SELECT
;
5653 gamedata
->FreeItem( item
, ItemResRef
, false );
5654 return PyInt_FromLong(ret
);
5657 PyDoc_STRVAR( GemRB_SetPurchasedAmount__doc
,
5658 "SetPurchasedAmount(idx, amount)\n\n"
5659 "Sets the amount of purchased items of a type.");
5661 static PyObject
* GemRB_SetPurchasedAmount(PyObject
* /*self*/, PyObject
* args
)
5666 if (!PyArg_ParseTuple( args
, "ii", &Slot
, &tmp
)) {
5667 return AttributeError( GemRB_SetPurchasedAmount__doc
);
5669 amount
= (ieDword
) tmp
;
5670 Store
*store
= core
->GetCurrentStore();
5672 return RuntimeError("No current store!");
5674 STOItem
* si
= store
->GetItem( Slot
);
5676 return RuntimeError("Store item not found!");
5679 if (si
->InfiniteSupply
!= -1) {
5680 if (si
->AmountInStock
<amount
) {
5681 amount
=si
->AmountInStock
;
5684 si
->PurchasedAmount
=amount
;
5686 si
->Flags
|= IE_INV_ITEM_SELECTED
;
5688 si
->Flags
&= ~IE_INV_ITEM_SELECTED
;
5691 Py_INCREF( Py_None
);
5695 PyDoc_STRVAR( GemRB_ChangeStoreItem__doc
,
5696 "ChangeStoreItem(PartyID, Slot, action)=>int\n\n"
5697 "Performs an action of buying, selling, identifying or stealing in a store. "
5698 "It can also toggle the selection of an item." );
5700 static PyObject
* GemRB_ChangeStoreItem(PyObject
* /*self*/, PyObject
* args
)
5704 int res
= ASI_FAILED
;
5706 if (!PyArg_ParseTuple( args
, "iii", &PartyID
, &Slot
, &action
)) {
5707 return AttributeError( GemRB_ChangeStoreItem__doc
);
5709 Game
*game
= core
->GetGame();
5711 return RuntimeError( "No game loaded!" );
5713 Actor
* actor
= game
->FindPC( PartyID
);
5715 return RuntimeError( "Actor not found" );
5718 Store
*store
= core
->GetCurrentStore();
5720 return RuntimeError("No current store!");
5723 case IE_STORE_BUY
: case IE_STORE_STEAL
:
5725 STOItem
* si
= store
->GetItem( Slot
);
5727 return RuntimeError("Store item not found!");
5729 //the amount of items is stored in si->PurchasedAmount
5730 //it will adjust AmountInStock/PurchasedAmount
5731 actor
->inventory
.AddStoreItem(si
, action
);
5732 if (si
->PurchasedAmount
) {
5733 //was not able to buy it due to lack of space
5737 //if no item remained, remove it
5738 if (si
->AmountInStock
) {
5739 si
->Flags
&= ~IE_INV_ITEM_SELECTED
;
5741 store
->RemoveItem( Slot
);
5748 CREItem
* si
= actor
->inventory
.GetSlotItem( core
->QuerySlot(Slot
) );
5750 return RuntimeError( "Item not found!" );
5752 si
->Flags
|= IE_INV_ITEM_IDENTIFIED
;
5756 case IE_STORE_SELECT
|IE_STORE_BUY
:
5758 STOItem
* si
= store
->GetItem( Slot
);
5760 return RuntimeError("Store item not found!");
5762 si
->Flags
^= IE_INV_ITEM_SELECTED
;
5763 if (si
->Flags
& IE_INV_ITEM_SELECTED
) {
5764 si
->PurchasedAmount
=1;
5766 si
->PurchasedAmount
=0;
5772 case IE_STORE_SELECT
|IE_STORE_SELL
:
5774 //this is not removeitem, because the item is just marked
5775 CREItem
* si
= actor
->inventory
.GetSlotItem( core
->QuerySlot(Slot
) );
5777 return RuntimeError( "Item not found!" );
5779 si
->Flags
^= IE_INV_ITEM_SELECTED
;
5785 //store/bag is at full capacity
5786 if (store
->Capacity
&& (store
->Capacity
<= store
->GetRealStockSize()) ) {
5787 printMessage("GUIScript", "Store is full.\n", GREEN
);
5791 //this is removeitem, because the item leaves our inventory
5792 CREItem
* si
= actor
->inventory
.RemoveItem( core
->QuerySlot(Slot
) );
5794 return RuntimeError( "Item not found!" );
5796 //well, it shouldn't be sold at all, but if it is here
5798 if (!si
->Expired
&& (si
->Flags
& IE_INV_ITEM_RESELLABLE
)) {
5799 si
->Flags
&= ~IE_INV_ITEM_SELECTED
;
5800 store
->AddItem( si
);
5807 return PyInt_FromLong(res
);
5810 PyDoc_STRVAR( GemRB_GetStoreItem__doc
,
5811 "GetStoreItem(idx) => dictionary\n\n"
5812 "Returns the store item referenced by the index." );
5814 static PyObject
* GemRB_GetStoreItem(PyObject
* /*self*/, PyObject
* args
)
5818 if (!PyArg_ParseTuple( args
, "i", &index
)) {
5819 return AttributeError( GemRB_GetStoreItem__doc
);
5821 Store
*store
= core
->GetCurrentStore();
5823 return RuntimeError("No current store!");
5825 if (index
>=(int) store
->GetRealStockSize()) {
5826 printMessage("GUIScript","Item is not available???",YELLOW
);
5827 Py_INCREF( Py_None
);
5830 PyObject
* dict
= PyDict_New();
5831 STOItem
*si
=store
->GetItem( index
);
5833 printMessage("GUIScript","Item is not available???",YELLOW
);
5834 Py_INCREF( Py_None
);
5837 PyDict_SetItemString(dict
, "ItemResRef", PyString_FromResRef( si
->ItemResRef
));
5838 PyDict_SetItemString(dict
, "Usages0", PyInt_FromLong (si
->Usages
[0]));
5839 PyDict_SetItemString(dict
, "Usages1", PyInt_FromLong (si
->Usages
[1]));
5840 PyDict_SetItemString(dict
, "Usages2", PyInt_FromLong (si
->Usages
[2]));
5841 PyDict_SetItemString(dict
, "Flags", PyInt_FromLong (si
->Flags
));
5842 PyDict_SetItemString(dict
, "Purchased", PyInt_FromLong (si
->PurchasedAmount
) );
5845 if (si
->InfiniteSupply
==-1) {
5846 PyDict_SetItemString(dict
, "Amount", PyInt_FromLong( -1 ) );
5849 amount
= si
->AmountInStock
;
5850 PyDict_SetItemString(dict
, "Amount", PyInt_FromLong( amount
) );
5853 Item
*item
= gamedata
->GetItem( si
->ItemResRef
);
5856 printMessage("GUIScript","Item is not available???",YELLOW
);
5857 Py_INCREF( Py_None
);
5861 int identified
= !!(si
->Flags
& IE_INV_ITEM_IDENTIFIED
);
5862 PyDict_SetItemString(dict
, "ItemName", PyInt_FromLong( (signed) item
->GetItemName( (bool) identified
)) );
5863 PyDict_SetItemString(dict
, "ItemDesc", PyInt_FromLong( (signed) item
->GetItemDesc( (bool) identified
)) );
5865 int price
= item
->Price
* store
->SellMarkup
/ 100;
5866 //calculate depreciation too
5867 //store->DepreciationRate, mount
5869 if (item
->StackAmount
>1) {
5870 price
*= si
->Usages
[0];
5876 PyDict_SetItemString(dict
, "Price", PyInt_FromLong( price
) );
5878 gamedata
->FreeItem( item
, si
->ItemResRef
, false );
5882 PyDoc_STRVAR( GemRB_GetStoreDrink__doc
,
5883 "GetStoreDrink(idx) => dictionary\n\n"
5884 "Returns the drink structure indexed. Returns None if the index is wrong." );
5886 static PyObject
* GemRB_GetStoreDrink(PyObject
* /*self*/, PyObject
* args
)
5890 if (!PyArg_ParseTuple( args
, "i", &index
)) {
5891 return AttributeError( GemRB_GetStoreDrink__doc
);
5893 Store
*store
= core
->GetCurrentStore();
5895 return RuntimeError("No current store!");
5897 if (index
>=(int) store
->DrinksCount
) {
5898 Py_INCREF( Py_None
);
5901 PyObject
* dict
= PyDict_New();
5902 STODrink
*drink
=store
->GetDrink(index
);
5903 PyDict_SetItemString(dict
, "DrinkName", PyInt_FromLong( (signed) drink
->DrinkName
));
5904 PyDict_SetItemString(dict
, "Price", PyInt_FromLong( drink
->Price
));
5905 PyDict_SetItemString(dict
, "Strength", PyInt_FromLong( drink
->Strength
));
5909 static void ReadSpecialSpells()
5913 SpecialSpellsCount
= 0;
5914 int table
= gamedata
->LoadTable("splspec");
5916 Holder
<TableMgr
> tab
= gamedata
->GetTable(table
);
5917 if (!tab
) goto table_loaded
;
5918 SpecialSpellsCount
= tab
->GetRowCount();
5919 SpecialSpells
= (SpellDescType
*) malloc( sizeof(SpellDescType
) * SpecialSpellsCount
);
5920 for (i
=0;i
<SpecialSpellsCount
;i
++) {
5921 strnlwrcpy(SpecialSpells
[i
].resref
, tab
->GetRowName(i
),8 );
5922 //if there are more flags, compose this value into a bitfield
5923 SpecialSpells
[i
].value
= atoi(tab
->QueryField(i
,0) );
5926 gamedata
->DelTable(table
);
5930 int GetSpecialSpell(ieResRef resref
)
5932 if (SpecialSpellsCount
==-1) {
5933 ReadSpecialSpells();
5935 for (int i
=0;i
<SpecialSpellsCount
;i
++) {
5936 if (!strnicmp(resref
, SpecialSpells
[i
].resref
, sizeof(ieResRef
))) {
5937 return SpecialSpells
[i
].value
;
5943 //disable spells based on some circumstances
5944 int CheckSpecialSpell(ieResRef resref
, Actor
*actor
)
5946 int sp
= GetSpecialSpell(resref
);
5948 //the identify spell is always disabled on the menu
5949 if (sp
&SP_IDENTIFY
) {
5953 //if actor is silenced, and spell cannot be cast in silence, disable it
5954 if (actor
->GetStat(IE_STATE_ID
) & STATE_SILENCED
) {
5955 if (!(sp
&SP_SILENCE
)) {
5963 static void ReadUsedItems()
5968 int table
= gamedata
->LoadTable("item_use");
5970 Holder
<TableMgr
> tab
= gamedata
->GetTable(table
);
5971 if (!tab
) goto table_loaded
;
5972 UsedItemsCount
= tab
->GetRowCount();
5973 UsedItems
= (UsedItemType
*) malloc( sizeof(UsedItemType
) * UsedItemsCount
);
5974 for (i
=0;i
<UsedItemsCount
;i
++) {
5975 strnlwrcpy(UsedItems
[i
].itemname
, tab
->GetRowName(i
),8 );
5976 strnlwrcpy(UsedItems
[i
].username
, tab
->QueryField(i
,0),32 );
5978 UsedItems
[i
].value
= atoi(tab
->QueryField(i
,1) );
5981 gamedata
->DelTable(table
);
5985 static void ReadSpecialItems()
5989 SpecialItemsCount
= 0;
5990 int table
= gamedata
->LoadTable("itemspec");
5992 Holder
<TableMgr
> tab
= gamedata
->GetTable(table
);
5993 if (!tab
) goto table_loaded
;
5994 SpecialItemsCount
= tab
->GetRowCount();
5995 SpecialItems
= (SpellDescType
*) malloc( sizeof(SpellDescType
) * SpecialItemsCount
);
5996 for (i
=0;i
<SpecialItemsCount
;i
++) {
5997 strnlwrcpy(SpecialItems
[i
].resref
, tab
->GetRowName(i
),8 );
5998 //if there are more flags, compose this value into a bitfield
5999 SpecialItems
[i
].value
= atoi(tab
->QueryField(i
,0) );
6002 gamedata
->DelTable(table
);
6006 static ieStrRef
GetSpellDesc(ieResRef CureResRef
)
6010 if (StoreSpellsCount
==-1) {
6011 StoreSpellsCount
= 0;
6012 int table
= gamedata
->LoadTable("speldesc");
6014 Holder
<TableMgr
> tab
= gamedata
->GetTable(table
);
6015 if (!tab
) goto table_loaded
;
6016 StoreSpellsCount
= tab
->GetRowCount();
6017 StoreSpells
= (SpellDescType
*) malloc( sizeof(SpellDescType
) * StoreSpellsCount
);
6018 for (i
=0;i
<StoreSpellsCount
;i
++) {
6019 strnlwrcpy(StoreSpells
[i
].resref
, tab
->GetRowName(i
),8 );
6020 StoreSpells
[i
].value
= atoi(tab
->QueryField(i
,0) );
6023 gamedata
->DelTable(table
);
6026 if (StoreSpellsCount
==0) {
6027 Spell
*spell
= gamedata
->GetSpell(CureResRef
);
6031 int ret
= spell
->SpellDescIdentified
;
6032 gamedata
->FreeSpell(spell
, CureResRef
, false);
6035 for (i
=0;i
<StoreSpellsCount
;i
++) {
6036 if (!strnicmp(StoreSpells
[i
].resref
, CureResRef
, 8) ) {
6037 return StoreSpells
[i
].value
;
6043 PyDoc_STRVAR( GemRB_GetStoreCure__doc
,
6044 "GetStoreCure(idx) => dictionary\n\n"
6045 "Returns the cure structure indexed. Returns None if the index is wrong." );
6047 static PyObject
* GemRB_GetStoreCure(PyObject
* /*self*/, PyObject
* args
)
6051 if (!PyArg_ParseTuple( args
, "i", &index
)) {
6052 return AttributeError( GemRB_GetStoreCure__doc
);
6054 Store
*store
= core
->GetCurrentStore();
6056 return RuntimeError("No current store!");
6058 if (index
>=(int) store
->CuresCount
) {
6059 Py_INCREF( Py_None
);
6062 PyObject
* dict
= PyDict_New();
6063 STOCure
*cure
=store
->GetCure(index
);
6064 PyDict_SetItemString(dict
, "CureResRef", PyString_FromResRef( cure
->CureResRef
));
6065 PyDict_SetItemString(dict
, "Price", PyInt_FromLong( cure
->Price
));
6066 PyDict_SetItemString(dict
, "Description", PyInt_FromLong( (signed) GetSpellDesc(cure
->CureResRef
) ) );
6070 PyDoc_STRVAR( GemRB_ExecuteString__doc
,
6071 "ExecuteString(String[,PC])\n\n"
6072 "Executes an In-Game Script Action in the current Area Script Context. "
6073 "If a number was given, it will execute the action in the numbered PC's context." );
6075 static PyObject
* GemRB_ExecuteString(PyObject
* /*self*/, PyObject
* args
)
6080 if (!PyArg_ParseTuple( args
, "s|i", &String
, &actornum
)) {
6081 return AttributeError( GemRB_ExecuteString__doc
);
6083 Game
*game
= core
->GetGame();
6085 return RuntimeError( "No game loaded!" );
6088 Actor
*pc
= game
->FindPC(actornum
);
6090 GameScript::ExecuteString( pc
, String
);
6092 printMessage("GUIScript","Player not found!\n", YELLOW
);
6095 GameScript::ExecuteString( game
->GetCurrentArea( ), String
);
6097 Py_INCREF( Py_None
);
6101 PyDoc_STRVAR( GemRB_RunEventHandler__doc
,
6102 "RunEventHandler(String[, error])\n\n"
6103 "Executes a GUIScript event handler function named String. "
6104 "If error is set to nonzero, then a missing handler will cause an error." );
6106 static PyObject
* GemRB_RunEventHandler(PyObject
* /*self*/, PyObject
* args
)
6111 if (!PyArg_ParseTuple( args
, "s|i", &String
, error
)) {
6112 return AttributeError( GemRB_RunEventHandler__doc
);
6114 core
->GetGUIScriptEngine()->RunFunction( String
, error
);
6115 Py_INCREF( Py_None
);
6119 PyDoc_STRVAR( GemRB_EvaluateString__doc
,
6120 "EvaluateString(String)\n\n"
6121 "Evaluate an In-Game Script Trigger in the current Area Script Context." );
6123 static PyObject
* GemRB_EvaluateString(PyObject
* /*self*/, PyObject
* args
)
6127 if (!PyArg_ParseTuple( args
, "s", &String
)) {
6128 return AttributeError( GemRB_EvaluateString__doc
);
6130 if (GameScript::EvaluateString( core
->GetGame()->GetCurrentArea( ), String
)) {
6131 printf( "%s returned True\n", String
);
6133 printf( "%s returned False\n", String
);
6135 Py_INCREF( Py_None
);
6139 PyDoc_STRVAR( GemRB_UpdateMusicVolume__doc
,
6140 "UpdateMusicVolume()\n\n"
6141 "Update music volume on-the-fly." );
6143 static PyObject
* GemRB_UpdateMusicVolume(PyObject
* /*self*/, PyObject
* /*args*/)
6145 core
->GetAudioDrv()->UpdateVolume( GEM_SND_VOL_MUSIC
);
6147 Py_INCREF( Py_None
);
6151 PyDoc_STRVAR( GemRB_UpdateAmbientsVolume__doc
,
6152 "UpdateAmbientsVolume()\n\n"
6153 "Update ambients volume on-the-fly." );
6155 static PyObject
* GemRB_UpdateAmbientsVolume(PyObject
* /*self*/, PyObject
* /*args*/)
6157 core
->GetAudioDrv()->UpdateVolume( GEM_SND_VOL_AMBIENTS
);
6159 Py_INCREF( Py_None
);
6163 PyDoc_STRVAR( GemRB_GetCurrentArea__doc
,
6164 "GetCurrentArea()=>resref\n\n"
6165 "Returns current area's ResRef." );
6167 static PyObject
* GemRB_GetCurrentArea(PyObject
* /*self*/, PyObject
* /*args*/)
6169 return PyString_FromString( core
->GetGame()->CurrentArea
);
6172 PyDoc_STRVAR( GemRB_MoveToArea__doc
,
6173 "MoveToArea(resref)\n\n"
6174 "Moves the selected characters to the area." );
6176 static PyObject
* GemRB_MoveToArea(PyObject
* /*self*/, PyObject
* args
)
6180 if (!PyArg_ParseTuple( args
, "s", &String
)) {
6181 return AttributeError( GemRB_MoveToArea__doc
);
6183 Game
*game
= core
->GetGame();
6185 return RuntimeError( "No game loaded!" );
6187 Map
* map2
= game
->GetMap(String
, true);
6189 return RuntimeError( "Map not found!" );
6191 int i
= game
->GetPartySize(true);
6193 Actor
* actor
= game
->GetPC(i
, false);
6194 if (!actor
->Selected
) {
6197 Map
* map1
= actor
->GetCurrentArea();
6199 map1
->RemoveActor( actor
);
6201 map2
->AddActor( actor
);
6204 Py_INCREF( Py_None
);
6208 PyDoc_STRVAR( GemRB_GetMemorizableSpellsCount__doc
,
6209 "GetMemorizableSpellsCount(PartyID, SpellType, Level [,Bonus])=>int\n\n"
6210 "Returns number of memorizable spells of given type and level in PC's spellbook." );
6212 static PyObject
* GemRB_GetMemorizableSpellsCount(PyObject
* /*self*/, PyObject
* args
)
6214 int PartyID
, SpellType
, Level
, Bonus
=1;
6216 if (!PyArg_ParseTuple( args
, "iii|i", &PartyID
, &SpellType
, &Level
, &Bonus
)) {
6217 return AttributeError( GemRB_GetMemorizableSpellsCount__doc
);
6219 Game
*game
= core
->GetGame();
6221 return RuntimeError( "No game loaded!" );
6223 Actor
* actor
= game
->FindPC( PartyID
);
6225 return RuntimeError( "Actor not found" );
6228 //this isn't in the actor's spellbook, handles Wisdom
6229 return PyInt_FromLong(actor
->spellbook
.GetMemorizableSpellsCount( (ieSpellType
) SpellType
, Level
, (bool) Bonus
) );
6232 PyDoc_STRVAR( GemRB_SetMemorizableSpellsCount__doc
,
6233 "SetMemorizableSpellsCount(PartyID, Value, SpellType, Level, [Bonus])=>int\n\n"
6234 "Sets number of memorizable spells of given type and level in PC's spellbook." );
6236 static PyObject
* GemRB_SetMemorizableSpellsCount(PyObject
* /*self*/, PyObject
* args
)
6238 int PartyID
, Value
, SpellType
, Level
;
6240 if (!PyArg_ParseTuple( args
, "iiii", &PartyID
, &Value
, &SpellType
, &Level
)) {
6241 return AttributeError( GemRB_SetMemorizableSpellsCount__doc
);
6243 Game
*game
= core
->GetGame();
6245 return RuntimeError( "No game loaded!" );
6247 Actor
* actor
= game
->FindPC( PartyID
);
6249 return RuntimeError( "Actor not found" );
6252 //the bonus increased value (with wisdom too) is handled by the core
6253 actor
->spellbook
.SetMemorizableSpellsCount( Value
, (ieSpellType
) SpellType
, Level
, 0 );
6255 Py_INCREF( Py_None
);
6259 PyDoc_STRVAR( GemRB_GetKnownSpellsCount__doc
,
6260 "GetKnownSpellsCount(PartyID, SpellType, Level)=>int\n\n"
6261 "Returns number of known spells of given type and level in PC's spellbook." );
6263 static PyObject
* GemRB_GetKnownSpellsCount(PyObject
* /*self*/, PyObject
* args
)
6265 int PartyID
, SpellType
, Level
;
6267 if (!PyArg_ParseTuple( args
, "iii", &PartyID
, &SpellType
, &Level
)) {
6268 return AttributeError( GemRB_GetKnownSpellsCount__doc
);
6270 Game
*game
= core
->GetGame();
6272 return RuntimeError( "No game loaded!" );
6274 Actor
* actor
= game
->FindPC( PartyID
);
6276 return RuntimeError( "Actor not found" );
6279 return PyInt_FromLong(actor
->spellbook
.GetKnownSpellsCount( SpellType
, Level
) );
6282 PyDoc_STRVAR( GemRB_GetKnownSpell__doc
,
6283 "GetKnownSpell(PartyID, SpellType, Level, Index)=>dict\n\n"
6284 "Returns dict with specified known spell from PC's spellbook." );
6286 static PyObject
* GemRB_GetKnownSpell(PyObject
* /*self*/, PyObject
* args
)
6288 int PartyID
, SpellType
, Level
, Index
;
6290 if (!PyArg_ParseTuple( args
, "iiii", &PartyID
, &SpellType
, &Level
, &Index
)) {
6291 return AttributeError( GemRB_GetKnownSpell__doc
);
6293 Game
*game
= core
->GetGame();
6295 return RuntimeError( "No game loaded!" );
6297 Actor
* actor
= game
->FindPC( PartyID
);
6299 return RuntimeError( "Actor not found!" );
6302 CREKnownSpell
* ks
= actor
->spellbook
.GetKnownSpell( SpellType
, Level
, Index
);
6304 return RuntimeError( "Spell not found!" );
6307 PyObject
* dict
= PyDict_New();
6308 PyDict_SetItemString(dict
, "SpellResRef", PyString_FromResRef (ks
->SpellResRef
));
6309 //PyDict_SetItemString(dict, "Flags", PyInt_FromLong (ms->Flags));
6315 PyDoc_STRVAR( GemRB_GetMemorizedSpellsCount__doc
,
6316 "GetMemorizedSpellsCount(PartyID, SpellType[, Level])=>int\n\n"
6317 "Returns number of spells of given type and level in PartyID's memory. "
6318 "If level is omitted then it returns the number of distinct spells memorised." );
6320 static PyObject
* GemRB_GetMemorizedSpellsCount(PyObject
* /*self*/, PyObject
* args
)
6322 int PartyID
, SpellType
, Level
= -1;
6324 if (!PyArg_ParseTuple( args
, "ii|i", &PartyID
, &SpellType
, &Level
)) {
6325 return AttributeError( GemRB_GetMemorizedSpellsCount__doc
);
6327 Game
*game
= core
->GetGame();
6329 return RuntimeError( "No game loaded!" );
6331 Actor
* actor
= game
->FindPC( PartyID
);
6333 return RuntimeError( "Actor not found!" );
6337 return PyInt_FromLong( actor
->spellbook
.GetSpellInfoSize( SpellType
) );
6339 return PyInt_FromLong( actor
->spellbook
.GetMemorizedSpellsCount( SpellType
, Level
) );
6343 PyDoc_STRVAR( GemRB_GetMemorizedSpell__doc
,
6344 "GetMemorizedSpell(PartyID, SpellType, Level, Index)=>dict\n\n"
6345 "Returns dict with specified memorized spell from PC's spellbook." );
6347 static PyObject
* GemRB_GetMemorizedSpell(PyObject
* /*self*/, PyObject
* args
)
6349 int PartyID
, SpellType
, Level
, Index
;
6351 if (!PyArg_ParseTuple( args
, "iiii", &PartyID
, &SpellType
, &Level
, &Index
)) {
6352 return AttributeError( GemRB_GetMemorizedSpell__doc
);
6354 Game
*game
= core
->GetGame();
6356 return RuntimeError( "No game loaded!" );
6358 Actor
* actor
= game
->FindPC( PartyID
);
6360 return RuntimeError( "Actor not found!" );
6363 CREMemorizedSpell
* ms
= actor
->spellbook
.GetMemorizedSpell( SpellType
, Level
, Index
);
6365 return RuntimeError( "Spell not found!" );
6368 PyObject
* dict
= PyDict_New();
6369 PyDict_SetItemString(dict
, "SpellResRef", PyString_FromResRef (ms
->SpellResRef
));
6370 PyDict_SetItemString(dict
, "Flags", PyInt_FromLong (ms
->Flags
));
6376 PyDoc_STRVAR( GemRB_GetSpell__doc
,
6377 "GetSpell(ResRef[, silent])=>dict\n\n"
6378 "Returns dict with specified spell. Verbose by default." );
6380 static PyObject
* GemRB_GetSpell(PyObject
* /*self*/, PyObject
* args
)
6385 if (!PyArg_ParseTuple( args
, "s|i", &ResRef
, &silent
)) {
6386 return AttributeError( GemRB_GetSpell__doc
);
6389 if (silent
&& !gamedata
->Exists(ResRef
,IE_SPL_CLASS_ID
, true)) {
6390 Py_INCREF( Py_None
);
6394 Spell
* spell
= gamedata
->GetSpell(ResRef
, silent
);
6395 if (spell
== NULL
) {
6396 Py_INCREF( Py_None
);
6400 PyObject
* dict
= PyDict_New();
6401 PyDict_SetItemString(dict
, "SpellName", PyInt_FromLong ((signed) spell
->SpellName
));
6402 PyDict_SetItemString(dict
, "SpellDesc", PyInt_FromLong ((signed) spell
->SpellDesc
));
6403 PyDict_SetItemString(dict
, "SpellbookIcon", PyString_FromResRef (spell
->SpellbookIcon
));
6404 PyDict_SetItemString(dict
, "SpellExclusion", PyInt_FromLong (spell
->ExclusionSchool
)); //this will list school exclusions and alignment
6405 PyDict_SetItemString(dict
, "SpellDivine", PyInt_FromLong (spell
->PriestType
)); //this will tell apart a priest spell from a druid spell
6406 PyDict_SetItemString(dict
, "SpellSchool", PyInt_FromLong (spell
->PrimaryType
));
6407 PyDict_SetItemString(dict
, "SpellType", PyInt_FromLong (spell
->SecondaryType
));
6408 PyDict_SetItemString(dict
, "SpellLevel", PyInt_FromLong (spell
->SpellLevel
));
6409 gamedata
->FreeSpell( spell
, ResRef
, false );
6414 PyDoc_STRVAR( GemRB_LearnSpell__doc
,
6415 "LearnSpell(PartyID, SpellResRef[, Flags])=>int\n\n"
6416 "Learns specified spell. Returns 0 on success." );
6418 static PyObject
* GemRB_LearnSpell(PyObject
* /*self*/, PyObject
* args
)
6424 if (!PyArg_ParseTuple( args
, "is|i", &PartyID
, &Spell
, &Flags
)) {
6425 return AttributeError( GemRB_LearnSpell__doc
);
6427 Game
*game
= core
->GetGame();
6429 return RuntimeError( "No game loaded!" );
6431 Actor
* actor
= game
->FindPC( PartyID
);
6433 return RuntimeError( "Actor not found" );
6436 int ret
= actor
->LearnSpell( Spell
, Flags
); // returns 0 on success
6437 if (!ret
) core
->SetEventFlag( EF_ACTION
);
6438 return PyInt_FromLong( ret
);
6441 PyDoc_STRVAR( GemRB_DispelEffect__doc
,
6442 "DispelEffect(PartyID, EffectName, Parameter2)\n\n"
6443 "Removes all effects from target whose opcode and second parameter matches the arguments." );
6445 static EffectRef work_ref
;
6447 static PyObject
* GemRB_DispelEffect(PyObject
* /*self*/, PyObject
* args
)
6449 int PartyID
, Parameter2
;
6450 const char *EffectName
;
6452 if (!PyArg_ParseTuple( args
, "isi", &PartyID
, &EffectName
, &Parameter2
)) {
6453 return AttributeError( GemRB_DispelEffect__doc
);
6455 Game
*game
= core
->GetGame();
6457 return RuntimeError( "No game loaded!" );
6459 Actor
* actor
= game
->FindPC( PartyID
);
6461 return RuntimeError( "Actor not found!" );
6464 work_ref
.Name
=EffectName
;
6466 actor
->fxqueue
.RemoveAllEffectsWithParam(work_ref
, Parameter2
);
6468 Py_INCREF( Py_None
);
6473 PyDoc_STRVAR( GemRB_RemoveEffects__doc
,
6474 "RemoveEffects(PartyID, SpellResRef)\n\n"
6475 "Removes all effects from target whose source is SpellResRef." );
6477 static PyObject
* GemRB_RemoveEffects(PyObject
* /*self*/, PyObject
* args
)
6480 const char * SpellResRef
;
6482 if (!PyArg_ParseTuple( args
, "is", &PartyID
, &SpellResRef
)) {
6483 return AttributeError( GemRB_RemoveEffects__doc
);
6485 Game
*game
= core
->GetGame();
6487 return RuntimeError( "No game loaded!" );
6489 Actor
* actor
= game
->FindPC( PartyID
);
6491 return RuntimeError( "Actor not found!" );
6494 actor
->fxqueue
.RemoveAllEffects(SpellResRef
);
6496 Py_INCREF( Py_None
);
6500 PyDoc_STRVAR( GemRB_RemoveSpell__doc
,
6501 "RemoveSpell(PartyID, SpellType, Level, Index)=>bool\n\n"
6502 "Removes specified known spell. Returns 1 on success." );
6504 static PyObject
* GemRB_RemoveSpell(PyObject
* /*self*/, PyObject
* args
)
6506 int PartyID
, SpellType
, Level
, Index
;
6508 if (!PyArg_ParseTuple( args
, "iiii", &PartyID
, &SpellType
, &Level
, &Index
)) {
6509 return AttributeError( GemRB_RemoveSpell__doc
);
6511 Game
*game
= core
->GetGame();
6513 return RuntimeError( "No game loaded!" );
6515 Actor
* actor
= game
->FindPC( PartyID
);
6517 return RuntimeError( "Actor not found!" );
6520 CREKnownSpell
* ks
= actor
->spellbook
.GetKnownSpell( SpellType
, Level
, Index
);
6522 return RuntimeError( "Spell not known!" );
6525 return PyInt_FromLong( actor
->spellbook
.RemoveSpell( ks
) );
6528 PyDoc_STRVAR( GemRB_RemoveItem__doc
,
6529 "RemoveItem(PartyID, Slot[, Count])=>bool\n\n"
6530 "Removes (or decreases the charges) of a specified item. Returns 1 on success." );
6532 static PyObject
* GemRB_RemoveItem(PyObject
* /*self*/, PyObject
* args
)
6537 if (!PyArg_ParseTuple( args
, "ii|i", &PartyID
, &Slot
, &Count
)) {
6538 return AttributeError( GemRB_RemoveItem__doc
);
6540 Game
*game
= core
->GetGame();
6542 return RuntimeError( "No game loaded!" );
6544 Actor
* actor
= game
->FindPC( PartyID
);
6546 return RuntimeError( "Actor not found!" );
6551 Slot
= core
->QuerySlot(Slot
);
6552 actor
->inventory
.UnEquipItem( Slot
, false );
6553 CREItem
*si
= actor
->inventory
.RemoveItem( Slot
, Count
);
6560 return PyInt_FromLong( ok
);
6563 PyDoc_STRVAR( GemRB_MemorizeSpell__doc
,
6564 "MemorizeSpell(PartyID, SpellType, Level, Index)=>bool\n\n"
6565 "Memorizes specified known spell. Returns 1 on success." );
6567 static PyObject
* GemRB_MemorizeSpell(PyObject
* /*self*/, PyObject
* args
)
6569 int PartyID
, SpellType
, Level
, Index
;
6571 if (!PyArg_ParseTuple( args
, "iiii", &PartyID
, &SpellType
, &Level
, &Index
)) {
6572 return AttributeError( GemRB_MemorizeSpell__doc
);
6574 Game
*game
= core
->GetGame();
6576 return RuntimeError( "No game loaded!" );
6578 Actor
* actor
= game
->FindPC( PartyID
);
6580 return RuntimeError( "Actor not found!" );
6583 CREKnownSpell
* ks
= actor
->spellbook
.GetKnownSpell( SpellType
, Level
, Index
);
6585 return RuntimeError( "Spell not found!" );
6588 bool enabled
= false;
6589 if (SpellType
== IE_SPELL_TYPE_INNATE
) enabled
= true;
6591 return PyInt_FromLong( actor
->spellbook
.MemorizeSpell( ks
, enabled
) );
6595 PyDoc_STRVAR( GemRB_UnmemorizeSpell__doc
,
6596 "UnmemorizeSpell(PartyID, SpellType, Level, Index)=>bool\n\n"
6597 "Unmemorizes specified known spell. Returns 1 on success." );
6599 static PyObject
* GemRB_UnmemorizeSpell(PyObject
* /*self*/, PyObject
* args
)
6601 int PartyID
, SpellType
, Level
, Index
;
6603 if (!PyArg_ParseTuple( args
, "iiii", &PartyID
, &SpellType
, &Level
, &Index
)) {
6604 return AttributeError( GemRB_UnmemorizeSpell__doc
);
6606 Game
*game
= core
->GetGame();
6608 return RuntimeError( "No game loaded!" );
6610 Actor
* actor
= game
->FindPC( PartyID
);
6612 return RuntimeError( "Actor not found!" );
6615 CREMemorizedSpell
* ms
= actor
->spellbook
.GetMemorizedSpell( SpellType
, Level
, Index
);
6617 return RuntimeError( "Spell not found!" );
6620 return PyInt_FromLong( actor
->spellbook
.UnmemorizeSpell( ms
) );
6623 PyDoc_STRVAR( GemRB_GetSlotItem__doc
,
6624 "GetSlotItem(PartyID, slot)=>dict\n\n"
6625 "Returns dict with specified slot item from PC's inventory or the dragged item if PartyID is 0." );
6627 static PyObject
* GemRB_GetSlotItem(PyObject
* /*self*/, PyObject
* args
)
6631 if (!PyArg_ParseTuple( args
, "ii", &PartyID
, &Slot
)) {
6632 return AttributeError( GemRB_GetSlotItem__doc
);
6638 si
= core
->GetDraggedItem();
6640 Game
*game
= core
->GetGame();
6642 return RuntimeError( "No game loaded!" );
6644 Actor
*actor
= game
->FindPC( PartyID
);
6646 return RuntimeError( "Actor not found" );
6649 Slot
= core
->QuerySlot(Slot
);
6650 header
= actor
->PCStats
->GetHeaderForSlot(Slot
);
6652 si
= actor
->inventory
.GetSlotItem( Slot
);
6655 Py_INCREF( Py_None
);
6658 PyObject
* dict
= PyDict_New();
6659 PyDict_SetItemString(dict
, "ItemResRef", PyString_FromResRef (si
->ItemResRef
));
6660 PyDict_SetItemString(dict
, "Usages0", PyInt_FromLong (si
->Usages
[0]));
6661 PyDict_SetItemString(dict
, "Usages1", PyInt_FromLong (si
->Usages
[1]));
6662 PyDict_SetItemString(dict
, "Usages2", PyInt_FromLong (si
->Usages
[2]));
6663 PyDict_SetItemString(dict
, "Flags", PyInt_FromLong (si
->Flags
));
6664 PyDict_SetItemString(dict
, "Header", PyInt_FromLong (header
));
6669 PyDoc_STRVAR( GemRB_ChangeItemFlag__doc
,
6670 "ChangeItemFlag(PartyID, slot, flags, op) => bool\n\n"
6671 "Changes an item flag of a player character in inventory slot. Returns false if failed." );
6673 static PyObject
* GemRB_ChangeItemFlag(PyObject
* /*self*/, PyObject
* args
)
6675 int PartyID
, Slot
, Flags
, Mode
;
6677 if (!PyArg_ParseTuple( args
, "iiii", &PartyID
, &Slot
, &Flags
, &Mode
)) {
6678 return AttributeError( GemRB_ChangeItemFlag__doc
);
6680 Game
*game
= core
->GetGame();
6682 return RuntimeError( "No game loaded!" );
6684 Actor
*actor
= game
->FindPC( PartyID
);
6686 return RuntimeError( "Actor not found" );
6688 if (actor
->inventory
.ChangeItemFlag(core
->QuerySlot(Slot
), Flags
, Mode
)) {
6689 return PyInt_FromLong(1);
6691 return PyInt_FromLong(0);
6695 PyDoc_STRVAR( GemRB_CanUseItemType__doc
,
6696 "CanUseItemType( slottype, itemname[, actor])=>bool\n\n"
6697 "Checks the itemtype vs. slottype, and also checks the usability flags vs. Actor's stats (alignment, class, race, kit etc.)" );
6699 static PyObject
* GemRB_CanUseItemType(PyObject
* /*self*/, PyObject
* args
)
6701 int SlotType
, PartyID
;
6702 const char *ItemName
;
6705 if (!PyArg_ParseTuple( args
, "is|i", &SlotType
, &ItemName
, &PartyID
)) {
6706 return AttributeError( GemRB_CanUseItemType__doc
);
6709 return PyInt_FromLong(0);
6711 Item
*item
= gamedata
->GetItem(ItemName
);
6713 return PyInt_FromLong(0);
6717 Game
*game
= core
->GetGame();
6719 return RuntimeError( "No game loaded!" );
6721 actor
= game
->FindPC( PartyID
);
6723 return RuntimeError( "Actor not found" );
6727 int ret
=core
->CanUseItemType(SlotType
, item
, actor
, false);
6728 gamedata
->FreeItem(item
, ItemName
, false);
6729 return PyInt_FromLong(ret
);
6733 PyDoc_STRVAR( GemRB_GetSlots__doc
,
6734 "GetSlots(PartyID, SlotType[,flag])=>dict\n\n"
6735 "Returns a tuple of slots of the inventory of a PC matching the slot type criteria.\n"
6736 "If the flag is >0, it will ignore empty slots.\n"
6737 "If the flag is <0, it will ignore filled slots.\n"
6738 "If the flag is 0, it will return all slots.\n"
6739 "The default is 1." );
6741 static PyObject
* GemRB_GetSlots(PyObject
* /*self*/, PyObject
* args
)
6743 int SlotType
, Count
, MaxCount
, PartyID
;
6746 if (!PyArg_ParseTuple( args
, "ii|i", &PartyID
, &SlotType
, &flag
)) {
6747 return AttributeError( GemRB_GetSlots__doc
);
6750 Game
*game
= core
->GetGame();
6752 return RuntimeError( "No game loaded!" );
6754 Actor
* actor
= game
->FindPC( PartyID
);
6756 return RuntimeError( "Actor not found" );
6759 MaxCount
= core
->SlotTypes
;
6762 for (i
=0;i
<MaxCount
;i
++) {
6763 int id
= core
->QuerySlot(i
);
6764 if ((core
->QuerySlotType( id
) & (ieDword
) SlotType
) != (ieDword
) SlotType
) {
6767 CREItem
*slot
= actor
->inventory
.GetSlotItem( id
);
6769 if(flag
<0 && slot
) continue;
6770 if(flag
>0 && !slot
) continue;
6775 PyObject
* tuple
= PyTuple_New( Count
);
6777 for (i
=0;i
<MaxCount
;i
++) {
6778 int id
= core
->QuerySlot(i
);
6779 if ((core
->QuerySlotType( id
) & (ieDword
) SlotType
) != (ieDword
) SlotType
) {
6782 CREItem
*slot
= actor
->inventory
.GetSlotItem( id
);
6784 if(flag
<0 && slot
) continue;
6785 if(flag
>0 && !slot
) continue;
6787 PyTuple_SetItem( tuple
, Count
++, PyInt_FromLong( i
) );
6793 PyDoc_STRVAR( GemRB_GetItem__doc
,
6794 "GetItem(ResRef)=>dict\n\n"
6795 "Returns dict with specified item." );
6797 #define CAN_DRINK 1 //potions
6798 #define CAN_READ 2 //scrolls
6799 #define CAN_STUFF 4 //containers
6800 #define CAN_SELECT 8 //items with more abilities
6802 static PyObject
* GemRB_GetItem(PyObject
* /*self*/, PyObject
* args
)
6806 Actor
*actor
= NULL
;
6808 if (!PyArg_ParseTuple( args
, "s|i", &ResRef
, &PartyID
)) {
6809 return AttributeError( GemRB_GetItem__doc
);
6811 //it isn't a problem if actor not found
6812 Game
*game
= core
->GetGame();
6815 PartyID
= game
->GetSelectedPCSingle();
6817 actor
= game
->FindPC( PartyID
);
6820 Item
* item
= gamedata
->GetItem(ResRef
);
6822 Py_INCREF( Py_None
);
6826 PyObject
* dict
= PyDict_New();
6827 PyDict_SetItemString(dict
, "ItemName", PyInt_FromLong ((signed) item
->GetItemName(false)));
6828 PyDict_SetItemString(dict
, "ItemNameIdentified", PyInt_FromLong ((signed) item
->GetItemName(true)));
6829 PyDict_SetItemString(dict
, "ItemDesc", PyInt_FromLong ((signed) item
->GetItemDesc(false)));
6830 PyDict_SetItemString(dict
, "ItemDescIdentified", PyInt_FromLong ((signed)item
->GetItemDesc(true)));
6831 PyDict_SetItemString(dict
, "ItemIcon", PyString_FromResRef (item
->ItemIcon
));
6832 PyDict_SetItemString(dict
, "DescIcon", PyString_FromResRef (item
->DescriptionIcon
));
6833 PyDict_SetItemString(dict
, "BrokenItem", PyString_FromResRef (item
->ReplacementItem
));
6834 PyDict_SetItemString(dict
, "StackAmount", PyInt_FromLong (item
->StackAmount
));
6835 PyDict_SetItemString(dict
, "Dialog", PyString_FromResRef (item
->Dialog
));
6836 PyDict_SetItemString(dict
, "DialogName", PyInt_FromLong ((signed)item
->DialogName
));
6837 PyDict_SetItemString(dict
, "Price", PyInt_FromLong (item
->Price
));
6838 PyDict_SetItemString(dict
, "Type", PyInt_FromLong (item
->ItemType
));
6839 PyDict_SetItemString(dict
, "AnimationType", PyString_FromAnimID(item
->AnimationType
));
6840 PyDict_SetItemString(dict
, "Exclusion", PyInt_FromLong(item
->ItemExcl
));
6841 PyDict_SetItemString(dict
, "LoreToID", PyInt_FromLong(item
->LoreToID
));
6843 int ehc
= item
->ExtHeaderCount
;
6845 PyObject
* tooltiptuple
= PyTuple_New(ehc
);
6846 for(int i
=0;i
<ehc
;i
++) {
6847 int tip
= core
->GetItemTooltip(ResRef
, i
, 1);
6848 PyTuple_SetItem(tooltiptuple
, i
, PyInt_FromLong(tip
));
6851 PyDict_SetItemString(dict
, "Tooltips", tooltiptuple
);
6855 if (core
->CanUseItemType(SLOT_POTION
, item
, actor
, false) ) {
6856 function
|=CAN_DRINK
;
6858 if (core
->CanUseItemType(SLOT_SCROLL
, item
, actor
, false) ) {
6861 //determining if this is a copyable scroll
6865 eh
= item
->ext_headers
+1;
6866 if (eh
->FeatureCount
<1) {
6869 f
= eh
->features
; //+0
6871 //normally the learn spell opcode is 147
6872 EffectQueue::ResolveEffect(fx_learn_spell_ref
);
6873 if (f
->Opcode
!=(ieDword
) fx_learn_spell_ref
.opcode
) {
6876 //maybe further checks for school exclusion?
6877 //no, those were done by CanUseItemType
6879 PyDict_SetItemString(dict
, "Spell", PyString_FromResRef (f
->Resource
));
6881 function
|=CAN_SELECT
;
6884 if (core
->CanUseItemType(SLOT_BAG
, item
, NULL
, false) ) {
6885 //allow the open container flag only if there is
6886 //a store file (this fixes pst eye items, which
6887 //got the same item type as bags)
6888 //while this isn't required anymore, as bag itemtypes are customisable
6889 //we still better check for the existence of the store, or we
6890 //get a crash somewhere.
6891 if (gamedata
->Exists( ResRef
, IE_STO_CLASS_ID
) ) {
6892 function
|=CAN_STUFF
;
6895 PyDict_SetItemString(dict
, "Function", PyInt_FromLong(function
));
6896 gamedata
->FreeItem( item
, ResRef
, false );
6900 void DragItem(CREItem
*si
)
6905 Item
*item
= gamedata
->GetItem (si
->ItemResRef
);
6909 core
->DragItem(si
, item
->ItemIcon
);
6910 gamedata
->FreeItem( item
, si
->ItemResRef
, false );
6913 int CheckRemoveItem(Actor
*actor
, CREItem
*si
)
6915 ///check if item is undroppable because the actor likes it
6916 if (UsedItemsCount
==-1) {
6919 unsigned int i
=UsedItemsCount
;
6922 if (UsedItems
[i
].itemname
[0] && strnicmp(UsedItems
[i
].itemname
, si
->ItemResRef
,8) ) {
6925 if (UsedItems
[i
].username
[0] && strnicmp(UsedItems
[i
].username
, actor
->GetScriptName(), 32) ) {
6928 core
->DisplayString(UsedItems
[i
].value
,0xffffff, IE_STR_SOUND
);
6934 CREItem
*TryToUnequip(Actor
*actor
, unsigned int Slot
, unsigned int Count
)
6936 //we should use getslotitem, because
6937 //getitem would remove the item from the inventory!
6938 CREItem
*si
= actor
->inventory
.GetSlotItem(Slot
);
6943 //it is always possible to put these items into the inventory
6944 if (!(core
->QuerySlotType(Slot
)&SLOT_INVENTORY
)) {
6945 if (CheckRemoveItem(actor
, si
)) {
6949 ///fixme: make difference between cursed/unmovable
6950 if (! actor
->inventory
.UnEquipItem( Slot
, false )) {
6951 // Item is currently undroppable/cursed
6952 core
->DisplayConstantString(STR_CANT_DROP_ITEM
,0xffffff);
6955 si
= actor
->inventory
.RemoveItem( Slot
, Count
);
6959 PyDoc_STRVAR( GemRB_DragItem__doc
,
6960 "DragItem(PartyID, Slot, ResRef, [Count=0, Type])\n\n"
6961 "Start dragging specified item, if Slot is negative, drag the PartyID portrait instead." );
6963 static PyObject
* GemRB_DragItem(PyObject
* /*self*/, PyObject
* args
)
6966 int PartyID
, Slot
, Count
= 0, Type
= 0;
6969 if (!PyArg_ParseTuple( args
, "iis|ii", &PartyID
, &Slot
, &ResRef
, &Count
, &Type
)) {
6970 return AttributeError( GemRB_DragItem__doc
);
6974 // we should Drop the Dragged item in place of the current item
6975 // but only if the current item is draggable, tough!
6976 if (core
->GetDraggedItem()) {
6977 Py_INCREF( Py_None
);
6981 Game
*game
= core
->GetGame();
6983 return RuntimeError( "No game loaded!" );
6985 Actor
* actor
= game
->FindPC( PartyID
);
6987 if (!actor
&& ( PartyID
|| ResRef
[0]) ) {
6988 return RuntimeError( "Actor not found" );
6991 //dragging a portrait
6993 core
->SetDraggedPortrait(PartyID
, Slot
);
6994 Py_INCREF( Py_None
);
6998 if ((unsigned int) Slot
>core
->GetInventorySize()) {
6999 return AttributeError( "Invalid slot" );
7003 Map
*map
= actor
->GetCurrentArea();
7004 Container
*cc
= map
->GetPile(actor
->Pos
);
7006 return RuntimeError( "No current container" );
7008 si
= cc
->RemoveItem(Slot
, Count
);
7010 si
= TryToUnequip( actor
, core
->QuerySlot(Slot
), Count
);
7011 actor
->RefreshEffects(NULL
);
7012 printf("Actor ac:%d\n", actor
->Modified
[IE_ARMORCLASS
]);
7013 actor
->ReinitQuickSlots();
7014 core
->SetEventFlag(EF_SELECTION
);
7017 Py_INCREF( Py_None
);
7021 Item
*item
= gamedata
->GetItem(si
->ItemResRef
);
7023 if (core
->HasFeature(GF_HAS_PICK_SOUND
) && item
->DescriptionIcon
[0]) {
7024 memcpy(Sound
,item
->DescriptionIcon
,sizeof(ieResRef
));
7026 GetItemSound(Sound
, item
->ItemType
, item
->AnimationType
, IS_GET
);
7028 gamedata
->FreeItem(item
, si
->ItemResRef
,0);
7031 core
->GetAudioDrv()->Play(Sound
);
7034 //if res is positive, it is gold!
7035 int res
= core
->CanMoveItem(si
);
7039 Py_INCREF( Py_None
);
7043 core
->DragItem (si
, ResRef
);
7044 Py_INCREF( Py_None
);
7048 PyDoc_STRVAR( GemRB_DropDraggedItem__doc
,
7049 "DropDraggedItem(PartyID, Slot)=>int\n\n"
7050 "Put currently dragged item to specified PC and slot. "
7051 "If Slot==-1, puts it to a first usable slot. "
7052 "If Slot==-2, puts it to a ground pile. "
7053 "If Slot==-3, puts it to the first empty inventory slot. "
7054 "Returns 0 (unsuccessful), 1 (partial success) or 2 (complete success)."
7055 "Can also return 3 (swapped item)\n" );
7057 static PyObject
* GemRB_DropDraggedItem(PyObject
* /*self*/, PyObject
* args
)
7062 if (!PyArg_ParseTuple( args
, "ii", &PartyID
, &Slot
)) {
7063 return AttributeError( GemRB_DropDraggedItem__doc
);
7067 if (core
->GetDraggedItem() == NULL
) {
7068 Py_INCREF( Py_None
);
7072 Game
*game
= core
->GetGame();
7074 return RuntimeError( "No game loaded!" );
7076 Actor
* actor
= game
->FindPC( PartyID
);
7078 return RuntimeError( "Actor not found" );
7084 Map
*map
= actor
->GetCurrentArea();
7085 Container
*cc
= map
->GetPile(actor
->Pos
);
7087 return RuntimeError( "No current container" );
7089 CREItem
*si
= core
->GetDraggedItem();
7090 res
= cc
->AddItem(si
);
7091 Item
*item
= gamedata
->GetItem(si
->ItemResRef
);
7093 if (core
->HasFeature(GF_HAS_PICK_SOUND
) && item
->ReplacementItem
[0]) {
7094 memcpy(Sound
,item
->ReplacementItem
,sizeof(ieResRef
));
7096 GetItemSound(Sound
, item
->ItemType
, item
->AnimationType
, IS_DROP
);
7098 gamedata
->FreeItem(item
, si
->ItemResRef
,0);
7100 core
->GetAudioDrv()->Play(Sound
);
7104 // Whole amount was placed
7105 core
->ReleaseDraggedItem ();
7107 return PyInt_FromLong( res
);
7110 int Slottype
, Effect
;
7113 //anything but inventory
7114 Slottype
= ~SLOT_INVENTORY
;
7123 Slot
= core
->QuerySlot(Slot
);
7124 Slottype
= core
->QuerySlotType( Slot
);
7125 Effect
= core
->QuerySlotEffects( Slot
);
7127 CREItem
* slotitem
= core
->GetDraggedItem();
7128 Item
*item
= gamedata
->GetItem( slotitem
->ItemResRef
);
7130 return PyInt_FromLong( -1 );
7133 // can't equip item because of similar already equipped
7135 if (item
->ItemExcl
& actor
->inventory
.GetEquipExclusion(Slot
)) {
7136 core
->DisplayConstantString(STR_ITEMEXCL
, 0xf0f0f0);
7137 //freeing the item before returning
7138 gamedata
->FreeItem( item
, slotitem
->ItemResRef
, false );
7139 return PyInt_FromLong( 0 );
7143 // can't equip item because it is not identified
7144 if ( (Slottype
== SLOT_ITEM
) && !(slotitem
->Flags
&IE_INV_ITEM_IDENTIFIED
)) {
7145 ITMExtHeader
*eh
= item
->GetExtHeader(0);
7146 if (eh
&& eh
->IDReq
) {
7147 core
->DisplayConstantString(STR_ITEMID
, 0xf0f0f0);
7148 gamedata
->FreeItem( item
, slotitem
->ItemResRef
, false );
7149 return PyInt_FromLong( 0 );
7153 //CanUseItemType will check actor's class bits too
7154 Slottype
= core
->CanUseItemType (Slottype
, item
, actor
, true);
7155 //resolve the equipping sound, it needs to be resolved before
7157 if (core
->HasFeature(GF_HAS_PICK_SOUND
) && item
->ReplacementItem
[0]) {
7158 memcpy(Sound
, item
->ReplacementItem
, 9);
7160 GetItemSound(Sound
, item
->ItemType
, item
->AnimationType
, IS_DROP
);
7163 //freeing the item before returning
7164 gamedata
->FreeItem( item
, slotitem
->ItemResRef
, false );
7166 return PyInt_FromLong( 0 );
7168 res
= actor
->inventory
.AddSlotItem( slotitem
, Slot
, Slottype
);
7170 //release it only when fully placed
7171 if (res
==ASI_SUCCESS
) {
7172 core
->ReleaseDraggedItem ();
7174 //EquipItem (in AddSlotItem) already called RefreshEffects
7175 actor
->ReinitQuickSlots();
7176 //couldn't place item there, try swapping (only if slot is explicit)
7177 } else if ( Slot
>= 0 ) {
7178 //swapping won't cure this
7179 res
= actor
->inventory
.WhyCantEquip(Slot
, slotitem
->Flags
&IE_INV_ITEM_TWOHANDED
);
7181 core
->DisplayConstantString(res
,0xffffff);
7182 return PyInt_FromLong( 0 );
7184 CREItem
*tmp
= TryToUnequip(actor
, Slot
, 0 );
7186 //this addslotitem MUST succeed because the slot was
7187 //just emptied (canuseitemtype already confirmed too)
7188 actor
->inventory
.AddSlotItem( slotitem
, Slot
, Slottype
);
7189 core
->ReleaseDraggedItem ();
7191 // switched items, not returned by normal AddSlotItem
7193 //EquipItem (in AddSlotItem) already called RefreshEffects
7194 actor
->RefreshEffects(NULL
);
7195 actor
->ReinitQuickSlots();
7196 core
->SetEventFlag(EF_SELECTION
);
7202 core
->GetAudioDrv()->Play(Sound
);
7204 return PyInt_FromLong( res
);
7207 PyDoc_STRVAR( GemRB_IsDraggingItem__doc
,
7208 "IsDraggingItem()=>int\n\n"
7209 "Returns 1 if we are dragging some item.\n"
7210 "Returns 2 if we are dragging a portrait." );
7212 static PyObject
* GemRB_IsDraggingItem(PyObject
* /*self*/, PyObject
* /*args*/)
7214 if (core
->GetDraggedPortrait()) {
7215 return PyInt_FromLong(2);
7217 return PyInt_FromLong( core
->GetDraggedItem() != NULL
);
7220 PyDoc_STRVAR( GemRB_GetSystemVariable__doc
,
7221 "GetSystemVariable(Variable)=>int\n\n"
7222 "Returns the named Interface attribute." );
7224 static PyObject
* GemRB_GetSystemVariable(PyObject
* /*self*/, PyObject
* args
)
7226 int Variable
, value
;
7228 if (!PyArg_ParseTuple( args
, "i", &Variable
)) {
7229 return AttributeError( GemRB_GetSystemVariable__doc
);
7232 case SV_BPP
: value
= core
->Bpp
; break;
7233 case SV_WIDTH
: value
= core
->Width
; break;
7234 case SV_HEIGHT
: value
= core
->Height
; break;
7235 default: value
= -1; break;
7237 return PyInt_FromLong( value
);
7240 PyDoc_STRVAR( GemRB_CreateItem__doc
,
7241 "CreateItem(PartyID, ItemResRef, [SlotID, Charge0, Charge1, Charge2])\n\n"
7242 "Creates Item in the inventory of the player character.");
7244 static PyObject
* GemRB_CreateItem(PyObject
* /*self*/, PyObject
* args
)
7248 int Charge0
=1,Charge1
=0,Charge2
=0;
7249 const char *ItemResRef
;
7251 if (!PyArg_ParseTuple( args
, "is|iiii", &PartyID
, &ItemResRef
, &SlotID
, &Charge0
, &Charge1
, &Charge2
)) {
7252 return AttributeError( GemRB_CreateItem__doc
);
7254 Game
*game
= core
->GetGame();
7256 return RuntimeError( "No game loaded!" );
7258 Actor
* actor
= game
->FindPC( PartyID
);
7260 return RuntimeError( "Actor not found" );
7264 //This is already a slot ID we need later
7265 SlotID
=actor
->inventory
.FindCandidateSlot(SLOT_INVENTORY
,0);
7267 //I believe we need this only here
7268 SlotID
= core
->QuerySlot(SlotID
);
7272 // Create item on ground
7273 Map
*map
= actor
->GetCurrentArea();
7275 CREItem
*item
= CreateCreItem(ItemResRef
, Charge0
, Charge1
, Charge2
);
7277 map
->AddItemToLocation(actor
->Pos
, item
);
7281 // Note: this forcefully gets rid of any item currently
7282 // in the slot without properly unequipping it
7283 actor
->inventory
.SetSlotItemRes( ItemResRef
, SlotID
, Charge0
, Charge1
, Charge2
);
7284 actor
->inventory
.EquipItem(SlotID
);
7285 //EquipItem already called RefreshEffects
7286 actor
->ReinitQuickSlots();
7288 Py_INCREF( Py_None
);
7292 PyDoc_STRVAR( GemRB_SetMapnote__doc
,
7293 "SetMapnote(X, Y, color, Text)\n\n"
7294 "Adds or removes a mapnote.");
7296 static PyObject
* GemRB_SetMapnote(PyObject
* /*self*/, PyObject
* args
)
7300 const char *txt
=NULL
;
7302 if (!PyArg_ParseTuple( args
, "ii|is", &x
, &y
, &color
, &txt
)) {
7303 return AttributeError( GemRB_SetMapnote__doc
);
7305 Game
*game
= core
->GetGame();
7307 return RuntimeError( "No game loaded!" );
7309 Map
*map
= game
->GetCurrentArea();
7311 return RuntimeError( "No current area" );
7317 if (txt
&& txt
[0]) {
7318 char* newvalue
= ( char* ) malloc( strlen( txt
) + 1 ); //duplicating the string
7319 strcpy( newvalue
, txt
);
7320 MapNote
*old
= map
->GetMapNote(point
);
7321 if (old
) strref
= old
->strref
;
7322 else strref
= 0xffffffff;
7323 map
->AddMapNote(point
, color
, newvalue
, strref
);
7325 map
->RemoveMapNote(point
);
7327 Py_INCREF( Py_None
);
7331 PyDoc_STRVAR( GemRB_CreateCreature__doc
,
7332 "CreateCreature(PartyID, CreResRef)\n\n"
7333 "Creates Creature in vicinity of a player character.");
7335 static PyObject
* GemRB_CreateCreature(PyObject
* /*self*/, PyObject
* args
)
7338 const char *CreResRef
;
7340 if (!PyArg_ParseTuple( args
, "is", &PartyID
, &CreResRef
)) {
7341 return AttributeError( GemRB_CreateCreature__doc
);
7344 Game
*game
= core
->GetGame();
7346 return RuntimeError( "No game loaded!" );
7348 Actor
* actor
= game
->FindPC( PartyID
);
7350 return RuntimeError( "Actor not found" );
7352 Map
*map
=game
->GetCurrentArea();
7354 return RuntimeError( "No current area" );
7357 map
->SpawnCreature(actor
->Pos
, CreResRef
, 10);
7358 Py_INCREF( Py_None
);
7362 PyDoc_STRVAR( GemRB_RevealArea__doc
,
7363 "RevealArea(x, y, radius, type)\n\n"
7364 "Reveals part of the area.");
7366 static PyObject
* GemRB_RevealArea(PyObject
* /*self*/, PyObject
* args
)
7372 if (!PyArg_ParseTuple( args
, "iiii", &x
, &y
, &radius
, &Value
)) {
7373 return AttributeError( GemRB_RevealArea__doc
);
7377 Game
*game
= core
->GetGame();
7379 return RuntimeError( "No game loaded!" );
7381 Map
*map
=game
->GetCurrentArea();
7383 return RuntimeError( "No current area" );
7385 map
->ExploreMapChunk( p
, radius
, Value
);
7387 Py_INCREF( Py_None
);
7391 PyDoc_STRVAR( GemRB_ExploreArea__doc
,
7392 "ExploreArea([bitvalue=-1])\n\n"
7393 "Explores or unexplores whole area.");
7395 static PyObject
* GemRB_ExploreArea(PyObject
* /*self*/, PyObject
* args
)
7399 if (!PyArg_ParseTuple( args
, "|i", &Value
)) {
7400 return AttributeError( GemRB_ExploreArea__doc
);
7402 Game
*game
= core
->GetGame();
7404 return RuntimeError( "No game loaded!" );
7406 Map
*map
=game
->GetCurrentArea();
7408 return RuntimeError( "No current area" );
7410 map
->Explore( Value
);
7412 Py_INCREF( Py_None
);
7417 PyDoc_STRVAR( GemRB_GetRumour__doc
,
7418 "GetRumour(percent, ResRef) => ieStrRef\n\n"
7419 "Returns a string to a rumour message. ResRef is a dialog resource.");
7421 static PyObject
* GemRB_GetRumour(PyObject
* /*self*/, PyObject
* args
)
7426 if (!PyArg_ParseTuple( args
, "is", &percent
, &ResRef
)) {
7427 return AttributeError( GemRB_GetRumour__doc
);
7429 if (rand()%100 >= percent
) {
7430 return PyInt_FromLong( -1 );
7433 ieStrRef strref
= core
->GetRumour( ResRef
);
7434 return PyInt_FromLong( strref
);
7437 PyDoc_STRVAR( GemRB_GamePause__doc
,
7438 "GamePause(Pause, Quiet)\n\n"
7439 "Pause or unpause the game or just toggle the pause.");
7441 static PyObject
* GemRB_GamePause(PyObject
* /*self*/, PyObject
* args
)
7445 if (!PyArg_ParseTuple( args
, "ii", &pause
, &quiet
)) {
7446 return AttributeError( GemRB_GamePause__doc
);
7449 GameControl
*gc
= core
->GetGameControl();
7451 //this will trigger when pause is not 0 or 1
7452 if ((unsigned int) pause
> 1) {
7453 pause
= ~gc
->GetDialogueFlags()&DF_FREEZE_SCRIPTS
;
7457 gc
->SetDialogueFlags(DF_FREEZE_SCRIPTS
, BM_OR
);
7459 gc
->SetDialogueFlags(DF_FREEZE_SCRIPTS
, BM_NAND
);
7462 if (gc
->GetDialogueFlags()&DF_FREEZE_SCRIPTS
) {
7463 core
->DisplayConstantString(STR_PAUSED
,0xff0000);
7465 core
->DisplayConstantString(STR_UNPAUSED
,0xff0000);
7470 Py_INCREF( Py_None
);
7474 PyDoc_STRVAR( GemRB_CheckFeatCondition__doc
,
7475 "CheckFeatCondition(partyslot, a_stat, a_value, b_stat, b_value, c_stat, c_value, d_stat, d_value[,a_op, b_op, c_op, d_op]) => bool\n\n"
7476 "Checks if actor in partyslot is eligible for a feat, the formula is: (stat[a]~a or stat[b]~b) and (stat[c]~c or stat[d]~d). Where ~ is a relational operator. If the operators are omitted, the default operator is <=.");
7478 static PyObject
* GemRB_CheckFeatCondition(PyObject
* /*self*/, PyObject
* args
)
7481 const char *callback
= NULL
;
7486 v
[i
]=GREATER_OR_EQUALS
;
7489 if (!PyArg_UnpackTuple( args
, "ref", 9, 13, &p
[0], &p
[1], &p
[2], &p
[3], &p
[4], &p
[5], &p
[6], &p
[7], &p
[8], &p
[9], &p
[10], &p
[11], &p
[12] )) {
7490 return AttributeError( GemRB_CheckFeatCondition__doc
);
7493 if (!PyObject_TypeCheck( p
[0], &PyInt_Type
)) {
7494 return AttributeError( GemRB_CheckFeatCondition__doc
);
7496 v
[0]=PyInt_AsLong( p
[0] ); //slot
7498 if (PyObject_TypeCheck( p
[1], &PyInt_Type
)) {
7499 v
[1]=PyInt_AsLong( p
[1] ); //a_stat
7501 if (!PyObject_TypeCheck( p
[1], &PyString_Type
)) {
7502 return AttributeError( GemRB_CheckFeatCondition__doc
);
7504 callback
= PyString_AsString( p
[1] ); // callback
7505 if (callback
== NULL
) {
7506 return RuntimeError("Null string received");
7509 v
[0]=PyInt_AsLong( p
[0] );
7512 if (!PyObject_TypeCheck( p
[i
], &PyInt_Type
)) {
7513 return AttributeError( GemRB_CheckFeatCondition__doc
);
7515 v
[i
]=PyInt_AsLong( p
[i
] );
7520 if (!PyObject_TypeCheck( p
[i
], &PyInt_Type
)) {
7521 return AttributeError( GemRB_CheckFeatCondition__doc
);
7523 v
[i
]=PyInt_AsLong( p
[i
] );
7527 Game
*game
= core
->GetGame();
7529 return RuntimeError( "No game loaded!" );
7532 Actor
*actor
= core
->GetGame()->FindPC(v
[0]);
7534 return RuntimeError( "Actor not found" );
7537 /* see if the special function exists */
7541 snprintf(fname
, 32, "Check_%s", callback
);
7542 PyObject
* param
= PyTuple_New( 11 );
7543 PyTuple_SetItem( param
, 0, PyInt_FromLong(v
[0]) );
7544 for (i
= 3;i
<13;i
++) {
7545 PyTuple_SetItem( param
, i
-2, PyInt_FromLong( v
[i
] ) );
7548 PyObject
*pValue
= gs
->CallbackFunction(fname
, param
);
7550 /* we created this parameter, now we don't need it*/
7553 /* don't think we need any incref */
7556 return RuntimeError( "Callback failed" );
7562 ret
= CheckStat(actor
, v
[1], v
[2], v
[9]);
7565 ret
|= CheckStat(actor
, v
[3], v
[4], v
[10]);
7571 // no | because the formula is (a|b) & (c|d)
7572 ret
= CheckStat(actor
, v
[5], v
[6], v
[11]);
7575 ret
|= CheckStat(actor
, v
[7], v
[8], v
[12]);
7579 Py_INCREF( Py_True
);
7582 Py_INCREF( Py_False
);
7587 PyDoc_STRVAR( GemRB_GetAbilityBonus__doc
,
7588 "GetAbilityBonus(stat, column, value[, ex])\n\n"
7589 "Returns an ability bonus value based on various .2da files.");
7591 static PyObject
* GemRB_GetAbilityBonus(PyObject
* /*self*/, PyObject
* args
)
7593 int stat
, column
, value
, ex
= 0;
7596 if (!PyArg_ParseTuple( args
, "iii|i", &stat
, &column
, &value
, &ex
)) {
7597 return AttributeError( GemRB_GetAbilityBonus__doc
);
7600 Game
*game
= core
->GetGame();
7602 return RuntimeError( "No game loaded!" );
7604 Actor
*actor
= game
->FindPC(game
->GetSelectedPCSingle());
7606 return RuntimeError( "Actor not found" );
7611 ret
=core
->GetStrengthBonus(column
, value
, ex
);
7614 ret
=core
->GetIntelligenceBonus(column
, value
);
7617 ret
=core
->GetDexterityBonus(column
, value
);
7620 ret
=core
->GetConstitutionBonus(column
, value
);
7623 ret
=core
->GetCharismaBonus(column
, value
);
7626 ret
=core
->GetLoreBonus(column
, value
);
7628 case IE_REPUTATION
: //both chr and reputation affect the reaction, but chr is already taken
7629 ret
=GetReaction(actor
, NULL
); // this is used only for display, so the null is fine
7632 ret
=core
->GetWisdomBonus(column
, value
);
7635 return RuntimeError( "Invalid ability!");
7637 return PyInt_FromLong( ret
);
7640 PyDoc_STRVAR( GemRB_LeaveParty__doc
,
7641 "LeaveParty(Slot [,dialog])\n\n"
7642 "Makes player in Slot leave party, and initiate dialog if demanded." );
7644 static PyObject
* GemRB_LeaveParty(PyObject
* /*self*/, PyObject
* args
)
7646 int PlayerSlot
, initDialog
;
7648 if (!PyArg_ParseTuple( args
, "i|i", &PlayerSlot
, &initDialog
)) {
7649 return AttributeError( GemRB_LeaveParty__doc
);
7651 Game
*game
= core
->GetGame();
7653 return RuntimeError( "No game loaded!" );
7655 Actor
*actor
= game
->FindPC(PlayerSlot
);
7657 return RuntimeError( "Actor not found" );
7661 if (initDialog
== 2)
7662 GameScript::SetLeavePartyDialogFile(actor
, NULL
);
7663 if(actor
->GetBase(IE_HITPOINTS
) > 0) {
7666 actor
->ClearActions();
7667 strncpy(Tmp
,"Dialogue([PC])",sizeof(Tmp
) );
7668 actor
->AddAction( GenerateAction(Tmp
) );
7671 game
->LeaveParty (actor
);
7673 Py_INCREF( Py_None
);
7677 typedef union pack
{
7682 static void ReadActionButtons()
7686 memset(GUIAction
, -1, sizeof(GUIAction
));
7687 memset(GUITooltip
, -1, sizeof(GUITooltip
));
7688 memset(GUIResRef
, 0, sizeof(GUIResRef
));
7689 memset(GUIEvent
, 0, sizeof(GUIEvent
));
7690 int table
= gamedata
->LoadTable( "guibtact" );
7694 Holder
<TableMgr
> tab
= gamedata
->GetTable( table
);
7695 for (i
= 0; i
< MAX_ACT_COUNT
; i
++) {
7698 row
.bytes
[0] = (ieByte
) atoi( tab
->QueryField(i
,0) );
7699 row
.bytes
[1] = (ieByte
) atoi( tab
->QueryField(i
,1) );
7700 row
.bytes
[2] = (ieByte
) atoi( tab
->QueryField(i
,2) );
7701 row
.bytes
[3] = (ieByte
) atoi( tab
->QueryField(i
,3) );
7702 GUIAction
[i
] = row
.data
;
7703 GUITooltip
[i
] = atoi( tab
->QueryField(i
,4) );
7704 strnlwrcpy(GUIResRef
[i
], tab
->QueryField(i
,5), 8);
7705 strncpy(GUIEvent
[i
], tab
->GetRowName(i
), 16);
7707 gamedata
->DelTable( table
);
7710 static void SetButtonCycle(AnimationFactory
*bam
, Button
*btn
, int cycle
, unsigned char which
)
7712 Sprite2D
*tspr
= bam
->GetFrame( cycle
, 0 );
7713 btn
->SetImage( which
, tspr
);
7716 PyDoc_STRVAR( GemRB_Button_SetActionIcon__doc
,
7717 "SetActionIcon(Window, Button, ActionIndex[, Function])\n\n"
7718 "Sets up an action button. The ActionIndex should be less than 34." );
7720 static PyObject
* SetActionIcon(int WindowIndex
, int ControlIndex
, int Index
, int Function
)
7722 if (ControlIndex
>99) {
7723 return AttributeError( GemRB_Button_SetActionIcon__doc
);
7725 if (Index
>=MAX_ACT_COUNT
) {
7726 return AttributeError( GemRB_Button_SetActionIcon__doc
);
7728 Button
* btn
= ( Button
* ) GetControl(WindowIndex
, ControlIndex
, IE_GUI_BUTTON
);
7734 btn
->SetImage( IE_GUI_BUTTON_UNPRESSED
, 0 );
7735 btn
->SetImage( IE_GUI_BUTTON_PRESSED
, 0 );
7736 btn
->SetImage( IE_GUI_BUTTON_SELECTED
, 0 );
7737 btn
->SetImage( IE_GUI_BUTTON_DISABLED
, 0 );
7738 btn
->SetFlags( IE_GUI_BUTTON_NO_IMAGE
, BM_SET
);
7739 btn
->SetEvent( IE_GUI_BUTTON_ON_PRESS
, NULL
);
7740 core
->SetTooltip( (ieWord
) WindowIndex
, (ieWord
) ControlIndex
, "" );
7745 if (GUIAction
[0]==0xcccccccc) {
7746 ReadActionButtons();
7750 //FIXME: this is a hardcoded resource (pst has no such one)
7751 AnimationFactory
* bam
= ( AnimationFactory
* )
7752 gamedata
->GetFactoryResource( GUIResRef
[Index
],
7753 IE_BAM_CLASS_ID
, IE_NORMAL
);
7755 return RuntimeError( "BAM not found" );
7759 row
.data
= GUIAction
[Index
];
7760 SetButtonCycle(bam
, btn
, (char) row
.bytes
[0], IE_GUI_BUTTON_UNPRESSED
);
7761 SetButtonCycle(bam
, btn
, (char) row
.bytes
[1], IE_GUI_BUTTON_PRESSED
);
7762 SetButtonCycle(bam
, btn
, (char) row
.bytes
[2], IE_GUI_BUTTON_SELECTED
);
7763 SetButtonCycle(bam
, btn
, (char) row
.bytes
[3], IE_GUI_BUTTON_DISABLED
);
7764 btn
->SetFlags( IE_GUI_BUTTON_NO_IMAGE
|IE_GUI_BUTTON_PICTURE
, BM_NAND
);
7766 snprintf(Event
,sizeof(Event
)-1, "Action%sPressed", GUIEvent
[Index
]);
7767 btn
->SetEvent( IE_GUI_BUTTON_ON_PRESS
, new StringCallback(Event
) );
7768 //cannot make this const, because it will be freed
7769 char *txt
= core
->GetString( GUITooltip
[Index
] );
7771 SetFunctionTooltip(WindowIndex
, ControlIndex
, txt
, Function
);
7776 static PyObject
* GemRB_Button_SetActionIcon(PyObject
* /*self*/, PyObject
* args
)
7778 int WindowIndex
, ControlIndex
, Index
;
7781 if (!PyArg_ParseTuple( args
, "iii|i", &WindowIndex
, &ControlIndex
, &Index
, &Function
)) {
7782 return AttributeError( GemRB_Button_SetActionIcon__doc
);
7785 PyObject
* ret
= SetActionIcon(WindowIndex
, ControlIndex
, Index
, Function
);
7792 PyDoc_STRVAR( GemRB_HasResource__doc
,
7793 "HasResource(ResRef, ResType)\n\n"
7794 "Returns true if resource is accessible." );
7796 static PyObject
* GemRB_HasResource(PyObject
* /*self*/, PyObject
* args
)
7802 if (!PyArg_ParseTuple( args
, "si|i", &ResRef
, &ResType
, &silent
)) {
7803 return AttributeError( GemRB_HasResource__doc
);
7805 if (gamedata
->Exists(ResRef
, ResType
, silent
)) {
7806 Py_INCREF( Py_True
);
7809 Py_INCREF( Py_False
);
7814 PyDoc_STRVAR( GemRB_Window_SetupEquipmentIcons__doc
,
7815 "SetupEquipmentIcons(WindowIndex, slot[, Start, Offset])\n\n"
7816 "Automagically sets up the controls of the equipment list window for a PC indexed by slot.\n"
7817 "Start is the beginning of the visible part of the item list.\n"
7818 "Offset is the ID of the first usable button.");
7820 static PyObject
* GemRB_Window_SetupEquipmentIcons(PyObject
* /*self*/, PyObject
* args
)
7824 int Offset
= 0; //control offset (iwd2 has the action buttons starting at 6)
7826 if (!PyArg_ParseTuple( args
, "ii|ii", &wi
, &slot
, &Start
, &Offset
)) {
7827 return AttributeError( GemRB_Window_SetupEquipmentIcons__doc
);
7830 Game
*game
= core
->GetGame();
7832 return RuntimeError( "No game loaded!" );
7834 Actor
* actor
= game
->FindPC( slot
);
7836 return RuntimeError( "Actor not found" );
7839 //-2 because of the left/right scroll icons
7841 ItemArray
= (ItemExtHeader
*) malloc((GUIBT_COUNT
) * sizeof (ItemExtHeader
) );
7843 bool more
= actor
->inventory
.GetEquipmentInfo(ItemArray
, Start
, GUIBT_COUNT
-(Start
?1:0));
7846 PyObject
*ret
= SetActionIcon(wi
,core
->GetControl(wi
, Offset
),ACT_LEFT
,0);
7848 return RuntimeError("Cannot set action button!\n");
7851 //FIXME: this is a hardcoded resource (pst has no such one)
7852 AnimationFactory
* bam
= ( AnimationFactory
* )
7853 gamedata
->GetFactoryResource( "guibtbut",
7854 IE_BAM_CLASS_ID
, IE_NORMAL
);
7856 return RuntimeError( "BAM not found" );
7859 for (i
=0;i
<GUIBT_COUNT
-(more
?1:0);i
++) {
7860 int ci
= core
->GetControl(wi
, i
+Offset
+(Start
?1:0) );
7861 Button
* btn
= (Button
*) GetControl( wi
, ci
, IE_GUI_BUTTON
);
7862 btn
->SetEvent(IE_GUI_BUTTON_ON_PRESS
, new StringCallback("EquipmentPressed"));
7863 strcpy(btn
->VarName
,"Equipment");
7864 btn
->Value
= Start
+i
;
7866 ItemExtHeader
*item
= ItemArray
+i
;
7867 Sprite2D
*Picture
= NULL
;
7869 if (item
->UseIcon
[0]) {
7870 Picture
= gamedata
->GetBAMSprite(item
->UseIcon
, 1, 0);
7874 btn
->SetState(IE_GUI_BUTTON_DISABLED
);
7875 btn
->SetFlags(IE_GUI_BUTTON_NO_IMAGE
, BM_SET
);
7876 btn
->SetTooltip(NULL
);
7878 SetButtonCycle(bam
, btn
, 0, IE_GUI_BUTTON_UNPRESSED
);
7879 SetButtonCycle(bam
, btn
, 1, IE_GUI_BUTTON_PRESSED
);
7880 SetButtonCycle(bam
, btn
, 2, IE_GUI_BUTTON_SELECTED
);
7881 SetButtonCycle(bam
, btn
, 3, IE_GUI_BUTTON_DISABLED
);
7882 btn
->SetPicture( Picture
);
7883 btn
->SetState(IE_GUI_BUTTON_UNPRESSED
);
7884 btn
->SetFlags(IE_GUI_BUTTON_PICTURE
|IE_GUI_BUTTON_ALIGN_BOTTOM
|IE_GUI_BUTTON_ALIGN_RIGHT
, BM_SET
);
7886 const CREItem
*item_slot
= actor
->inventory
.GetSlotItem(item
->slot
);
7887 int tip
= core
->GetItemTooltip(item
->itemname
, item
->headerindex
, item_slot
->Flags
&IE_INV_ITEM_IDENTIFIED
);
7889 //cannot make this const, because it will be freed
7890 char *tmp
= core
->GetString((ieStrRef
) tip
,0);
7891 btn
->SetTooltip(tmp
);
7892 core
->FreeString(tmp
);
7894 btn
->SetTooltip(NULL
);
7898 if (item
->Charges
&& (item
->Charges
!=0xffff) ) {
7899 sprintf(usagestr
,"%d", item
->Charges
);
7900 btn
->SetText( usagestr
);
7902 if (!item
->Charges
&& (item
->ChargeDepletion
==CHG_NONE
) ) {
7903 btn
->SetState(IE_GUI_BUTTON_DISABLED
);
7909 PyObject
*ret
= SetActionIcon(wi
,core
->GetControl(wi
, i
+Offset
+1),ACT_RIGHT
,i
+1);
7911 return RuntimeError("Cannot set action button!\n");
7915 Py_INCREF( Py_None
);
7919 PyDoc_STRVAR( GemRB_Window_SetupSpellIcons__doc
,
7920 "SetupSpellIcons(WindowIndex, slot, type[, Start, Offset])\n\n"
7921 "Automagically sets up the controls of the spell or innate list window for a PC indexed by slot.\n"
7922 "Start is the beginning of the visible part of the spell list.\n"
7923 "Offset is the ID of the first usable button.");
7925 static PyObject
* GemRB_Window_SetupSpellIcons(PyObject
* /*self*/, PyObject
* args
)
7931 if (!PyArg_ParseTuple( args
, "iii|ii", &wi
, &slot
, &Type
, &Start
, &Offset
)) {
7932 return AttributeError( GemRB_Window_SetupSpellIcons__doc
);
7935 Game
*game
= core
->GetGame();
7937 return RuntimeError( "No game loaded!" );
7939 Actor
* actor
= game
->FindPC( slot
);
7941 return RuntimeError( "Actor not found" );
7944 //-2 because of the left/right scroll icons
7946 SpellArray
= (SpellExtHeader
*) malloc((GUIBT_COUNT
) * sizeof (SpellExtHeader
) );
7948 int more
= actor
->spellbook
.GetSpellInfo(SpellArray
, Type
, Start
, GUIBT_COUNT
-(Start
?1:0));
7954 int ci
= core
->GetControl(wi
, Offset
);
7955 PyObject
*ret
= SetActionIcon(wi
, ci
, ACT_LEFT
, 0);
7957 return RuntimeError("Cannot set action button!\n");
7959 Button
* btn
= (Button
*) GetControl(wi
, ci
, IE_GUI_BUTTON
);
7961 btn
->SetState(IE_GUI_BUTTON_UNPRESSED
);
7963 btn
->SetState(IE_GUI_BUTTON_DISABLED
);
7967 //FIXME: this is a hardcoded resource (pst has no such one)
7968 AnimationFactory
* bam
= ( AnimationFactory
* )
7969 gamedata
->GetFactoryResource( "guibtbut",
7970 IE_BAM_CLASS_ID
, IE_NORMAL
);
7972 return RuntimeError( "BAM not found" );
7975 // disable all spells if fx_disable_spellcasting was run with the same type
7976 // but only if there are any spells of that type to disable
7977 int disabled_spellcasting
= actor
->fxqueue
.DisabledSpellcasting(7);
7979 for (i
=0;i
<GUIBT_COUNT
-(more
?2:0);i
++) {
7980 SpellExtHeader
*spell
= SpellArray
+i
;
7982 int ci
= core
->GetControl(wi
, i
+Offset
+(more
?1:0) );
7983 Button
* btn
= (Button
*) GetControl( wi
, ci
, IE_GUI_BUTTON
);
7984 strcpy(btn
->VarName
,"Spell");
7985 btn
->Value
= i
+Start
;
7987 // disable spells that should be cast from the inventory
7988 // Identify is misclassified and has Target 3 (Dead char)
7990 if (CheckSpecialSpell(spell
->spellname
, actor
) || (disabled_spellcasting
&(1<<spell
->type
)) ) {
7991 btn
->SetState(IE_GUI_BUTTON_DISABLED
);
7992 btn
->EnableBorder(1, IE_GUI_BUTTON_DISABLED
);
7993 btn
->SetEvent(IE_GUI_BUTTON_ON_PRESS
, new StringCallback("UpdateActionsWindow")); //noop
7995 btn
->SetState(IE_GUI_BUTTON_UNPRESSED
);
7996 btn
->SetEvent(IE_GUI_BUTTON_ON_PRESS
, new StringCallback("SpellPressed"));
7998 Sprite2D
*Picture
= NULL
;
8000 if (spell
->MemorisedIcon
[0]) {
8001 Picture
= gamedata
->GetBAMSprite(spell
->MemorisedIcon
, 0, 0);
8005 btn
->SetState(IE_GUI_BUTTON_DISABLED
);
8006 btn
->SetFlags(IE_GUI_BUTTON_NO_IMAGE
, BM_SET
);
8007 btn
->SetTooltip(NULL
);
8009 SetButtonCycle(bam
, btn
, 0, IE_GUI_BUTTON_UNPRESSED
);
8010 SetButtonCycle(bam
, btn
, 1, IE_GUI_BUTTON_PRESSED
);
8011 SetButtonCycle(bam
, btn
, 2, IE_GUI_BUTTON_SELECTED
);
8012 SetButtonCycle(bam
, btn
, 3, IE_GUI_BUTTON_DISABLED
);
8013 btn
->SetPicture( Picture
);
8014 btn
->SetFlags(IE_GUI_BUTTON_PICTURE
|IE_GUI_BUTTON_ALIGN_BOTTOM
|IE_GUI_BUTTON_ALIGN_RIGHT
, BM_SET
);
8015 //cannot make this const, because it will be freed
8016 char *tmp
= core
->GetString(spell
->strref
,0);
8017 btn
->SetTooltip(tmp
);
8018 core
->FreeString(tmp
);
8021 if (spell
->count
>0) {
8022 sprintf(usagestr
,"%d", spell
->count
);
8023 btn
->SetText( usagestr
);
8024 btn
->SetState(IE_GUI_BUTTON_UNPRESSED
);
8026 btn
->SetState(IE_GUI_BUTTON_DISABLED
);
8032 int ci
= core
->GetControl(wi
, i
+Offset
+1);
8033 PyObject
*ret
= SetActionIcon(wi
, ci
, ACT_RIGHT
, i
+1);
8035 return RuntimeError("Cannot set action button!\n");
8037 Button
* btn
= (Button
*) GetControl( wi
, ci
, IE_GUI_BUTTON
);
8039 btn
->SetState(IE_GUI_BUTTON_UNPRESSED
);
8041 btn
->SetState(IE_GUI_BUTTON_DISABLED
);
8042 btn
->SetFlags(IE_GUI_BUTTON_NO_IMAGE
, BM_SET
);
8043 btn
->SetTooltip(NULL
);
8047 Py_INCREF( Py_None
);
8051 PyDoc_STRVAR( GemRB_Window_SetupControls__doc
,
8052 "SetupControls(WindowIndex, slot[, Start])\n\n"
8053 "Automagically sets up the controls of the action window for a PC indexed by slot." );
8055 static PyObject
* GemRB_Window_SetupControls(PyObject
* /*self*/, PyObject
* args
)
8060 if (!PyArg_ParseTuple( args
, "ii|i", &wi
, &slot
, &Start
)) {
8061 return AttributeError( GemRB_Window_SetupControls__doc
);
8064 Game
*game
= core
->GetGame();
8066 return RuntimeError( "No game loaded!" );
8068 Actor
* actor
= game
->FindPC( slot
);
8070 return RuntimeError( "Actor not found" );
8073 ActionButtonRow myrow
;
8074 actor
->GetActionButtonRow(myrow
);
8075 bool fistdrawn
= true;
8076 ieDword magicweapon
= actor
->inventory
.GetMagicSlot();
8077 if (!actor
->inventory
.HasItemInSlot("",magicweapon
) ) {
8078 magicweapon
= 0xffff;
8080 ieDword fistweapon
= actor
->inventory
.GetFistSlot();
8081 ieDword usedslot
= actor
->inventory
.GetEquippedSlot();
8082 ieDword disabledbutton
= actor
->GetStat(IE_DISABLEDBUTTON
);
8084 for (int i
=0;i
<GUIBT_COUNT
;i
++) {
8085 int ci
= core
->GetControl(wi
, i
+Start
);
8087 printf("Couldn't find button #%d on Window #%d\n", i
+Start
, wi
);
8088 return RuntimeError ("No such control!\n");
8090 int action
= myrow
[i
];
8096 Button
* btn
= (Button
*) GetControl(wi
,ci
,IE_GUI_BUTTON
);
8100 btn
->SetFlags(IE_GUI_BUTTON_NO_IMAGE
|IE_GUI_BUTTON_ALIGN_BOTTOM
|IE_GUI_BUTTON_ALIGN_RIGHT
, BM_SET
);
8101 SetItemText(wi
, ci
, 0, false);
8102 PyObject
*ret
= SetActionIcon(wi
,ci
,action
,i
+1);
8104 int state
= IE_GUI_BUTTON_UNPRESSED
;
8105 ieDword modalstate
= actor
->ModalState
;
8109 if (actor
->spellbook
.IsIWDSpellBook()) {
8110 type
= IE_IWD2_SPELL_INNATE
;
8112 type
= IE_SPELL_TYPE_INNATE
;
8114 if (!actor
->spellbook
.GetMemorizedSpellsCount(type
)) {
8115 state
= IE_GUI_BUTTON_DISABLED
;
8119 //luckily the castable spells in IWD2 are all bits below INNATE, so we can do this trick
8120 if (actor
->spellbook
.IsIWDSpellBook()) {
8121 type
= (1<<IE_IWD2_SPELL_INNATE
)-1;
8123 type
= (1<<IE_SPELL_TYPE_INNATE
)-1;
8125 //returns true if there are ANY spells to cast
8126 if (!actor
->spellbook
.GetSpellInfoSize(type
)) {
8127 state
= IE_GUI_BUTTON_DISABLED
;
8131 if (actor
->spellbook
.IsIWDSpellBook()) {
8132 type
= 1<<IE_IWD2_SPELL_SHAPE
;
8134 type
= 0; //no separate shapes in old spellbook
8136 //returns true if there is ANY shape
8137 if (!actor
->spellbook
.GetSpellInfoSize(type
)) {
8138 state
= IE_GUI_BUTTON_DISABLED
;
8142 //returns true if there is ANY equipment
8143 if (!actor
->inventory
.GetEquipmentInfo(NULL
, 0, 0)) {
8144 state
= IE_GUI_BUTTON_DISABLED
;
8148 if (actor
->spellbook
.IsIWDSpellBook()) {
8149 type
= 1<<IE_IWD2_SPELL_SONG
;
8150 if (!actor
->spellbook
.GetSpellInfoSize(type
)) {
8151 state
= IE_GUI_BUTTON_DISABLED
;
8154 if (modalstate
==MS_BATTLESONG
) {
8155 state
= IE_GUI_BUTTON_SELECTED
;
8160 if (actor
->GetStat(IE_TURNUNDEADLEVEL
)<1) {
8161 state
= IE_GUI_BUTTON_DISABLED
;
8163 if (modalstate
==MS_TURNUNDEAD
) {
8164 state
= IE_GUI_BUTTON_SELECTED
;
8169 if (modalstate
==MS_STEALTH
) {
8170 state
= IE_GUI_BUTTON_SELECTED
;
8174 if (modalstate
==MS_DETECTTRAPS
) {
8175 state
= IE_GUI_BUTTON_SELECTED
;
8183 SetButtonBAM(wi
, ci
, "stonweap",0,0,-1);
8185 if (magicweapon
!=0xffff) {
8188 slot
= actor
->GetQuickSlot(action
-ACT_WEAPON1
);
8191 CREItem
*item
= actor
->inventory
.GetSlotItem(slot
);
8192 //no slot translation required
8193 int launcherslot
= actor
->inventory
.FindSlotRangedWeapon(slot
);
8194 const char* Item2ResRef
= 0;
8195 if (launcherslot
!= actor
->inventory
.GetFistSlot()) {
8196 // launcher/projectile in this slot
8198 item2
= actor
->inventory
.GetSlotItem(launcherslot
);
8199 Item2ResRef
= item2
->ItemResRef
;
8204 if (slot
== fistweapon
) {
8208 //empty weapon slot, already drawn
8212 SetItemIcon(wi
, ci
, item
->ItemResRef
,mode
,(item
->Flags
&IE_INV_ITEM_IDENTIFIED
)?2:1, i
+1, Item2ResRef
);
8213 SetItemText(wi
, ci
, item
->Usages
[actor
->PCStats
->QuickWeaponHeaders
[action
-ACT_WEAPON1
]], true);
8214 if (usedslot
== slot
) {
8215 btn
->EnableBorder(0, true);
8216 if (core
->GetGameControl()->target_mode
== TARGET_MODE_ATTACK
) {
8217 state
= IE_GUI_BUTTON_SELECTED
;
8219 state
= IE_GUI_BUTTON_THIRD
;
8222 btn
->EnableBorder(0, false);
8233 SetButtonBAM(wi
, ci
, "stonspel",0,0,-1);
8234 ieResRef
*poi
= &actor
->PCStats
->QuickSpells
[action
-ACT_QSPELL1
];
8236 SetSpellIcon(wi
, ci
, *poi
, 1, 1, i
+1);
8256 SetButtonBAM(wi
, ci
, "stonitem",0,0,-1);
8257 ieDword slot
= actor
->PCStats
->QuickItemSlots
[tmp
];
8259 //no slot translation required
8260 CREItem
*item
= actor
->inventory
.GetSlotItem(slot
);
8262 //MISC3H (horn of blasting) is not displayed when it is out of usages
8263 int header
= actor
->PCStats
->QuickItemHeaders
[tmp
];
8264 int usages
= item
->Usages
[header
];
8265 //I don't like this feature, if the goal is full IE compatibility
8266 //uncomment the next line.
8269 //SetItemIcon parameter needs header+6 to display extended header icons
8270 SetItemIcon(wi
, ci
, item
->ItemResRef
,header
+6,(item
->Flags
&IE_INV_ITEM_IDENTIFIED
)?2:1, i
+1, NULL
);
8271 SetItemText(wi
, ci
, usages
, false);
8281 return RuntimeError("Cannot set action button!\n");
8283 if (action
<0 || (disabledbutton
& (1<<action
) )) {
8284 state
= IE_GUI_BUTTON_DISABLED
;
8286 btn
->SetState(state
);
8287 //you have to set this overlay up
8288 btn
->EnableBorder(1, state
==IE_GUI_BUTTON_DISABLED
);
8290 Py_INCREF( Py_None
);
8294 PyDoc_STRVAR( GemRB_ClearActions__doc
,
8295 "ClearActions(slot)\n\n"
8296 "Stops an action for a PC indexed by slot." );
8298 static PyObject
* GemRB_ClearActions(PyObject
* /*self*/, PyObject
* args
)
8302 if (!PyArg_ParseTuple( args
, "i", &slot
)) {
8303 return AttributeError( GemRB_ClearActions__doc
);
8305 Game
*game
= core
->GetGame();
8307 return RuntimeError( "No game loaded!" );
8309 Actor
* actor
= game
->FindPC( slot
);
8311 return RuntimeError( "Actor not found" );
8313 if (actor
->GetInternalFlag()&IF_NOINT
) {
8314 printMessage( "GuiScript","Cannot break action", GREEN
);
8315 Py_INCREF( Py_None
);
8318 if (!(actor
->GetNextStep()) && !actor
->ModalState
) {
8319 printMessage( "GuiScript","No breakable action", GREEN
);
8320 Py_INCREF( Py_None
);
8323 actor
->ClearPath(); //stop walking
8324 actor
->ClearActions(); //stop pending action involved walking
8325 actor
->SetModal(MS_NONE
);//stop modal actions
8326 Py_INCREF( Py_None
);
8331 PyDoc_STRVAR( GemRB_SetDefaultActions__doc
,
8332 "SetDefaultActions(qslot, slot1, slot2, slot3)\n\n"
8333 "Sets whether qslots need an additional translation like in iwd2. "
8334 "Also sets up the first three default action types." );
8336 static PyObject
* GemRB_SetDefaultActions(PyObject
* /*self*/, PyObject
* args
)
8339 int slot1
, slot2
, slot3
;
8341 if (!PyArg_ParseTuple( args
, "iiii", &qslot
, &slot1
, &slot2
, &slot3
)) {
8342 return AttributeError( GemRB_SetDefaultActions__doc
);
8344 Actor::SetDefaultActions((bool) qslot
, (ieByte
) slot1
, (ieByte
) slot2
, (ieByte
) slot3
);
8345 Py_INCREF( Py_None
);
8349 PyDoc_STRVAR( GemRB_SetupQuickSlot__doc
,
8350 "SetupQuickSlot(PartyID, quickslot, inventoryslot, headerindex)\n\n"
8351 "Set up a quick slot or weapon slot of a PC to use a weapon ability.\n\n"
8352 "If the inventoryslot number is -1, only the header index will be changed. "
8353 "If the quick slot is 0, then the inventory slot will be used to find which "
8354 "headerindex should be set. The default value for headerindex is 0.");
8356 static PyObject
* GemRB_SetupQuickSlot(PyObject
* /*self*/, PyObject
* args
)
8358 int PartyID
, which
, slot
, headerindex
= 0;
8360 if (!PyArg_ParseTuple( args
, "iii|i", &PartyID
, &which
, &slot
, &headerindex
)) {
8361 return AttributeError( GemRB_SetupQuickSlot__doc
);
8364 Game
*game
= core
->GetGame();
8366 return RuntimeError( "No game loaded!" );
8368 Actor
* actor
= game
->FindPC( PartyID
);
8370 return RuntimeError( "Actor not found" );
8372 actor
->SetupQuickSlot(which
, slot
, headerindex
);
8373 Py_INCREF( Py_None
);
8377 PyDoc_STRVAR( GemRB_SetEquippedQuickSlot__doc
,
8378 "SetEquippedQuickSlot(PartyID, QWeaponSlot[, ability])->int\n\n"
8379 "Sets the named weapon/item slot as equipped weapon slot, optionally sets the used ability."
8380 "Returns strref number of failure (0 success, -1 silent failure)." );
8382 static PyObject
* GemRB_SetEquippedQuickSlot(PyObject
* /*self*/, PyObject
* args
)
8388 if (!PyArg_ParseTuple( args
, "ii|i", &PartyID
, &slot
, &ability
)) {
8389 return AttributeError( GemRB_SetEquippedQuickSlot__doc
);
8392 Game
*game
= core
->GetGame();
8394 return RuntimeError( "No game loaded!" );
8396 Actor
* actor
= game
->FindPC( PartyID
);
8398 return RuntimeError( "Actor not found" );
8401 int ret
= actor
->SetEquippedQuickSlot(slot
, ability
);
8402 return PyInt_FromLong( ret
);
8405 PyDoc_STRVAR( GemRB_GetEquippedQuickSlot__doc
,
8406 "GetEquippedQuickSlot(PartyID[, NoTrans]) => Slot\n\n"
8407 "Returns the inventory slot (translation) or quick weapon index (no translation) of the equipped weapon." );
8409 static PyObject
* GemRB_GetEquippedQuickSlot(PyObject
* /*self*/, PyObject
* args
)
8414 if (!PyArg_ParseTuple( args
, "i|i", &PartyID
, &NoTrans
)) {
8415 return AttributeError( GemRB_GetEquippedQuickSlot__doc
);
8418 Game
*game
= core
->GetGame();
8420 return RuntimeError( "No game loaded!" );
8422 Actor
* actor
= game
->FindPC( PartyID
);
8424 return RuntimeError( "Actor not found" );
8427 int ret
= actor
->inventory
.GetEquippedSlot();
8428 /*int effect = core->QuerySlotEffects(ret);
8429 if (effect == SLOT_EFFECT_MISSILE) {
8430 ret = actor->inventory.FindRangedWeapon();
8432 if (actor
->PCStats
) {
8433 for(int i
=0;i
<4;i
++) {
8434 if (ret
== actor
->PCStats
->QuickWeaponSlots
[i
]) {
8436 return PyInt_FromLong(i
);
8438 ret
= i
+actor
->inventory
.GetWeaponSlot();
8443 ret-=actor->inventory.GetWeaponSlot();
8445 return PyInt_FromLong( core
->FindSlot(ret
) );
8448 PyDoc_STRVAR( GemRB_GetEquippedAmmunition__doc
,
8449 "GetEquippedAmmunition(PartyID) => QSlot\n\n"
8450 "Returns the equipped ammunition slot, if any; -1 if none." );
8452 static PyObject
* GemRB_GetEquippedAmmunition(PyObject
* /*self*/, PyObject
* args
)
8456 if (!PyArg_ParseTuple( args
, "i", &PartyID
)) {
8457 return AttributeError( GemRB_GetEquippedQuickSlot__doc
);
8460 Game
*game
= core
->GetGame();
8462 return RuntimeError( "No game loaded!" );
8464 Actor
* actor
= game
->FindPC( PartyID
);
8466 return RuntimeError( "Actor not found" );
8469 int ret
= actor
->inventory
.GetEquippedSlot();
8470 int effect
= core
->QuerySlotEffects(ret
);
8471 if (effect
== SLOT_EFFECT_MISSILE
) {
8472 return PyInt_FromLong( core
->FindSlot(ret
) );
8474 return PyInt_FromLong( -1 );
8478 PyDoc_STRVAR( GemRB_SetModalState__doc
,
8479 "SetModalState(slot, state[,spell])\n\n"
8480 "Sets the modal state of the actor.\n"
8481 "If 'spell' is not given, it will set a default spell resource associated with the state.");
8483 static PyObject
* GemRB_SetModalState(PyObject
* /*self*/, PyObject
* args
)
8487 const char *spell
=NULL
;
8489 if (!PyArg_ParseTuple( args
, "ii|s", &slot
, &state
, &spell
)) {
8490 return AttributeError( GemRB_SetModalState__doc
);
8492 Game
*game
= core
->GetGame();
8494 return RuntimeError( "No game loaded!" );
8496 Actor
* actor
= game
->FindPC( slot
);
8498 return RuntimeError( "Actor not found" );
8500 actor
->SetModal( (ieDword
) state
, 0);
8501 actor
->SetModalSpell(state
, spell
);
8503 Py_INCREF( Py_None
);
8507 PyDoc_STRVAR( GemRB_SpellCast__doc
,
8508 "SpellCast(actor, type, spell)\n\n"
8509 "Makes the actor try to cast a spell. Type is the spell type like 3 for normal spells and 4 for innates.\n"
8510 "Spell is the index of the spell in the memorised spell list.");
8512 static PyObject
* GemRB_SpellCast(PyObject
* /*self*/, PyObject
* args
)
8518 if (!PyArg_ParseTuple( args
, "iii", &slot
, &type
, &spell
)) {
8519 return AttributeError( GemRB_SpellCast__doc
);
8521 Game
*game
= core
->GetGame();
8523 return RuntimeError( "No game loaded!" );
8525 Actor
* actor
= game
->FindPC( slot
);
8527 return RuntimeError( "Actor not found" );
8530 SpellExtHeader spelldata
; // = SpellArray[spell];
8531 actor
->spellbook
.GetSpellInfo(&spelldata
, type
, spell
, 1);
8533 printf("Cast spell: %s\n", spelldata
.spellname
);
8534 printf("Slot: %d\n", spelldata
.slot
);
8535 printf("Type: %d\n", spelldata
.type
);
8536 //cannot make this const, because it will be freed
8537 char *tmp
= core
->GetString(spelldata
.strref
);
8538 printf("Spellname: %s\n", tmp
);
8539 core
->FreeString(tmp
);
8540 printf("Target: %d\n", spelldata
.Target
);
8541 printf("Range: %d\n", spelldata
.Range
);
8542 if(! (1<<spelldata
.type
) & type
) {
8543 return RuntimeError( "Wrong type of spell!");
8546 GameControl
*gc
= core
->GetGameControl();
8547 switch (spelldata
.Target
) {
8549 // FIXME: GA_NO_DEAD and such are not actually used by SetupCasting
8550 gc
->SetupCasting(spelldata
.type
, spelldata
.level
, spelldata
.slot
, actor
, GA_NO_DEAD
, spelldata
.TargetNumber
);
8551 gc
->TryToCast(actor
, actor
);
8555 gc
->target_mode
= TARGET_MODE_NONE
;
8556 //this is always instant casting
8557 core
->ApplySpell(spelldata
.spellname
, actor
, actor
, 0);
8560 gc
->SetupCasting(spelldata
.type
, spelldata
.level
, spelldata
.slot
, actor
, GA_POINT
, spelldata
.TargetNumber
);
8563 gc
->SetupCasting(spelldata
.type
, spelldata
.level
, spelldata
.slot
, actor
, GA_NO_DEAD
, spelldata
.TargetNumber
);
8566 gc
->SetupCasting(spelldata
.type
, spelldata
.level
, spelldata
.slot
, actor
, 0, spelldata
.TargetNumber
);
8569 //bring up inventory in the end???
8572 printf("Unhandled target type: %d\n", spelldata
.Target
);
8575 Py_INCREF( Py_None
);
8579 PyDoc_STRVAR( GemRB_ApplySpell__doc
,
8580 "ApplySpell(actor, spellname)\n\n"
8581 "Applies a spell on actor.");
8583 static PyObject
* GemRB_ApplySpell(PyObject
* /*self*/, PyObject
* args
)
8588 if (!PyArg_ParseTuple( args
, "is", &PartyID
, &spell
)) {
8589 return AttributeError( GemRB_ApplySpell__doc
);
8592 Game
*game
= core
->GetGame();
8594 return RuntimeError( "No game loaded!" );
8596 Actor
* actor
= game
->FindPC( PartyID
);
8598 return RuntimeError( "Actor not found" );
8600 core
->ApplySpell(spell
, actor
, actor
, 0);
8602 Py_INCREF( Py_None
);
8606 PyDoc_STRVAR( GemRB_UseItem__doc
,
8607 "UseItem(actor, slot, header[,forcetarget])\n\n"
8608 "Makes the actor try to use an item. "
8609 "If slot is -1, then header is the index of the item functionality in the use item list. "
8610 "If slot is -2, then header is the quickslot index. "
8611 "If slot is non-negative, then header is the header of the item in the 'slot'.");
8613 static PyObject
* GemRB_UseItem(PyObject
* /*self*/, PyObject
* args
)
8618 int forcetarget
=-1; //some crappy scrolls don't target self correctly!
8620 if (!PyArg_ParseTuple( args
, "iii|i", &PartyID
, &slot
, &header
, &forcetarget
)) {
8621 return AttributeError( GemRB_UseItem__doc
);
8624 Game
*game
= core
->GetGame();
8626 return RuntimeError( "No game loaded!" );
8628 Actor
* actor
= game
->FindPC( PartyID
);
8630 return RuntimeError( "Actor not found" );
8632 ItemExtHeader itemdata
;
8638 actor
->inventory
.GetEquipmentInfo(&itemdata
, header
, 1);
8642 actor
->GetItemSlotInfo(&itemdata
, header
, -1);
8643 if (!itemdata
.Charges
) {
8644 printMessage("GUIScript","QuickItem has no charges.\n", WHITE
);
8645 Py_INCREF( Py_None
);
8651 actor
->GetItemSlotInfo(&itemdata
, core
->QuerySlot(slot
), header
);
8656 if(forcetarget
==-1) {
8657 forcetarget
= itemdata
.Target
;
8660 //is there any better check for a non existent item?
8661 if (!itemdata
.itemname
[0]) {
8662 printMessage("GUIScript","Empty slot used?\n", YELLOW
);
8663 Py_INCREF( Py_None
);
8667 /// remove this after projectile is done
8668 printf("Use item: %s\n", itemdata
.itemname
);
8669 printf("Extended header: %d\n", itemdata
.headerindex
);
8670 printf("Attacktype: %d\n",itemdata
.AttackType
);
8671 printf("Range: %d\n",itemdata
.Range
);
8672 printf("Target: %d\n",forcetarget
);
8673 printf("Projectile: %d\n", itemdata
.ProjectileAnimation
);
8675 switch (forcetarget
) {
8677 actor
->UseItem(itemdata
.slot
, itemdata
.headerindex
, actor
, flags
);
8680 actor
->UseItem(itemdata
.slot
, itemdata
.headerindex
, NULL
, flags
);
8683 core
->GetGameControl()->SetupItemUse(itemdata
.slot
, itemdata
.headerindex
, actor
, GA_POINT
, itemdata
.TargetNumber
);
8686 core
->GetGameControl()->SetupItemUse(itemdata
.slot
, itemdata
.headerindex
, actor
, GA_NO_DEAD
, itemdata
.TargetNumber
);
8689 core
->GetGameControl()->SetupItemUse(itemdata
.slot
, itemdata
.headerindex
, actor
, 0, itemdata
.TargetNumber
);
8692 printMessage("GUIScript", "Unhandled target type!", LIGHT_RED
);
8695 Py_INCREF( Py_None
);
8699 PyDoc_STRVAR( GemRB_SetGamma__doc
,
8700 "SetGamma(brightness, contrast)\n\n"
8701 "Adjusts brightness and contrast.");
8703 static PyObject
* GemRB_SetGamma(PyObject
* /*self*/, PyObject
* args
)
8705 int brightness
, contrast
;
8707 if (!PyArg_ParseTuple( args
, "ii", &brightness
, &contrast
)) {
8708 return AttributeError( GemRB_SetGamma__doc
);
8710 if (brightness
<0 || brightness
>40) {
8711 return RuntimeError( "Brightness must be 0-40" );
8713 if (contrast
<0 || contrast
>5) {
8714 return RuntimeError( "Contrast must be 0-5" );
8716 core
->GetVideoDriver()->SetGamma(brightness
, contrast
);
8717 Py_INCREF( Py_None
);
8721 PyDoc_STRVAR( GemRB_SetMouseScrollSpeed__doc
,
8722 "SetMouseScrollSpeed(mouseSpeed)\n\n"
8723 "Adjusts mouse scroll speed.");
8725 static PyObject
* GemRB_SetMouseScrollSpeed(PyObject
* /*self*/, PyObject
* args
)
8729 if (!PyArg_ParseTuple( args
, "i", &mouseSpeed
)) {
8730 return AttributeError( GemRB_SetMouseScrollSpeed__doc
);
8733 core
->SetMouseScrollSpeed(mouseSpeed
);
8735 Py_INCREF( Py_None
);
8739 PyDoc_STRVAR( GemRB_SetTooltipDelay__doc
,
8740 "SetTooltipDelay(tooltipDelay)\n\n"
8741 "Adjusts tooltip appearing speed.");
8743 static PyObject
* GemRB_SetTooltipDelay(PyObject
* /*self*/, PyObject
* args
)
8747 if (!PyArg_ParseTuple( args
, "i", &tooltipDelay
)) {
8748 return AttributeError( GemRB_SetTooltipDelay__doc
);
8751 core
->TooltipDelay
= tooltipDelay
;
8753 Py_INCREF( Py_None
);
8757 PyDoc_STRVAR( GemRB_SetFullScreen__doc
,
8758 "SetFullScreen(int)\n\n"
8759 "0 - windowed, 1 - fullscreen, -1 - toggle");
8761 static PyObject
* GemRB_SetFullScreen(PyObject
* /*self*/, PyObject
* args
)
8765 if (!PyArg_ParseTuple( args
, "i", &fullscreen
)) {
8766 return AttributeError( GemRB_SetFullScreen__doc
);
8768 core
->GetVideoDriver()->ToggleFullscreenMode(fullscreen
);
8769 Py_INCREF( Py_None
);
8773 PyDoc_STRVAR( GemRB_RestParty__doc
,
8774 "RestParty(noareacheck, dream, hp)\n\n"
8775 "Executes the party rest function, used from both stores and via the main screen.");
8777 static PyObject
* GemRB_RestParty(PyObject
* /*self*/, PyObject
* args
)
8782 if (!PyArg_ParseTuple( args
, "iii", &noareacheck
, &dream
, &hp
)) {
8783 return AttributeError( GemRB_RestParty__doc
);
8785 Game
*game
= core
->GetGame();
8787 return RuntimeError( "No game loaded!" );
8789 game
->RestParty(noareacheck
, dream
, hp
);
8790 Py_INCREF( Py_None
);
8794 PyDoc_STRVAR( GemRB_HasSpecialItem__doc
,
8795 "HasSpecialItem(pc, itemtype, useup) => bool\n\n"
8796 "Checks if a team member has an item, optionally uses it.");
8798 //itemtype 1 - identify
8799 static PyObject
* GemRB_HasSpecialItem(PyObject
* /*self*/, PyObject
* args
)
8801 int PartyID
, itemtype
, useup
;
8803 if (!PyArg_ParseTuple( args
, "iii", &PartyID
, &itemtype
, &useup
)) {
8804 return AttributeError( GemRB_HasSpecialItem__doc
);
8806 if (SpecialItemsCount
==-1) {
8810 Game
*game
= core
->GetGame();
8812 return RuntimeError( "No game loaded!" );
8814 Actor
* actor
= game
->FindPC( PartyID
);
8816 return RuntimeError( "Actor not found" );
8818 int i
= SpecialItemsCount
;
8821 if (itemtype
&SpecialItems
[i
].value
) {
8822 slot
= actor
->inventory
.FindItem(SpecialItems
[i
].resref
,0);
8830 return PyInt_FromLong( 0 );
8834 //use the found item's first usage
8835 useup
= actor
->UseItem((ieDword
) slot
, 0, actor
, UI_SILENT
);
8837 CREItem
*si
= actor
->inventory
.GetSlotItem( slot
);
8838 if (si
->Usages
[0]) useup
= 1;
8840 return PyInt_FromLong( useup
);
8843 PyDoc_STRVAR( GemRB_HasSpecialSpell__doc
,
8844 "HasSpecialSpell(pc, itemtype, useup) => bool\n\n"
8845 "Checks if a team member has a spell, optionally uses it.");
8847 //itemtype 1 - identify
8848 static PyObject
* GemRB_HasSpecialSpell(PyObject
* /*self*/, PyObject
* args
)
8850 int PartyID
, itemtype
, useup
;
8852 if (!PyArg_ParseTuple( args
, "iii", &PartyID
, &itemtype
, &useup
)) {
8853 return AttributeError( GemRB_HasSpecialSpell__doc
);
8855 if (SpecialSpellsCount
==-1) {
8856 ReadSpecialSpells();
8859 Game
*game
= core
->GetGame();
8861 return RuntimeError( "No game loaded!" );
8863 Actor
* actor
= game
->FindPC( PartyID
);
8865 return RuntimeError( "Actor not found" );
8867 int i
= SpecialSpellsCount
;
8869 if (itemtype
&SpecialSpells
[i
].value
) {
8870 if (actor
->spellbook
.HaveSpell(SpecialSpells
[i
].resref
,useup
)) {
8872 //actor->SpellCast(SpecialSpells[i].resref, actor);
8880 return PyInt_FromLong( 0 );
8882 return PyInt_FromLong( 1 );
8885 PyDoc_STRVAR( GemRB_ApplyEffect__doc
,
8886 "ApplyEffect(pc, effect, param1, param2[,resref,resref2, resref3]])\n\n"
8887 "Creates a basic effect and applies it on the player character. "
8888 "This function could be used to add stats that are stored in effect blocks. "
8889 "The resource fields are optional.");
8891 static PyObject
* GemRB_ApplyEffect(PyObject
* /*self*/, PyObject
* args
)
8894 const char *opcodename
;
8896 const char *resref1
= NULL
;
8897 const char *resref2
= NULL
;
8898 const char *resref3
= NULL
;
8899 const char *source
= NULL
;
8901 if (!PyArg_ParseTuple( args
, "isii|ssss", &PartyID
, &opcodename
, ¶m1
, ¶m2
, &resref1
, &resref2
, &resref3
, &source
)) {
8902 return AttributeError( GemRB_ApplyEffect__doc
);
8904 Game
*game
= core
->GetGame();
8906 return RuntimeError( "No game loaded!" );
8908 Actor
* actor
= game
->FindPC( PartyID
);
8910 return RuntimeError( "Actor not found" );
8912 work_ref
.Name
=opcodename
;
8914 Effect
*fx
= EffectQueue::CreateEffect(work_ref
, param1
, param2
, FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES
);
8916 //invalid effect name didn't resolve to opcode
8917 return RuntimeError( "Invalid effect name!" );
8920 strnlwrcpy(fx
->Resource
, resref1
, 8);
8923 strnlwrcpy(fx
->Resource2
, resref2
, 8);
8926 strnlwrcpy(fx
->Resource3
, resref3
, 8);
8929 strnlwrcpy(fx
->Source
, source
, 8);
8934 //fx is not freed by this function
8935 core
->ApplyEffect(fx
, actor
, actor
);
8940 Py_INCREF( Py_None
);
8944 PyDoc_STRVAR( GemRB_CountEffects__doc
,
8945 "CountEffects(pc, effect, param1, param2[,resref])\n\n"
8946 "Counts how many matching effects are applied on the player character. "
8947 "This function could be used to get HLA information in ToB. "
8948 "The resource field is optional.");
8950 static PyObject
* GemRB_CountEffects(PyObject
* /*self*/, PyObject
* args
)
8953 const char *opcodename
;
8955 const char *resref
= NULL
;
8957 if (!PyArg_ParseTuple( args
, "isii|s", &PartyID
, &opcodename
, ¶m1
, ¶m2
, &resref
)) {
8958 return AttributeError( GemRB_CountEffects__doc
);
8960 Game
*game
= core
->GetGame();
8962 return RuntimeError( "No game loaded!" );
8964 Actor
* actor
= game
->FindPC( PartyID
);
8966 return RuntimeError( "Actor not found" );
8968 work_ref
.Name
=opcodename
;
8970 ieDword ret
= actor
->fxqueue
.CountEffects(work_ref
, param1
, param2
, resref
);
8971 return PyInt_FromLong( ret
);
8974 PyDoc_STRVAR( GemRB_ModifyEffect__doc
,
8975 "ModifyEffect(pc, effect, p1, p2)\n\n"
8976 "Changes/sets the target coordinates of the specified effect. "
8977 "This command is used for the farsight spell.");
8979 static PyObject
* GemRB_ModifyEffect(PyObject
* /*self*/, PyObject
* args
)
8982 const char *opcodename
;
8985 if (!PyArg_ParseTuple( args
, "isii", &PartyID
, &opcodename
, &px
, &py
)) {
8986 return AttributeError( GemRB_ModifyEffect__doc
);
8988 Game
*game
= core
->GetGame();
8990 return RuntimeError( "No game loaded!" );
8992 Actor
* actor
= game
->FindPC( PartyID
);
8994 return RuntimeError( "Actor not found" );
8996 work_ref
.Name
=opcodename
;
8998 actor
->fxqueue
.ModifyEffectPoint(work_ref
, px
, py
);
8999 Py_INCREF( Py_None
);
9003 PyDoc_STRVAR( GemRB_StealFailed__doc
,
9005 "Sends the steal failed trigger (attacked) to the owner of the current store. "
9006 "The owner of the current store was set to the Sender of StartStore action.");
9008 static PyObject
* GemRB_StealFailed(PyObject
* /*self*/, PyObject
* /*args*/)
9010 Game
*game
= core
->GetGame();
9012 return RuntimeError( "No game loaded!" );
9014 Store
*store
= core
->GetCurrentStore();
9016 return RuntimeError( "No store loaded!" );
9018 Map
*map
= game
->GetCurrentArea();
9020 return RuntimeError( "No area loaded!" );
9022 Actor
* owner
= map
->GetActor( store
->GetOwner(), 0 );
9024 printMessage("GUIScript", "No owner found!", YELLOW
);
9025 Py_INCREF( Py_None
);
9028 Actor
* attacker
= game
->FindPC((int) game
->GetSelectedPCSingle() );
9030 printMessage("GUIScript", "No thief found!", YELLOW
);
9031 Py_INCREF( Py_None
);
9034 //not sure if this is ok
9035 //owner->LastAttacker = attacker->GetID();
9036 owner
->LastDisarmFailed
= attacker
->GetID();
9037 Py_INCREF( Py_None
);
9041 PyDoc_STRVAR( GemRB_SwapPCs__doc
,
9042 "SwapPCs(idx1, idx2)\n\n"
9043 "Swaps the party order for two player characters.");
9045 static PyObject
* GemRB_SwapPCs(PyObject
* /*self*/, PyObject
* args
)
9049 if (!PyArg_ParseTuple( args
, "ii", &idx1
, &idx2
)) {
9050 return AttributeError( GemRB_SwapPCs__doc
);
9053 Game
*game
= core
->GetGame();
9055 return RuntimeError( "No game loaded!" );
9058 game
->SwapPCs(game
->FindPlayer(idx1
), game
->FindPlayer(idx2
));
9060 if (idx1
==1 || idx2
==1) {
9061 DisplayStringCore( game
->FindPC(1), VB_LEADER
, DS_CONST
);
9064 Py_INCREF( Py_None
);
9068 PyDoc_STRVAR( GemRB_SetRepeatClickFlags__doc
,
9069 "SetRepeatClickFlags(value, op)\n\n"
9070 "Sets the mode repeat clicks are handled.");
9072 static PyObject
* GemRB_SetRepeatClickFlags(PyObject
* /*self*/, PyObject
* args
)
9077 if (!PyArg_ParseTuple( args
, "ii", &value
, &op
)) {
9078 return AttributeError( GemRB_SetRepeatClickFlags__doc
);
9080 ret
= core
->GetEventMgr()->SetRKFlags( (unsigned long) value
, (unsigned long) op
);
9081 return PyInt_FromLong( ret
);
9084 PyDoc_STRVAR( GemRB_DisplayString__doc
,
9085 "DisplayString(strref, color[,actor])\n\n"
9086 "Displays string on the MessageWindow using methods supplied by the engine core. "
9087 "The optional actor is the party ID of the character whose name will be displayed.");
9089 static PyObject
* GemRB_DisplayString(PyObject
* /*self*/, PyObject
* args
)
9094 if (!PyArg_ParseTuple( args
, "ii|i", &strref
, &color
, &PartyID
)) {
9095 return AttributeError( GemRB_DisplayString__doc
);
9098 Game
*game
= core
->GetGame();
9100 return RuntimeError( "No game loaded!" );
9102 Actor
*actor
= game
->FindPC(PartyID
);
9104 return RuntimeError( "Actor not found" );
9106 core
->DisplayStringName(strref
, (unsigned int) color
, actor
, IE_STR_SOUND
);
9108 core
->DisplayString(strref
, (unsigned int) color
, IE_STR_SOUND
);
9110 Py_INCREF( Py_None
);
9114 PyDoc_STRVAR( GemRB_GetCombatDetails__doc
,
9115 "GetCombatDetails(pc, leftorright) => dict\n\n"
9116 "Returns the current THAC0 and other data in relation to the equipped weapon.");
9118 static PyObject
* GemRB_GetCombatDetails(PyObject
* /*self*/, PyObject
* args
)
9123 if (!PyArg_ParseTuple( args
, "ii", &PartyID
, &leftorright
)) {
9124 return AttributeError( GemRB_GetCombatDetails__doc
);
9126 Game
*game
= core
->GetGame();
9128 return RuntimeError( "No game loaded!" );
9130 Actor
* actor
= game
->FindPC( PartyID
);
9132 return RuntimeError( "Actor not found" );
9135 leftorright
= leftorright
&1;
9137 ITMExtHeader
*header
= NULL
;
9138 ITMExtHeader
*hittingheader
= NULL
;
9141 int DamageBonus
=0, CriticalBonus
=0;
9144 PyObject
* dict
= PyDict_New();
9145 if (!actor
->GetCombatDetails(tohit
, leftorright
, wi
, header
, hittingheader
, Flags
, DamageBonus
, speed
, CriticalBonus
, style
)) {
9146 //TODO: handle error, so tohit will still be set correctly?
9148 PyDict_SetItemString(dict
, "ToHit", PyInt_FromLong (tohit
));
9149 PyDict_SetItemString(dict
, "Flags", PyInt_FromLong (Flags
));
9150 PyDict_SetItemString(dict
, "DamageBonus", PyInt_FromLong (DamageBonus
));
9151 PyDict_SetItemString(dict
, "Speed", PyInt_FromLong (speed
));
9152 PyDict_SetItemString(dict
, "CriticalBonus", PyInt_FromLong (CriticalBonus
));
9153 PyDict_SetItemString(dict
, "Style", PyInt_FromLong (style
));
9157 PyDoc_STRVAR( GemRB_IsDualWielding__doc
,
9158 "IsDualWielding(pc)\n\n"
9159 "1 if the pc is dual wielding; 0 otherwise.");
9161 static PyObject
* GemRB_IsDualWielding(PyObject
* /*self*/, PyObject
* args
)
9165 if (!PyArg_ParseTuple( args
, "i", &PartyID
)) {
9166 return AttributeError( GemRB_IsDualWielding__doc
);
9168 Game
*game
= core
->GetGame();
9170 return RuntimeError( "No game loaded!" );
9172 Actor
* actor
= game
->FindPC( PartyID
);
9174 return RuntimeError( "Actor not found" );
9177 int dualwield
= actor
->IsDualWielding();
9178 return PyInt_FromLong( dualwield
);
9181 PyDoc_STRVAR( GemRB_GetSelectedSize__doc
,
9182 "GetSelectedSize() => int\n\n"
9183 "Returns the number of actors selected in the party.");
9185 static PyObject
* GemRB_GetSelectedSize(PyObject
* /*self*/, PyObject
* /*args*/)
9187 return PyInt_FromLong(core
->GetGame()->selected
.size());
9190 PyDoc_STRVAR( GemRB_GetSpellCastOn__doc
,
9191 "GetSpellCastOn(pc) => resref\n\n"
9192 "Returns the last spell cast on a partymember.");
9194 static PyObject
* GemRB_GetSpellCastOn(PyObject
* /*self*/, PyObject
* args
)
9199 if (!PyArg_ParseTuple( args
, "i", &PartyID
)) {
9200 return AttributeError( GemRB_GetSpellCastOn__doc
);
9202 Game
*game
= core
->GetGame();
9204 return RuntimeError( "No game loaded!" );
9206 Actor
* actor
= game
->FindPC( PartyID
);
9208 return RuntimeError( "Actor not found" );
9211 ResolveSpellName(splname
, actor
->LastSpellOnMe
);
9212 return PyString_FromString(splname
);
9215 static PyMethodDef GemRBMethods
[] = {
9216 METHOD(ActOnPC
, METH_VARARGS
),
9217 METHOD(ApplyEffect
, METH_VARARGS
),
9218 METHOD(ApplySpell
, METH_VARARGS
),
9219 METHOD(CanUseItemType
, METH_VARARGS
),
9220 METHOD(ChangeContainerItem
, METH_VARARGS
),
9221 METHOD(ChangeItemFlag
, METH_VARARGS
),
9222 METHOD(ChangeStoreItem
, METH_VARARGS
),
9223 METHOD(CheckFeatCondition
, METH_VARARGS
),
9224 METHOD(CheckVar
, METH_VARARGS
),
9225 METHOD(ClearActions
, METH_VARARGS
),
9226 METHOD(CountEffects
, METH_VARARGS
),
9227 METHOD(CreateCreature
, METH_VARARGS
),
9228 METHOD(CreateItem
, METH_VARARGS
),
9229 METHOD(CreateMovement
, METH_VARARGS
),
9230 METHOD(CreatePlayer
, METH_VARARGS
),
9231 METHOD(CreateString
, METH_VARARGS
),
9232 METHOD(CreateWindow
, METH_VARARGS
),
9233 METHOD(DeleteSaveGame
, METH_VARARGS
),
9234 METHOD(DispelEffect
, METH_VARARGS
),
9235 METHOD(DisplayString
, METH_VARARGS
),
9236 METHOD(DragItem
, METH_VARARGS
),
9237 METHOD(DrawWindows
, METH_NOARGS
),
9238 METHOD(DropDraggedItem
, METH_VARARGS
),
9239 METHOD(EnableCheatKeys
, METH_VARARGS
),
9240 METHOD(EndCutSceneMode
, METH_NOARGS
),
9241 METHOD(EnterGame
, METH_NOARGS
),
9242 METHOD(EnterStore
, METH_VARARGS
),
9243 METHOD(EvaluateString
, METH_VARARGS
),
9244 METHOD(ExecuteString
, METH_VARARGS
),
9245 METHOD(ExploreArea
, METH_VARARGS
),
9246 METHOD(FillPlayerInfo
, METH_VARARGS
),
9247 METHOD(GameControlGetTargetMode
, METH_NOARGS
),
9248 METHOD(GameControlSetScreenFlags
, METH_VARARGS
),
9249 METHOD(GameControlSetTargetMode
, METH_VARARGS
),
9250 METHOD(GameGetReputation
, METH_NOARGS
),
9251 METHOD(GameSetReputation
, METH_VARARGS
),
9252 METHOD(GameGetFirstSelectedPC
, METH_NOARGS
),
9253 METHOD(GameGetFormation
, METH_VARARGS
),
9254 METHOD(GameGetPartyGold
, METH_NOARGS
),
9255 METHOD(GameGetSelectedPCSingle
, METH_VARARGS
),
9256 METHOD(GameIsBeastKnown
, METH_VARARGS
),
9257 METHOD(GameIsPCSelected
, METH_VARARGS
),
9258 METHOD(GamePause
, METH_VARARGS
),
9259 METHOD(GameSelectPC
, METH_VARARGS
),
9260 METHOD(GameSelectPCSingle
, METH_VARARGS
),
9261 METHOD(GameSetExpansion
, METH_VARARGS
),
9262 METHOD(GameSetFormation
, METH_VARARGS
),
9263 METHOD(GameSetPartyGold
, METH_VARARGS
),
9264 METHOD(GameSetPartySize
, METH_VARARGS
),
9265 METHOD(GameSetProtagonistMode
, METH_VARARGS
),
9266 METHOD(GameSetScreenFlags
, METH_VARARGS
),
9267 METHOD(GetAbilityBonus
, METH_VARARGS
),
9268 METHOD(GetCombatDetails
, METH_VARARGS
),
9269 METHOD(GetContainer
, METH_VARARGS
),
9270 METHOD(GetContainerItem
, METH_VARARGS
),
9271 METHOD(GetControl
, METH_VARARGS
),
9272 METHOD(GetCurrentArea
, METH_NOARGS
),
9273 METHOD(GetEquippedAmmunition
, METH_VARARGS
),
9274 METHOD(GetEquippedQuickSlot
, METH_VARARGS
),
9275 METHOD(GetGamePortraitPreview
, METH_VARARGS
),
9276 METHOD(GetGamePreview
, METH_VARARGS
),
9277 METHOD(GetGameString
, METH_VARARGS
),
9278 METHOD(GetGameTime
, METH_NOARGS
),
9279 METHOD(GetGameVar
, METH_VARARGS
),
9280 METHOD(GetINIBeastsKey
, METH_VARARGS
),
9281 METHOD(GetINIPartyCount
, METH_NOARGS
),
9282 METHOD(GetINIPartyKey
, METH_VARARGS
),
9283 METHOD(GetINIQuestsKey
, METH_VARARGS
),
9284 METHOD(GetItem
, METH_VARARGS
),
9285 METHOD(GetJournalEntry
, METH_VARARGS
),
9286 METHOD(GetJournalSize
, METH_VARARGS
),
9287 METHOD(GetKnownSpell
, METH_VARARGS
),
9288 METHOD(GetKnownSpellsCount
, METH_VARARGS
),
9289 METHOD(GetMemorizableSpellsCount
, METH_VARARGS
),
9290 METHOD(GetMemorizedSpell
, METH_VARARGS
),
9291 METHOD(GetMemorizedSpellsCount
, METH_VARARGS
),
9292 METHOD(GetMessageWindowSize
, METH_NOARGS
),
9293 METHOD(GetPartySize
, METH_NOARGS
),
9294 METHOD(GetPCStats
, METH_VARARGS
),
9295 METHOD(GetPlayerName
, METH_VARARGS
),
9296 METHOD(GetPlayerPortrait
, METH_VARARGS
),
9297 METHOD(GetPlayerStat
, METH_VARARGS
),
9298 METHOD(GetPlayerStates
, METH_VARARGS
),
9299 METHOD(GetPlayerScript
, METH_VARARGS
),
9300 METHOD(GetPlayerString
, METH_VARARGS
),
9301 METHOD(GetSaveGames
, METH_VARARGS
),
9302 METHOD(GetSelectedSize
, METH_NOARGS
),
9303 METHOD(GetString
, METH_VARARGS
),
9304 METHOD(GetSpellCastOn
, METH_VARARGS
),
9305 METHOD(GetToken
, METH_VARARGS
),
9306 METHOD(GetVar
, METH_VARARGS
),
9307 METHOD(GetSlotType
, METH_VARARGS
),
9308 METHOD(GetStore
, METH_VARARGS
),
9309 METHOD(GetStoreDrink
, METH_VARARGS
),
9310 METHOD(GetStoreCure
, METH_VARARGS
),
9311 METHOD(GetStoreItem
, METH_VARARGS
),
9312 METHOD(GetSpell
, METH_VARARGS
),
9313 METHOD(GetSlotItem
, METH_VARARGS
),
9314 METHOD(GetSlots
, METH_VARARGS
),
9315 METHOD(GetSystemVariable
, METH_VARARGS
),
9316 METHOD(GetRumour
, METH_VARARGS
),
9317 METHOD(HardEndPL
, METH_NOARGS
),
9318 METHOD(HasResource
, METH_VARARGS
),
9319 METHOD(HasSpecialItem
, METH_VARARGS
),
9320 METHOD(HasSpecialSpell
, METH_VARARGS
),
9321 METHOD(HideGUI
, METH_NOARGS
),
9322 METHOD(IncreaseReputation
, METH_VARARGS
),
9323 METHOD(IsDraggingItem
, METH_NOARGS
),
9324 METHOD(IsDualWielding
, METH_VARARGS
),
9325 METHOD(IsValidStoreItem
, METH_VARARGS
),
9326 METHOD(LearnSpell
, METH_VARARGS
),
9327 METHOD(LeaveContainer
, METH_VARARGS
),
9328 METHOD(LeaveParty
, METH_VARARGS
),
9329 METHOD(LeaveStore
, METH_VARARGS
),
9330 METHOD(LoadGame
, METH_VARARGS
),
9331 METHOD(LoadMusicPL
, METH_VARARGS
),
9332 METHOD(LoadSymbol
, METH_VARARGS
),
9333 METHOD(LoadTable
, METH_VARARGS
),
9334 METHOD(LoadWindowPack
, METH_VARARGS
),
9335 METHOD(LoadWindow
, METH_VARARGS
),
9336 METHOD(LoadWindowFrame
, METH_VARARGS
),
9337 METHOD(MemorizeSpell
, METH_VARARGS
),
9338 METHOD(ModifyEffect
, METH_VARARGS
),
9339 METHOD(MoveToArea
, METH_VARARGS
),
9340 METHOD(Quit
, METH_NOARGS
),
9341 METHOD(QuitGame
, METH_NOARGS
),
9342 METHOD(PlaySound
, METH_VARARGS
),
9343 METHOD(PlayMovie
, METH_VARARGS
),
9344 METHOD(RemoveItem
, METH_VARARGS
),
9345 METHOD(RemoveSpell
, METH_VARARGS
),
9346 METHOD(RemoveEffects
, METH_VARARGS
),
9347 METHOD(RestParty
, METH_VARARGS
),
9348 METHOD(RevealArea
, METH_VARARGS
),
9349 METHOD(Roll
, METH_VARARGS
),
9350 METHOD(RunEventHandler
, METH_VARARGS
),
9351 METHOD(SaveCharacter
, METH_VARARGS
),
9352 METHOD(SaveGame
, METH_VARARGS
),
9353 METHOD(SetDefaultActions
, METH_VARARGS
),
9354 METHOD(SetEquippedQuickSlot
, METH_VARARGS
),
9355 METHOD(SetFullScreen
, METH_VARARGS
),
9356 METHOD(SetGamma
, METH_VARARGS
),
9357 METHOD(SetGlobal
, METH_VARARGS
),
9358 METHOD(SetInfoTextColor
, METH_VARARGS
),
9359 METHOD(SetMapnote
, METH_VARARGS
),
9360 METHOD(SetMasterScript
, METH_VARARGS
),
9361 METHOD(SetMemorizableSpellsCount
, METH_VARARGS
),
9362 METHOD(SetModalState
, METH_VARARGS
),
9363 METHOD(SetMouseScrollSpeed
, METH_VARARGS
),
9364 METHOD(SetNextScript
, METH_VARARGS
),
9365 METHOD(SetPlayerName
, METH_VARARGS
),
9366 METHOD(SetPlayerScript
, METH_VARARGS
),
9367 METHOD(SetPlayerStat
, METH_VARARGS
),
9368 METHOD(SetPlayerString
, METH_VARARGS
),
9369 METHOD(SetPlayerSound
, METH_VARARGS
),
9370 METHOD(SetPurchasedAmount
, METH_VARARGS
),
9371 METHOD(SetRepeatClickFlags
, METH_VARARGS
),
9372 METHOD(SetTimedEvent
, METH_VARARGS
),
9373 METHOD(SetTimedEventByName
, METH_VARARGS
),
9374 METHOD(SetToken
, METH_VARARGS
),
9375 METHOD(SetTooltipDelay
, METH_VARARGS
),
9376 METHOD(SetupQuickSlot
, METH_VARARGS
),
9377 METHOD(SetVar
, METH_VARARGS
),
9378 METHOD(SoftEndPL
, METH_NOARGS
),
9379 METHOD(SpellCast
, METH_VARARGS
),
9380 METHOD(StatComment
, METH_VARARGS
),
9381 METHOD(StealFailed
, METH_NOARGS
),
9382 METHOD(SwapPCs
, METH_VARARGS
),
9383 METHOD(UnhideGUI
, METH_NOARGS
),
9384 METHOD(UnmemorizeSpell
, METH_VARARGS
),
9385 METHOD(UpdateAmbientsVolume
, METH_NOARGS
),
9386 METHOD(UpdateMusicVolume
, METH_NOARGS
),
9387 METHOD(UseItem
, METH_VARARGS
),
9388 // terminating entry
9389 {NULL
, NULL
, 0, NULL
}
9392 static PyMethodDef GemRBInternalMethods
[] = {
9393 METHOD(Button_CreateLabelOnButton
, METH_VARARGS
),
9394 METHOD(Button_EnableBorder
, METH_VARARGS
),
9395 METHOD(Button_SetActionIcon
, METH_VARARGS
),
9396 METHOD(Button_SetBAM
, METH_VARARGS
),
9397 METHOD(Button_SetBorder
, METH_VARARGS
),
9398 METHOD(Button_SetFlags
, METH_VARARGS
),
9399 METHOD(Button_SetFont
, METH_VARARGS
),
9400 METHOD(Button_SetItemIcon
, METH_VARARGS
),
9401 METHOD(Button_SetMOS
, METH_VARARGS
),
9402 METHOD(Button_SetOverlay
, METH_VARARGS
),
9403 METHOD(Button_SetPLT
, METH_VARARGS
),
9404 METHOD(Button_SetPicture
, METH_VARARGS
),
9405 METHOD(Button_SetPictureClipping
, METH_VARARGS
),
9406 METHOD(Button_SetSpellIcon
, METH_VARARGS
),
9407 METHOD(Button_SetSprite2D
, METH_VARARGS
),
9408 METHOD(Button_SetSprites
, METH_VARARGS
),
9409 METHOD(Button_SetState
, METH_VARARGS
),
9410 METHOD(Button_SetTextColor
, METH_VARARGS
),
9411 METHOD(Control_AttachScrollBar
, METH_VARARGS
),
9412 METHOD(Control_QueryText
, METH_VARARGS
),
9413 METHOD(Control_SetAnimation
, METH_VARARGS
),
9414 METHOD(Control_SetAnimationPalette
, METH_VARARGS
),
9415 METHOD(Control_SetEvent
, METH_VARARGS
),
9416 METHOD(Control_SetEventByName
, METH_VARARGS
),
9417 METHOD(Control_SetPos
, METH_VARARGS
),
9418 METHOD(Control_SetSize
, METH_VARARGS
),
9419 METHOD(Control_SetStatus
, METH_VARARGS
),
9420 METHOD(Control_SetText
, METH_VARARGS
),
9421 METHOD(Control_SetTooltip
, METH_VARARGS
),
9422 METHOD(Control_SetVarAssoc
, METH_VARARGS
),
9423 METHOD(Control_TextArea_SetFlags
, METH_VARARGS
),
9424 METHOD(Label_SetTextColor
, METH_VARARGS
),
9425 METHOD(Label_SetUseRGB
, METH_VARARGS
),
9426 METHOD(SaveGame_GetDate
, METH_VARARGS
),
9427 METHOD(SaveGame_GetGameDate
, METH_VARARGS
),
9428 METHOD(SaveGame_GetName
, METH_VARARGS
),
9429 METHOD(SaveGame_GetPortrait
, METH_VARARGS
),
9430 METHOD(SaveGame_GetPreview
, METH_VARARGS
),
9431 METHOD(SaveGame_GetSaveID
, METH_VARARGS
),
9432 METHOD(ScrollBar_SetDefaultScrollBar
, METH_VARARGS
),
9433 METHOD(ScrollBar_SetSprites
, METH_VARARGS
),
9434 METHOD(Symbol_GetValue
, METH_VARARGS
),
9435 METHOD(Symbol_Unload
, METH_VARARGS
),
9436 METHOD(Table_FindValue
, METH_VARARGS
),
9437 METHOD(Table_GetColumnCount
, METH_VARARGS
),
9438 METHOD(Table_GetColumnIndex
, METH_VARARGS
),
9439 METHOD(Table_GetColumnName
, METH_VARARGS
),
9440 METHOD(Table_GetRowCount
, METH_VARARGS
),
9441 METHOD(Table_GetRowIndex
, METH_VARARGS
),
9442 METHOD(Table_GetRowName
, METH_VARARGS
),
9443 METHOD(Table_GetValue
, METH_VARARGS
),
9444 METHOD(Table_Unload
, METH_VARARGS
),
9445 METHOD(TextArea_Append
, METH_VARARGS
),
9446 METHOD(TextArea_Clear
, METH_VARARGS
),
9447 METHOD(TextArea_GetCharSounds
, METH_VARARGS
),
9448 METHOD(TextArea_GetCharacters
, METH_VARARGS
),
9449 METHOD(TextArea_GetPortraits
, METH_VARARGS
),
9450 METHOD(TextArea_MoveText
, METH_VARARGS
),
9451 METHOD(TextArea_Rewind
, METH_VARARGS
),
9452 METHOD(TextArea_Scroll
, METH_VARARGS
),
9453 METHOD(TextArea_SetHistory
, METH_VARARGS
),
9454 METHOD(TextEdit_ConvertEdit
, METH_VARARGS
),
9455 METHOD(TextEdit_SetBufferLength
, METH_VARARGS
),
9456 METHOD(Window_CreateButton
, METH_VARARGS
),
9457 METHOD(Window_CreateLabel
, METH_VARARGS
),
9458 METHOD(Window_CreateMapControl
, METH_VARARGS
),
9459 METHOD(Window_CreateScrollBar
, METH_VARARGS
),
9460 METHOD(Window_CreateTextEdit
, METH_VARARGS
),
9461 METHOD(Window_CreateWorldMapControl
, METH_VARARGS
),
9462 METHOD(Window_DeleteControl
, METH_VARARGS
),
9463 METHOD(Window_GetControl
, METH_VARARGS
),
9464 METHOD(Window_HasControl
, METH_VARARGS
),
9465 METHOD(Window_Invalidate
, METH_VARARGS
),
9466 METHOD(Window_SetFrame
, METH_VARARGS
),
9467 METHOD(Window_SetPicture
, METH_VARARGS
),
9468 METHOD(Window_SetPos
, METH_VARARGS
),
9469 METHOD(Window_SetSize
, METH_VARARGS
),
9470 METHOD(Window_SetVisible
, METH_VARARGS
),
9471 METHOD(Window_SetupControls
, METH_VARARGS
),
9472 METHOD(Window_SetupEquipmentIcons
, METH_VARARGS
),
9473 METHOD(Window_SetupSpellIcons
, METH_VARARGS
),
9474 METHOD(Window_ShowModal
, METH_VARARGS
),
9475 METHOD(Window_Unload
, METH_VARARGS
),
9476 METHOD(WorldMap_AdjustScrolling
, METH_VARARGS
),
9477 METHOD(WorldMap_GetDestinationArea
, METH_VARARGS
),
9478 METHOD(WorldMap_SetTextColor
, METH_VARARGS
),
9479 // terminating entry
9480 {NULL
, NULL
, 0, NULL
}
9483 GUIScript::GUIScript(void)
9486 pDict
= NULL
; //borrowed, but used outside a function
9487 pModule
= NULL
; //should decref it
9488 pMainDic
= NULL
; //borrowed, but used outside a function
9491 GUIScript::~GUIScript(void)
9493 if (Py_IsInitialized()) {
9495 Py_DECREF( pModule
);
9511 if (SpecialSpells
) {
9512 free(SpecialSpells
);
9528 StoreSpellsCount
= -1;
9529 SpecialSpellsCount
= -1;
9530 SpecialItemsCount
= -1;
9531 UsedItemsCount
= -1;
9532 ItemSoundsCount
= -1;
9533 ReputationIncrease
[0]=(int) UNINIT_IEDWORD
;
9534 ReputationDonation
[0]=(int) UNINIT_IEDWORD
;
9535 GUIAction
[0]=UNINIT_IEDWORD
;
9538 PyDoc_STRVAR( GemRB__doc
,
9539 "Module exposing GemRB data and engine internals\n\n"
9540 "This module exposes to python GUIScripts GemRB engine data and internals."
9541 "It's implemented in gemrb/plugins/GUIScript/GUIScript.cpp" );
9543 PyDoc_STRVAR( GemRB_internal__doc
,
9544 "Internal module for GemRB metaclasses.\n\n"
9545 "This module is only for implementing GUIClass.py."
9546 "It's implemented in gemrb/plugins/GUIScript/GUIScript.cpp" );
9548 /** Initialization Routine */
9550 bool GUIScript::Init(void)
9553 if (!Py_IsInitialized()) {
9556 PyObject
* pGemRB
= Py_InitModule3( "GemRB", GemRBMethods
, GemRB__doc
);
9561 PyObject
* p_GemRB
= Py_InitModule3( "_GemRB", GemRBInternalMethods
, GemRB_internal__doc
);
9568 sprintf( string
, "import sys" );
9569 if (PyRun_SimpleString( string
) == -1) {
9570 printMessage( "GUIScript", string
, RED
);
9573 char path
[_MAX_PATH
];
9574 char path2
[_MAX_PATH
];
9576 PathJoin(path
, core
->GUIScriptsPath
, "GUIScripts", NULL
);
9578 // use the iwd guiscripts for how, but leave its override
9579 if (stricmp( core
->GameType
, "how" ) == 0) {
9580 PathJoin(path2
, path
, "iwd", NULL
);
9582 PathJoin(path2
, path
, core
->GameType
, NULL
);
9588 for (p
= path
; *p
!= 0; p
++)
9594 for (p
= path2
; *p
!= 0; p
++)
9601 sprintf( string
, "sys.path.append(\"%s\")", path2
);
9602 if (PyRun_SimpleString( string
) == -1) {
9603 printMessage( "GUIScript", string
, RED
);
9606 sprintf( string
, "sys.path.append(\"%s\")", path
);
9607 if (PyRun_SimpleString( string
) == -1) {
9608 printMessage( "GUIScript", string
, RED
);
9611 sprintf( string
, "import GemRB\n");
9612 if (PyRun_SimpleString( "import GemRB" ) == -1) {
9613 printMessage( "GUIScript", string
, RED
);
9617 sprintf( string
, "GemRB.GameType = \"%s\"", core
->GameType
);
9618 if (PyRun_SimpleString( string
) == -1) {
9619 printMessage( "GUIScript", string
, RED
);
9623 #if PY_MAJOR_VERSION == 2
9624 #if PY_MINOR_VERSION > 5
9625 // warn about python stuff that will go away in 3.0
9626 Py_Py3kWarningFlag
= true;
9630 if (PyRun_SimpleString( "from GUIDefines import *" ) == -1) {
9631 printMessage( "GUIScript", " ", RED
);
9632 printf("Check if %s/GUIDefines.py exists! ", path
);
9636 if (PyRun_SimpleString( "from GUIClasses import *" ) == -1) {
9637 printMessage( "GUIScript", " ", RED
);
9638 printf("Check if %s/GUIClasses.py exists! ", path
);
9642 if (PyRun_SimpleString( "from GemRB import *" ) == -1) {
9643 printMessage( "GUIScript", " ", RED
);
9644 printf("builtin GemRB module failed to load!!! ");
9648 PyObject
*pMainMod
= PyImport_AddModule( "__main__" );
9649 /* pMainMod is a borrowed reference */
9650 pMainDic
= PyModule_GetDict( pMainMod
);
9651 /* pMainDic is a borrowed reference */
9653 PyObject
*pClassesMod
= PyImport_AddModule( "GUIClasses" );
9654 /* pClassesMod is a borrowed reference */
9655 pGUIClasses
= PyModule_GetDict( pClassesMod
);
9656 /* pGUIClasses is a borrowed reference */
9661 bool GUIScript::LoadScript(const char* filename
)
9663 if (!Py_IsInitialized()) {
9666 printMessage( "GUIScript", "Loading Script ", WHITE
);
9667 printf( "%s...", filename
);
9669 char path
[_MAX_PATH
];
9670 strcpy( path
, filename
);
9672 PyObject
*pName
= PyString_FromString( filename
);
9673 /* Error checking of pName left out */
9674 if (pName
== NULL
) {
9675 printStatus( "ERROR", LIGHT_RED
);
9680 Py_DECREF( pModule
);
9683 pModule
= PyImport_Import( pName
);
9686 if (pModule
!= NULL
) {
9687 pDict
= PyModule_GetDict( pModule
);
9688 if (PyDict_Merge( pDict
, pMainDic
, false ) == -1)
9690 /* pDict is a borrowed reference */
9693 printStatus( "ERROR", LIGHT_RED
);
9696 printStatus( "OK", LIGHT_GREEN
);
9700 /* Similar to RunFunction, but with parameters, and doesn't necessarily fails */
9701 PyObject
*GUIScript::CallbackFunction(const char* fname
, PyObject
* pArgs
)
9703 if (!Py_IsInitialized()) {
9706 if (pDict
== NULL
) {
9709 PyObject
*pFunc
= PyDict_GetItemString( pDict
, (char *) fname
);
9710 /* pFunc: Borrowed reference */
9711 if (( !pFunc
) || ( !PyCallable_Check( pFunc
) )) {
9712 printMessage("GUIScript", " ", LIGHT_RED
);
9713 printf("%s is not callable!\n", fname
);
9716 PyObject
*pValue
= PyObject_CallObject( pFunc
, pArgs
);
9717 if (pValue
== NULL
) {
9718 if (PyErr_Occurred()) {
9725 bool GUIScript::RunFunction(const char *ModuleName
, const char* FunctionName
, bool error
, int intparam
)
9727 if (!Py_IsInitialized()) {
9733 module
= PyImport_Import(PyString_FromString(ModuleName
));
9738 if (module
== NULL
) {
9741 PyObject
*dict
= PyModule_GetDict(module
);
9743 PyObject
*pFunc
= PyDict_GetItemString( dict
, const_cast<char*>(FunctionName
) );
9744 /* pFunc: Borrowed reference */
9745 if (( !pFunc
) || ( !PyCallable_Check( pFunc
) )) {
9747 printMessage( "GUIScript", "Missing function:", LIGHT_RED
);
9748 printf("%s\n", FunctionName
);
9754 if (intparam
== -1) {
9757 pArgs
= Py_BuildValue("(i)", intparam
);
9759 PyObject
*pValue
= PyObject_CallObject( pFunc
, pArgs
);
9760 Py_XDECREF( pArgs
);
9761 if (pValue
== NULL
) {
9762 if (PyErr_Occurred()) {
9768 Py_DECREF( pValue
);
9773 /** Exec a single String */
9774 void GUIScript::ExecString(const char* string
)
9776 if (PyRun_SimpleString( (char *) string
) == -1) {
9777 if (PyErr_Occurred()) {
9783 PyObject
* GUIScript::ConstructObject(const char* type
, int arg
)
9785 PyObject
* tuple
= PyTuple_New(1);
9786 PyTuple_SET_ITEM(tuple
, 0, PyInt_FromLong(arg
));
9787 PyObject
* ret
= gs
->ConstructObject(type
, tuple
);
9792 PyObject
* GUIScript::ConstructObject(const char* type
, PyObject
* pArgs
)
9794 char classname
[_MAX_PATH
] = "G";
9795 strncat(classname
, type
, _MAX_PATH
- 2);
9798 snprintf(buf
, sizeof(buf
), "Tried to use an object (%s) before script compiled!", classname
);
9799 return RuntimeError(buf
);
9802 PyObject
* cobj
= PyDict_GetItemString( pGUIClasses
, classname
);
9805 snprintf(buf
, sizeof(buf
), "Failed to lookup name '%s'", classname
);
9806 return RuntimeError(buf
);
9808 PyObject
* ret
= PyObject_Call(cobj
, pArgs
, NULL
);
9810 return RuntimeError("Failed to call constructor");
9815 #include "plugindef.h"
9817 GEMRB_PLUGIN(0x1B01BE6B, "GUI Script Engine (Python)")
9818 PLUGIN_CLASS(IE_GUI_SCRIPT_CLASS_ID
, GUIScript
)