def OpenSaveWindow(): global SaveWindow, Games, ScrollBar global num_rows, ctrl_offset, sav_version, strs if GUICommon.CloseOtherWindow(OpenSaveWindow): GemRB.SetVar("OtherWindow", -1) CloseSaveWindow() return GemRB.GamePause(1, 3) GemRB.HideGUI() GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE) if GameCheck.IsIWD2(): GemRB.LoadWindowPack("GUISAVE", 800, 600) num_rows = 5 ctrl_offset = (55, 60, 25, 0x10000005, 0x1000000a, 23, 22, 3, 0x10000004, 40, 7, 8, 2) sav_version = 22 else: GemRB.LoadWindowPack("GUISAVE", 640, 480) if GameCheck.IsPST(): ctrl_offset = (14, 18, 22, 0x10000004, 0x10000008, 13, 46, 1, 0x10000002, 6, 4, 5, 3) strs = { 'cancel': 4196, 'save': 28645, 'delete': 28640, 'empty': 28647, 'overwrite': 28644, 'yousure': 28639 } SaveWindow = Window = GemRB.LoadWindow(0) Window.SetFrame() GemRB.SetVar("OtherWindow", SaveWindow.ID) # Cancel button CancelButton = Window.GetControl(ctrl_offset[6]) CancelButton.SetText(strs['cancel']) CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenSaveWindow) CancelButton.SetFlags(IE_GUI_BUTTON_CANCEL, OP_OR) GemRB.SetVar("SaveIdx", 0) for i in range(num_rows): Button = Window.GetControl(ctrl_offset[0] + i) Button.SetText(strs['save']) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenConfirmWindow) Button.SetState(IE_GUI_BUTTON_DISABLED) Button.SetVarAssoc("SaveIdx", i) Button = Window.GetControl(ctrl_offset[1] + i) Button.SetText(strs['delete']) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, DeleteGamePress) Button.SetState(IE_GUI_BUTTON_DISABLED) Button.SetVarAssoc("SaveIdx", i) # area previews Button = Window.GetControl(1 + i) Button.SetState(IE_GUI_BUTTON_LOCKED) Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PICTURE, OP_SET) # PC portraits for j in range(min(6, MAX_PARTY_SIZE)): Button = Window.GetControl(ctrl_offset[2] + i * min(6, MAX_PARTY_SIZE) + j) Button.SetState(IE_GUI_BUTTON_LOCKED) Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PICTURE, OP_SET) ScrollBar = Window.GetControl(ctrl_offset[5]) ScrollBar.SetEvent(IE_GUI_SCROLLBAR_ON_CHANGE, ScrollBarPress) Games = GemRB.GetSaveGames() TopIndex = max(0, len(Games) - num_rows + 1) #one more for the 'new game' GemRB.SetVar("TopIndex", TopIndex) ScrollBar.SetVarAssoc("TopIndex", TopIndex + 1) ScrollBar.SetDefaultScrollBar() ScrollBarPress() Window.SetVisible(WINDOW_VISIBLE) return
def SpellsDonePress(): """Move to the next assignable level. If there is not another assignable level, then save all the new spells and close the window.""" global SpellBook, SpellLevel, SpellsWindow, MemoBook, Memorization # oops, we were here before, just memorise the spells and exit if sum(MemoBook) > 0: for i in MemoBook: if i: GemRB.MemorizeSpell(pc, IE_SPELL_TYPE_WIZARD, SpellLevel, i - 1, 1) SpellBook = [] MemoBook = [0] * 24 # save all the spells if not Memorization: for i in range(len(Spells[SpellLevel])): if SpellBook[i]: # we need to learn this spell GemRB.LearnSpell(pc, Spells[SpellLevel][i][0]) # check to see if we need to update again for i in range(SpellLevel + 1, 9): if SpellsSelectPointsLeft[i] > 0: # reset the variables GemRB.SetVar("SpellTopIndex", 0) SpellLevel = i if not (chargen and GameCheck.IsBG1()): SpellBook = [0] * len(Spells[i]) if (EnhanceGUI): # setup the scrollbar ScrollBar = SpellsWindow.GetControl(1000) if len(Spells[i]) > (24 + ExtraSpellButtons()): HideUnhideScrollBar(0) if chargen: ScrollBar.SetVarAssoc( "SpellTopIndex", GUICommon.ceildiv( (len(Spells[i]) - 24), 6) + 1) else: ScrollBar.SetVarAssoc( "SpellTopIndex", GUICommon.ceildiv( (len(Spells[i]) - 25), 5) + 1) else: ScrollBar.SetVarAssoc("SpellTopIndex", 0) HideUnhideScrollBar(1) # show the spells and set the done button to off ShowSpells() DoneButton.SetState(IE_GUI_BUTTON_DISABLED) return # bg1 lets you memorize spells too (iwd too, but it does it by itself) # TODO: check iwd2, which is currently lacking all spell handling if chargen and GameCheck.IsBG1() and sum(MemoBook) == 0: SpellLevel = 0 SpellsSelectPointsLeft[SpellLevel] = 1 if KitMask != 0x4000: # specialists get an extra spell per level SpellsSelectPointsLeft[SpellLevel] += 1 DoneButton.SetState(IE_GUI_BUTTON_DISABLED) Memorization = 1 ShowKnownSpells() return # close our window and update our records if SpellsWindow and (not chargen or GameCheck.IsBG2()): SpellsWindow.Unload() SpellsWindow = None # move to the next script if this is chargen if chargen: if GameCheck.IsBG2(): # HACK GemRB.SetNextScript("GUICG6") elif GameCheck.IsBG1(): # HACK from CharGenCommon import next next() return
def ProfsRedraw (first=0): """Redraws the proficiencies part of the window. If first is true, it skips ahead to the first assignable proficiency.""" global ProfsTopIndex, ProfsScrollBar ProfSumLabel = ProfsWindow.GetControl(0x10000000+ProfsOffsetSum) ProfSumLabel.SetText(str(ProfsPointsLeft)) SkipProfs = [] for i in range(ProfsNumButtons): Pos=ProfsTopIndex+i ProfName = ProfsTable.GetValue(Pos+ProfsTableOffset, 1) #we add the bg1 skill count offset if ClassWeaponsTable: # iwd MaxProf = ClassWeaponsTable.GetValue (ClassNameSave, ProfsTable.GetRowName(Pos)) else: MaxProf = ProfsTable.GetValue(Pos+ProfsTableOffset, ProfsColumn) ProfName = ProfsTable.GetValue(Pos+ProfsTableOffset, 1) if ProfName > 0x1000000 or ProfName < 0: MaxProf = 0 cid = i*2+ProfsOffsetButton1 if Profs2ndOffsetButton1 != -1 and i > 7: cid = (i-8)*2+Profs2ndOffsetButton1 Button1=ProfsWindow.GetControl (cid) Button2=ProfsWindow.GetControl (cid+1) if MaxProf == 0: Button1.SetState(IE_GUI_BUTTON_DISABLED) Button2.SetState(IE_GUI_BUTTON_DISABLED) Button1.SetFlags(IE_GUI_BUTTON_NO_IMAGE,OP_OR) Button2.SetFlags(IE_GUI_BUTTON_NO_IMAGE,OP_OR) if GameCheck.IsBG2() and (i==0 or ((i-1) in SkipProfs)): SkipProfs.append (i) else: Button1.SetState(IE_GUI_BUTTON_ENABLED) Button2.SetState(IE_GUI_BUTTON_ENABLED) Button1.SetFlags(IE_GUI_BUTTON_NO_IMAGE,OP_NAND) Button2.SetFlags(IE_GUI_BUTTON_NO_IMAGE,OP_NAND) cid = 0x10000000 + ProfsOffsetLabel + i if Profs2ndOffsetLabel != -1 and i > 7: if OddIDs: cid = 0x10000000 + Profs2ndOffsetLabel + 2*(i - 8) else: cid = 0x10000000 + Profs2ndOffsetLabel + i - 8 Label=ProfsWindow.GetControl (cid) Label.SetText(ProfName) ActPoint = GemRB.GetVar("Prof "+str(Pos) ) for j in range(5): #5 is maximum distributable cid = i*5 + j + ProfsOffsetStar if Profs2ndOffsetStar != -1 and i > 7: cid = (i-8)*5 + j + Profs2ndOffsetStar Star=ProfsWindow.GetControl (cid) Star.SetSprites("GUIPFC", 0, 0, 0, 0, 0) if ActPoint > j: Star.SetFlags(IE_GUI_BUTTON_NO_IMAGE,OP_NAND) else: Star.SetFlags(IE_GUI_BUTTON_NO_IMAGE,OP_OR) if first and len (SkipProfs): ProfsTopIndex += SkipProfs[-1]+1 GemRB.SetVar ("ProfsTopIndex", ProfsTopIndex) if (ProfsScrollBar): ProfsScrollBar.SetVarAssoc ("ProfsTopIndex", ProfCount) ProfsRedraw () return
def IsDualClassed(actor, verbose): """Returns an array containing the dual class information. Return[0] is 0 if not dualclassed, 1 if the old class is a kit, 3 if the new class is a kit, 2 otherwise. Return[1] contains either the kit or class index of the old class. Return[2] contains the class index of the new class. If verbose is false, only Return[0] contains useable data.""" if GameCheck.IsIWD2(): return (0, -1, -1) Multi = HasMultiClassBits(actor) if Multi == 0: return (0, -1, -1) DualedFrom = GemRB.GetPlayerStat(actor, IE_MC_FLAGS) & MC_WAS_ANY_CLASS if verbose: KitIndex = GetKitIndex(actor) if KitIndex: KittedClass = CommonTables.KitList.GetValue(KitIndex, 7) KittedClassIndex = CommonTables.Classes.FindValue( "ID", KittedClass) else: KittedClassIndex = 0 if DualedFrom > 0: # first (previous) class of the dual class FirstClassIndex = CommonTables.Classes.FindValue( "MC_WAS_ID", DualedFrom) # use the first class of the multiclass bunch that isn't the same as the first class for i in range(1, 16): Mask = 1 << (i - 1) if Multi & Mask: ClassIndex = CommonTables.Classes.FindValue("ID", i) if ClassIndex == FirstClassIndex: continue SecondClassIndex = ClassIndex break else: GemRB.Log( LOG_WARNING, "IsDualClassed", "Invalid dualclass combination, treating as a single class!" ) print(DualedFrom, Multi, KitIndex, FirstClassIndex) return (0, -1, -1) if KittedClassIndex == FirstClassIndex and KitIndex: return (1, KitIndex, SecondClassIndex) elif KittedClassIndex == SecondClassIndex: return (3, FirstClassIndex, KitIndex) else: return (2, FirstClassIndex, SecondClassIndex) else: return (0, -1, -1) else: if DualedFrom > 0: return (1, -1, -1) else: return (0, -1, -1)
MemoBook = [ 0 ] * ButtonCount # array containing all the spell indexes to memorize Memorization = 0 # marker for the memorisation part SpellLevel = 0 # << current level of spells SpellStart = 0 # << starting id of the spell list SpellPointsLeftLabel = 0 # << label indicating the number of points left EnhanceGUI = 0 # << scrollbars and extra spell slot for sorcs on LU # chargen only SpellsPickButton = 0 # << button to select random spells SpellsCancelButton = 0 # << cancel chargen IWD2 = False SpellBookType = IE_SPELL_TYPE_WIZARD if GameCheck.IsIWD2(): WIDTH = 800 HEIGHT = 600 IWD2 = True else: WIDTH = 640 HEIGHT = 480 def OpenSpellsWindow(actor, table, level, diff, kit=0, gen=0, recommend=True,
def OpenOptionsWindow(): """Open main options window""" global GameOptionsWindow, OptionsWindow, PortraitWindow global OldPortraitWindow, OldOptionsWindow if GUICommon.CloseOtherWindow(OpenOptionsWindow): CloseOptionsWindow() return GemRB.GamePause(1, 3) CommonWindow.CloseContainerWindow() GemRB.HideGUI() GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE) if GameCheck.IsBG1(): GUICommonWindows.SetSelectionChangeHandler(None) GemRB.LoadWindowPack("GUIOPT", WIDTH, HEIGHT) GameOptionsWindow = Window = GemRB.LoadWindow(2) GemRB.SetVar("OtherWindow", GameOptionsWindow.ID) if OldOptionsWindow == None: # OptionsWindow is the leftmost menu bar window present in most of the games OldOptionsWindow = GUICommonWindows.OptionsWindow OptionsWindow = GemRB.LoadWindow(0) GUICommonWindows.MarkMenuButton(OptionsWindow) GUICommonWindows.SetupMenuWindowControls(OptionsWindow, 0, OpenOptionsWindow) OptionsWindow.SetFrame() if not GameCheck.IsBG1( ): #not in PST either, but it has its own OpenOptionsWindow() OptionsWindow.SetFrame() #saving the original portrait window OldPortraitWindow = GUICommonWindows.PortraitWindow PortraitWindow = GUICommonWindows.OpenPortraitWindow(0) # Return to Game Button = Window.GetControl(11) Button.SetText(10308) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenOptionsWindow) Button.SetFlags(IE_GUI_BUTTON_CANCEL, OP_OR) # Quit Game Button = Window.GetControl(10) Button.SetText(13731) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenQuitMsgWindow) # Load Game Button = Window.GetControl(5) Button.SetText(13729) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenLoadMsgWindow) # Save Game Button = Window.GetControl(6) Button.SetText(13730) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenSaveMsgWindow) # Video Options Button = Window.GetControl(7) Button.SetText(17162) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenVideoOptionsWindow) # Audio Options Button = Window.GetControl(8) Button.SetText(17164) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenAudioOptionsWindow) # Gameplay Options Button = Window.GetControl(9) Button.SetText(17165) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenGameplayOptionsWindow) # game version, e.g. v1.1.0000 VersionLabel = Window.GetControl(0x1000000b) VersionLabel.SetText(GEMRB_VERSION) if GameCheck.IsIWD2(): # Keyboard shortcuts KeyboardButton = Window.GetControl(13) KeyboardButton.SetText(33468) KeyboardButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenHotkeyOptionsWindow) # Movies MoviesButton = Window.GetControl(14) MoviesButton.SetText(15415) MoviesButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenMovieWindow) RestoreWinVisibility() return
def OpenItemAmountWindow (): """Open the split window.""" global UsedSlot, OverSlot global ItemAmountWindow, StackAmount pc = GemRB.GameGetSelectedPCSingle () if ItemAmountWindow != None: if ItemAmountWindow: ItemAmountWindow.Unload () ItemAmountWindow = None GemRB.SetRepeatClickFlags (GEM_RK_DISABLE, OP_OR) UsedSlot = None OverSlot = None GUIINV.UpdateInventoryWindow() return UsedSlot = GemRB.GetVar ("ItemButton") if GemRB.IsDraggingItem ()==1: GemRB.DropDraggedItem (pc, UsedSlot) #redraw slot UpdateSlot (pc, UsedSlot-1) # disallow splitting while holding split items (double splitting) if GemRB.IsDraggingItem () == 1: return slot_item = GemRB.GetSlotItem (pc, UsedSlot) if slot_item: StackAmount = slot_item["Usages0"] else: StackAmount = 0 if StackAmount<=1: UpdateSlot (pc, UsedSlot-1) return ResRef = slot_item['ItemResRef'] item = GemRB.GetItem (ResRef) ItemAmountWindow = Window = GemRB.LoadWindow (4) # item icon Icon = Window.GetControl (0) Icon.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_NO_IMAGE, OP_SET) Icon.SetItemIcon (ResRef) # item amount Text = Window.GetControl (6) # FIXME: use a proper size # FIXME: fix it for all the games if GameCheck.IsIWD2(): Text.SetSize (40, 40) Text.SetText (str (StackAmount//2)) Text.SetStatus (IE_GUI_EDIT_NUMBER|IE_GUI_CONTROL_FOCUSED) # Decrease Button = Window.GetControl (4) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DecreaseStackAmount) # Increase Button = Window.GetControl (3) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, IncreaseStackAmount) # Done Button = Window.GetControl (2) Button.SetText (11973) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DragItemAmount) Button.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR) # Cancel Button = Window.GetControl (1) Button.SetText (13727) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenItemAmountWindow) Button.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR) #GemRB.UnhideGUI () GemRB.SetRepeatClickFlags (GEM_RK_DISABLE, OP_NAND) Window.ShowModal (MODAL_SHADOW_GRAY) return
# of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # #character generation, export (GUICG21) import GemRB import GameCheck if GameCheck.IsBG1(): import GUICommon import CharGenCommon # export to a character file (.chr) ExportWindow = 0 TextAreaControl = 0 def OnLoad(): global ExportWindow, TextAreaControl ExportWindow = GemRB.LoadWindow (21, "GUICG") TextAreaControl = ExportWindow.GetControl (4) TextAreaControl.SetText (10962)
def StartTextScreen (): global TextScreen, TextArea, TableName, Row GemRB.GamePause (1, 3) ID = -1 MusicName = "*" Message = 17556 # default: Paused for chapter text TableName = GemRB.GetGameString (STR_TEXTSCREEN) #iwd2/bg2 has no separate music if GameCheck.IsIWD1(): if TableName == "": MusicName = "chap0" else: MusicName = "chap1" TableName = "chapters" elif GameCheck.IsIWD2(): TableName = "chapters" if TableName == "": EndTextScreen () return if GemRB.HasResource ("textscrn", RES_2DA, 1): TextTable = GemRB.LoadTable ("textscrn", 1) if TextTable != None: TxtRow = TextTable.GetRowIndex (TableName) if TxtRow >= 0: ID = TextTable.GetValue (TxtRow, 0) MusicName = TextTable.GetValue (TxtRow, 1) Message = TextTable.GetValue (TxtRow, 2) if Message != "*": GemRB.DisplayString (Message, 0xff0000) if GameCheck.IsIWD2(): GemRB.LoadWindowPack ("GUICHAP", 800, 600) else: GemRB.LoadWindowPack ("GUICHAP", 640, 480) Table = GemRB.LoadTable (TableName) if GameCheck.IsBG2(): LoadPic = Table.GetValue (-1, -1) if LoadPic.startswith ("*"): # BG2 epilogues ID = 63 LoadPic = LoadPic.replace ("*", "") else: ID = 62 elif ID == -1: #default: try to determine ID from current chapter ID = GemRB.GetGameVar("CHAPTER") & 0x7fffffff Chapter = ID + 1 if MusicName != "*": GemRB.LoadMusicPL (MusicName + ".mus") else: GemRB.HardEndPL () TextScreen = GemRB.LoadWindow (ID) TextScreen.SetFrame () TextArea = TextScreen.GetControl (2) if GameCheck.IsBG1(): #these suckers couldn't use a fix row FindTextRow (Table) elif GameCheck.IsBG2(): FindTextRow (Table) if LoadPic != "": if ID == 63: #only for BG2 epilogue windows PicButton = TextScreen.GetControl (4) PicButton.SetPicture (LoadPic) PicButton.SetState (IE_GUI_BUTTON_LOCKED) else: TextScreen.SetPicture (LoadPic) else: Row = Chapter #caption Value = Table.GetValue (Row, 0) #don't display the fake -1 string (No caption in toscst.2da) if Value!="NONE" and Value>0 and TextScreen.HasControl(0x10000000): Label=TextScreen.GetControl (0x10000000) Label.SetText (Value) #done Button=TextScreen.GetControl (0) Button.SetText (11973) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, EndTextScreen) Button.SetFlags (IE_GUI_BUTTON_DEFAULT|IE_GUI_BUTTON_CANCEL,OP_OR) #replay Button=TextScreen.GetControl (3) Button.SetText (16510) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ReplayTextScreen) #if this was opened from somewhere other than game control close that window GUICommon.CloseOtherWindow(None) GemRB.HideGUI () GUICommon.GameWindow.SetVisible(WINDOW_INVISIBLE) #removing the gamecontrol screen TextScreen.SetVisible (WINDOW_VISIBLE) TextScreen.ShowModal (MODAL_SHADOW_NONE) ReplayTextScreen() return
def OnLoad (): global PartyFormationWindow GUICommonWindows.PortraitWindow = None GUICommonWindows.SelectionChangeHandler = None GemRB.LoadWindowPack ("GUISP", 640, 480) PartyFormationWindow = GemRB.LoadWindow (0) PartyFormationWindow.SetFrame () ModifyCharsButton = PartyFormationWindow.GetControl (43) ModifyCharsButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, None) #TODO: ModifyPress ModifyCharsButton.SetStatus (IE_GUI_BUTTON_DISABLED) ModifyCharsButton.SetText (18816) ExitButton = PartyFormationWindow.GetControl (30) ExitButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ExitPress) ExitButton.SetStatus (IE_GUI_BUTTON_ENABLED) ExitButton.SetText (13906) ExitButton.SetFlags (IE_GUI_BUTTON_CANCEL, OP_OR) DoneButton = PartyFormationWindow.GetControl (28) DoneButton.SetText (11973) Portraits = 0 for i in range(18,24): Label = PartyFormationWindow.GetControl (0x10000012+i) #removing this label, it just disturbs us Label.SetSize (0, 0) Button = PartyFormationWindow.GetControl (i-12) ResRef = GemRB.GetPlayerPortrait (i-17, 1) if ResRef == "": Button.SetFlags (IE_GUI_BUTTON_NORMAL,OP_SET) else: Button.SetPicture (ResRef, "NOPORTSM") Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR) Portraits = Portraits+1 Button.SetState (IE_GUI_BUTTON_LOCKED) CreateCharButton = PartyFormationWindow.GetControl (i) CreateCharButton.SetVarAssoc ("Slot", i-17) CreateCharButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CreateCharPress) CreateCharButton.SetStatus (IE_GUI_BUTTON_ENABLED) CreateCharButton.SetFont ("NORMAL") if ResRef == "": CreateCharButton.SetText (10264) else: CreateCharButton.SetText (GemRB.GetPlayerName (i-17,0) ) if Portraits == 0: DoneButton.SetState (IE_GUI_BUTTON_DISABLED) else: DoneButton.SetState (IE_GUI_BUTTON_ENABLED) DoneButton.SetFlags (IE_GUI_BUTTON_DEFAULT, OP_OR) DoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, EnterGamePress) if not GameCheck.HasHOW(): GemRB.SetVar ("PlayMode",0) #using second row?? else: GemRB.SetGlobal ("EXPANSION_DOOR", "GLOBAL", 1) # entrance to the HOW start if GameCheck.HasTOTL(): GemRB.SetGlobal ("9101_SPAWN_HOBART", "GLOBAL", 1) if GemRB.GetVar("ExpansionGame") == 1: GemRB.SetGlobal ("CHAPTER", "GLOBAL", 1) GemRB.SetVar ("PlayMode",2) #using second row else: GemRB.SetVar ("PlayMode",0) #using first row GemRB.SetToken ("SaveDir", "mpsave") LoadScreen.CloseLoadScreen() PartyFormationWindow.SetVisible (WINDOW_VISIBLE) return
def SetupSkillsWindow(pc, skilltype, window, callback, level1=[0, 0, 0], level2=[1, 1, 1], classid=0, scroll=True): global SkillsWindow, SkillsCallback, SkillsOffsetPress, SkillsOffsetButton1, SkillsOffsetName global SkillsOffsetPoints, SkillsOffsetSum, SkillsIndices, SkillPointsLeft global SkillsTable, SkillsOldPos, SkillsClickCount, SkillsOldDirection, SkillsNumButtons global SkillsTextArea, SkillsKitName, SkillsAssignable, SkillsLabelIncrement #reset some basic values SkillLeftPress = SkillIncreasePress SkillRightPress = SkillDecreasePress SkillsWindow = window SkillsCallback = callback SkillsOldPos = 0 SkillsClickCount = 0 SkillsOldDirection = 0 SkillsAssignable = 0 SkillsTable = GemRB.LoadTable("skills") SkillPointsLeft = 0 GemRB.SetVar("SkillPointsLeft", 0) SkillsNullify() ScrollBar = None #make sure we're within ranges if not window or not callback or len(level1) != len(level2): return #setup the offsets if skilltype == LUSKILLS_TYPE_LEVELUP and GameCheck.IsBG2(): SkillsOffsetPress = 120 SkillsOffsetButton1 = 17 SkillsOffsetSum = 37 SkillsOffsetName = 32 SkillsOffsetPoints = 43 SkillsNumButtons = 4 SkillsTextArea = SkillsWindow.GetControl(110) ScrollBar = SkillsWindow.GetControl(109) elif skilltype == LUSKILLS_TYPE_LEVELUP and GameCheck.IsPST(): SkillsOffsetPress = -1 SkillsOffsetButton1 = 16 SkillsOffsetSum = 6 SkillsOffsetName = 7 SkillsOffsetPoints = 8 SkillsNumButtons = 4 SkillsLabelIncrement = 2 #The order of the buttons is the opposite of the other games SkillLeftPress = SkillDecreasePress SkillRightPress = SkillIncreasePress #There is actually no hint text to describe the skills, so this is a dummy SkillsWindow.CreateTextArea(45, 1, 1, 1, 1, "FONTDLG") SkillsTextArea = SkillsWindow.GetControl(45) elif skilltype == LUSKILLS_TYPE_LEVELUP: SkillsOffsetPress = -1 SkillsOffsetButton1 = 17 SkillsOffsetSum = 37 SkillsOffsetName = 32 SkillsOffsetPoints = 43 SkillsNumButtons = 4 SkillsTextArea = SkillsWindow.GetControl(42) if (scroll): ScrollBar = SkillsWindow.GetControl(109) elif skilltype == LUSKILLS_TYPE_DUALCLASS: SkillsOffsetPress = 5 SkillsOffsetButton1 = 14 SkillsOffsetSum = 8 SkillsOffsetName = 0 SkillsOffsetPoints = 9 SkillsNumButtons = 4 SkillsTextArea = SkillsWindow.GetControl(22) SkillsTextArea.SetText(17248) if (scroll): ScrollBar = SkillsWindow.GetControl(26) SkillsWindow.SetEventProxy(ScrollBar) elif skilltype == LUSKILLS_TYPE_CHARGEN: SkillsOffsetPress = 21 SkillsOffsetButton1 = 11 SkillsOffsetSum = 5 SkillsOffsetName = 6 SkillsOffsetPoints = 1 SkillsNumButtons = 4 SkillsTextArea = SkillsWindow.GetControl(19) SkillsTextArea.SetText(17248) if (scroll): ScrollBar = SkillsWindow.GetControl(26) SkillsWindow.SetEventProxy(ScrollBar) else: return if ScrollBar: ScrollBar.SetVarAssoc("SkillsTopIndex", 0, 0, 0) #get our class id and name IsDual = GUICommon.IsDualClassed(pc, 1) IsMulti = GUICommon.IsMultiClassed(pc, 1) if classid: #used when dual-classing Class = classid elif IsDual[0] == 3: Class = CommonTables.KitList.GetValue(IsDual[2], 7) elif IsDual[0]: #only care about the current class Class = GUICommon.GetClassRowName(IsDual[2], "index") Class = CommonTables.Classes.GetValue(Class, "ID") else: Class = GemRB.GetPlayerStat(pc, IE_CLASS) ClassName = GUICommon.GetClassRowName(Class, "class") #get the number of classes if IsMulti[0] > 1: NumClasses = IsMulti[0] else: NumClasses = 1 if NumClasses > len(level2): return #figure out the kitname if we need it #protect against kitted multiclasses Kit = GUICommon.GetKitIndex(pc) if not Kit or skilltype == LUSKILLS_TYPE_DUALCLASS or IsDual[0] in [ 1, 2 ] or IsMulti[0] > 1: SkillsKitName = ClassName else: SkillsKitName = CommonTables.KitList.GetValue(Kit, 0, GTV_STR) # also treat most mod-introduced kits as kitless for skills.2da # lookups - unless they add the required columns if SkillsTable.GetValue("OPEN_LOCKS", SkillsKitName) == -1: SkillsKitName = ClassName #figure out the correct skills table SkillIndex = -1 for i in range(NumClasses): TmpClass = Class if NumClasses > 1: TmpClass = IsMulti[i + 1] TmpClass = GUICommon.GetClassRowName(TmpClass, "class") if (CommonTables.ClassSkills.GetValue(TmpClass, "THIEFSKILL", GTV_STR) != "*"): SkillIndex = i break #see if we got a thief (or monk) SkillsIndices = [] if SkillIndex >= 0: #SkillsKitName should be fine as all multis are in classes.2da #also allows for thief kits SkillsAssignable = 1 for i in range(SkillsTable.GetRowCount() - 2): # -2/+2 to compensate for the special first_level and rate rows SkillName = SkillsTable.GetRowName(i + 2) if SkillsTable.GetValue(SkillName, SkillsKitName) != -1: SkillsIndices.append(i) LevelDiff = [] for i in range(NumClasses): LevelDiff.append(level2[i] - level1[i]) if level1[SkillIndex] == 0: SkillPointsLeft = SkillsTable.GetValue("FIRST_LEVEL", SkillsKitName, GTV_INT) LevelDiff[SkillIndex] -= 1 SkillPointsLeft += LevelDiff[SkillIndex] * SkillsTable.GetValue( "RATE", SkillsKitName, GTV_INT) TotalSkillsAssignable = 0 if SkillPointsLeft < 0: #really don't have an entry SkillPointsLeft = 0 else: #get the skill values for i in range(SkillsTable.GetRowCount() - 2): # -2/+2 to compensate for the special first_level and rate rows SkillName = SkillsTable.GetRowName(i + 2) SkillID = SkillsTable.GetValue(SkillName, "ID") SkillValue = GemRB.GetPlayerStat(pc, SkillID) BaseSkillValue = GemRB.GetPlayerStat(pc, SkillID, 1) GemRB.SetVar("Skill " + str(i), SkillValue) GemRB.SetVar("SkillBase " + str(i), SkillValue) # display the modified stat to avoid confusion (account for dex, race and effect boni) GemRB.SetVar("SkillDisplayMod " + str(i), SkillValue - BaseSkillValue) TotalSkillsAssignable += LUSKILLS_MAX - SkillValue #protect against having more skills than we can assign if SkillPointsLeft > TotalSkillsAssignable: SkillPointsLeft = TotalSkillsAssignable GemRB.SetVar("SkillPointsLeft", SkillPointsLeft) else: #get ranger and bard skills SpecialSkillsMap = [] for i in range(NumClasses): if IsMulti[0] > 1: classname = IsMulti[i + 1] else: classname = Class classname = GUICommon.GetClassRowName(classname, "class") for table in "RANGERSKILL", "BARDSKILL": SpecialSkillsTable = CommonTables.ClassSkills.GetValue( classname, table) if SpecialSkillsTable != "*": SpecialSkillsMap.append((SpecialSkillsTable, i)) break for skills in SpecialSkillsMap: SpecialSkillsTable = GemRB.LoadTable(skills[0]) for skill in range(SpecialSkillsTable.GetColumnCount()): skillname = SpecialSkillsTable.GetColumnName(skill) value = SpecialSkillsTable.GetValue(str(level2[skills[1]]), skillname) skillindex = SkillsTable.GetRowIndex(skillname) - 2 GemRB.SetVar("Skill " + str(skillindex), value) SkillsIndices.append(skillindex) #we didn't find anything, so don't continue (will show as a return of 0) #or don't display if we aren't leveling and have a bard/ranger if not len(SkillsIndices) or (not SkillPointsLeft and skilltype != LUSKILLS_TYPE_LEVELUP): SkillSumLabel = SkillsWindow.GetControl(0x10000000 + SkillsOffsetSum) SkillSumLabel.SetText("") return #skills scrollbar if len(SkillsIndices) > SkillsNumButtons: ScrollBar.SetEvent(IE_GUI_SCROLLBAR_ON_CHANGE, lambda: SkillsRedraw()) #decrease it with the number of controls on screen (list size) and two unrelated rows maxvalue = SkillsTable.GetRowCount() - SkillsNumButtons - 2 ScrollBar.SetVarAssoc("SkillsTopIndex", 0, 0, maxvalue) Button = SkillsWindow.GetControl(SkillsOffsetPress) AddScrollbarProxy(SkillsWindow, ScrollBar, Button) else: GemRB.SetVar("SkillsTopIndex", 0) #setup all the visible buttons for i in range(len(SkillsIndices)): if i == SkillsNumButtons: break if SkillsOffsetPress != -1: Button = SkillsWindow.GetControl(i + SkillsOffsetPress) Button.SetVarAssoc("Skill", SkillsIndices[i]) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, SkillJustPress) Button = SkillsWindow.GetControl(i * 2 + SkillsOffsetButton1) Button.SetVarAssoc("Skill", SkillsIndices[i]) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, SkillLeftPress) Button.SetActionInterval(20) Button = SkillsWindow.GetControl(i * 2 + SkillsOffsetButton1 + 1) Button.SetVarAssoc("Skill", SkillsIndices[i]) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, SkillRightPress) Button.SetActionInterval(20) SkillsRedraw() return
def CanLevelUp(actor): """Returns true if the actor can level up.""" # get our class and placements for Multi'd and Dual'd characters Class = GUICommon.GetClassRowName (actor) Multi = GUICommon.IsMultiClassed (actor, 1) Dual = GUICommon.IsDualClassed (actor, 1) # get all the levels and overall xp here xp = GemRB.GetPlayerStat (actor, IE_XP) Levels = [GemRB.GetPlayerStat (actor, IE_LEVEL), GemRB.GetPlayerStat (actor, IE_LEVEL2),\ GemRB.GetPlayerStat (actor, IE_LEVEL3)] if GemRB.GetPlayerStat(actor, IE_LEVELDRAIN)>0: return 0 if GameCheck.IsIWD2(): import GUIREC levelsum = GemRB.GetPlayerStat (actor, IE_CLASSLEVELSUM) nextXP = GUIREC.GetNextLevelExp (levelsum, GUIREC.GetECL (actor)) return nextXP <= xp # hardcoded special case to handle TNO, who is usually a single class # but with three separate Levels/XP values and the ability to switch between them # it returns the active class if true SwitcherClass = GUICommon.NamelessOneClass(actor) if SwitcherClass: xp = { "FIGHTER" : GemRB.GetPlayerStat (actor, IE_XP), "MAGE" : GemRB.GetPlayerStat (actor, IE_XP_MAGE), "THIEF" : GemRB.GetPlayerStat (actor, IE_XP_THIEF) } lvls = { "FIGHTER" : Levels[0] , "MAGE": Levels[1], "THIEF": Levels [2] } tmpNext = GetNextLevelExp (lvls[SwitcherClass], SwitcherClass) if (tmpNext != 0 or lvls[SwitcherClass] == 0) and tmpNext <= xp[SwitcherClass]: return 1 #ignore the rest of this function, to avoid false positives #other classes can only be achieved by hacking the game somehow return 0 if Multi[0] > 1: # multiclassed xp = xp // Multi[0] # divide the xp evenly between the classes for i in range (Multi[0]): # if any class can level, return 1 TmpClassName = GUICommon.GetClassRowName (Multi[i+1], "class") tmpNext = GetNextLevelExp (Levels[i], TmpClassName) if (tmpNext != 0 or Levels[i] == 0) and tmpNext <= xp: return 1 # didn't find a class that could level return 0 elif Dual[0] > 0: # dual classed # get the class we can level if Dual[0] == 3: ClassID = CommonTables.KitList.GetValue (Dual[2], 7) Class = GUICommon.GetClassRowName (ClassID, "class") else: Class = GUICommon.GetClassRowName(Dual[2], "index") if GUICommon.IsDualSwap(actor): Levels = [Levels[1], Levels[0], Levels[2]] # check the class that can be level (single or dual) tmpNext = GetNextLevelExp (Levels[0], Class) return ((tmpNext != 0 or Levels[0] == 0) and tmpNext <= xp)
def ApplyFeats(MyChar): #don't mess with feats outside of IWD2 if not GameCheck.IsIWD2(): return #feats giving a single innate ability SetSpell(MyChar, "SPIN111", FEAT_WILDSHAPE_BOAR) SetSpell(MyChar, "SPIN197", FEAT_MAXIMIZED_ATTACKS) SetSpell(MyChar, "SPIN231", FEAT_ENVENOM_WEAPON) SetSpell(MyChar, "SPIN245", FEAT_WILDSHAPE_PANTHER) SetSpell(MyChar, "SPIN246", FEAT_WILDSHAPE_SHAMBLER) SetSpell(MyChar, "SPIN275", FEAT_POWER_ATTACK) SetSpell(MyChar, "SPIN276", FEAT_EXPERTISE) SetSpell(MyChar, "SPIN277", FEAT_ARTERIAL_STRIKE) SetSpell(MyChar, "SPIN278", FEAT_HAMSTRING) SetSpell(MyChar, "SPIN279", FEAT_RAPID_SHOT) #extra rage level = GemRB.GetPlayerStat(MyChar, IE_LEVELBARBARIAN) if level>0: if level>=15: GemRB.RemoveSpell(MyChar, "SPIN236") Spell = "SPIN260" else: GemRB.RemoveSpell(MyChar, "SPIN260") Spell = "SPIN236" cnt = GemRB.GetPlayerStat (MyChar, IE_FEAT_EXTRA_RAGE) + (level + 3) // 4 GUICommon.MakeSpellCount(MyChar, Spell, cnt) else: GemRB.RemoveSpell(MyChar, "SPIN236") GemRB.RemoveSpell(MyChar, "SPIN260") #extra smiting level = GemRB.GetPlayerStat(MyChar, IE_LEVELPALADIN) if level>1: cnt = GemRB.GetPlayerStat (MyChar, IE_FEAT_EXTRA_SMITING) + 1 GUICommon.MakeSpellCount(MyChar, "SPIN152", cnt) else: GemRB.RemoveSpell(MyChar, "SPIN152") #extra turning level = GemRB.GetPlayerStat(MyChar, IE_TURNUNDEADLEVEL) if level>0: cnt = GUICommon.GetAbilityBonus(MyChar, IE_CHR) + 3 if cnt<1: cnt = 1 cnt += GemRB.GetPlayerStat (MyChar, IE_FEAT_EXTRA_TURNING) GUICommon.MakeSpellCount(MyChar, "SPIN970", cnt) else: GemRB.RemoveSpell(MyChar, "SPIN970") #stunning fist if GemRB.HasFeat (MyChar, FEAT_STUNNING_FIST): cnt = GemRB.GetPlayerStat(MyChar, IE_CLASSLEVELSUM) // 4 GUICommon.MakeSpellCount(MyChar, "SPIN232", cnt) else: GemRB.RemoveSpell(MyChar, "SPIN232") #remove any previous SPLFOCUS #GemRB.ApplyEffect(MyChar, "RemoveEffects",0,0,"SPLFOCUS") #spell focus stats SPLFocusTable = GemRB.LoadTable ("splfocus") for i in range(SPLFocusTable.GetRowCount()): Row = SPLFocusTable.GetRowName(i) Stat = SPLFocusTable.GetValue(Row, "STAT", GTV_STAT) if Stat: Column = GemRB.GetPlayerStat(MyChar, Stat) if Column: Value = SPLFocusTable.GetValue(i, Column) if Value: #add the effect, value could be 2 or 4, timing mode is 8 - so it is not saved GemRB.ApplyEffect(MyChar, "SpellFocus", Value, i,"","","","SPLFOCUS", 8) return
def SetupHP (pc, Level=None, LevelDiff=None): """Updates an actors hp based upon level. Level should contain the actors current level. LevelDiff should contain the change in levels. Level and LevelDiff must be of the same length. If either are None, they are filled with the actors current level.""" Levels, NumClasses, Class = _SetupLevels (pc, Level, noclass=1) LevelDiffs, NumClasses, Class = _SetupLevels (pc, LevelDiff, noclass=1) if len (Levels) != len (LevelDiffs): return #adjust the class for multi/dual chars Class = [GemRB.GetPlayerStat (pc, IE_CLASS)] Multi = GUICommon.IsMultiClassed (pc, 1) Dual = GUICommon.IsDualClassed (pc, 1) NumClasses = 1 if Multi[0]>1: #get each of the multi-classes NumClasses = Multi[0] Class = [Multi[1], Multi[2], Multi[3]] elif Dual[0]: #only worry about the newer class #we only get the hp bonus if the old class is reactivated if (Levels[0]<=Levels[1]): return if Dual[0] == 3: Class = [CommonTables.KitList.GetValue (Dual[2], 7)] else: ClassRow = GUICommon.GetClassRowName(Dual[2], "index") Class = [CommonTables.Classes.GetValue (ClassRow, "ID")] #if Level and LevelDiff are passed, we assume it is correct if GUICommon.IsDualSwap(pc) and not Level and not LevelDiff: LevelDiffs = [LevelDiffs[1], LevelDiffs[0], LevelDiffs[2]] elif GameCheck.IsIWD2(): Class = GetAllClasses (Levels) if NumClasses>len(Levels): return #get the correct hp for barbarians Kit = GUICommon.GetKitIndex (pc) ClassName = None if Kit and not Dual[0] and Multi[0]<2: KitName = CommonTables.KitList.GetValue (Kit, 0, GTV_STR) if CommonTables.Classes.GetRowIndex (KitName) >= 0: ClassName = KitName # determine the minimum hp roll ConBonTable = GemRB.LoadTable ("hpconbon") MinRoll = ConBonTable.GetValue (GemRB.GetPlayerStat (pc, IE_CON)-1, 2) # MIN_ROLL column #loop through each class and update the hp OldHP = GemRB.GetPlayerStat (pc, IE_MAXHITPOINTS, 1) CurrentHP = 0 Divisor = float (NumClasses) if GameCheck.IsIWD2(): # hack around so we can reuse more of the main loop NumClasses = len(Levels) Divisor = 1.0 for i in range (NumClasses): if GameCheck.IsIWD2() and not Class[i]: continue #check this classes hp table for any gain if not ClassName or NumClasses > 1: ClassName = GUICommon.GetClassRowName (Class[i], "class") HPTable = CommonTables.Classes.GetValue (ClassName, "HP") HPTable = GemRB.LoadTable (HPTable) #make sure we are within table ranges MaxLevel = HPTable.GetRowCount()-1 LowLevel = Levels[i]-LevelDiffs[i] HiLevel = Levels[i] if LowLevel >= HiLevel: continue if LowLevel < 0: LowLevel = 0 elif LowLevel > MaxLevel: LowLevel = MaxLevel if HiLevel < 0: HiLevel = 0 elif HiLevel > MaxLevel: HiLevel = MaxLevel #add all the hp for the given level #we use ceil to ensure each class gets hp for level in range(LowLevel, HiLevel): sides = HPTable.GetValue (level, 0) rolls = HPTable.GetValue (level, 1) bonus = HPTable.GetValue (level, 2) # we only do a roll on core difficulty or higher # and if maximum HP rolls (bg2 and later) are disabled # and/or if it is bg1 chargen (I guess too many testers got annoyed) # BUT when we do roll, constitution gives a kind of a luck bonus to the roll if rolls: if GemRB.GetVar ("Difficulty Level") >= 3 and not GemRB.GetVar ("Maximum HP") \ and not (GameCheck.IsBG1() and LowLevel == 0) and MinRoll < sides: if MinRoll > 1: roll = GemRB.Roll (rolls, sides, bonus) if roll-bonus < MinRoll: roll = MinRoll + bonus AddedHP = int (roll / Divisor + 0.5) else: AddedHP = int (GemRB.Roll (rolls, sides, bonus) / Divisor + 0.5) else: AddedHP = int ((rolls * sides + bonus) / Divisor + 0.5) else: AddedHP = int (bonus / Divisor + 0.5) # ensure atleast 1hp is given # this is safe for inactive dualclass levels too (handled above) if AddedHP == 0: AddedHP = 1 CurrentHP += AddedHP #update our hp values GemRB.SetPlayerStat (pc, IE_MAXHITPOINTS, CurrentHP+OldHP) # HACK: account also for the new constitution bonus for the current hitpoints GemRB.SetPlayerStat (pc, IE_HITPOINTS, GemRB.GetPlayerStat (pc, IE_HITPOINTS, 1)+CurrentHP+5) return
from GUIDefines import * ################################################### GameOptionsWindow = None # not in PST PortraitWindow = None # not in BG1 or PST OldPortraitWindow = None #not in BG1 or PST OptionsWindow = None OldOptionsWindow = None HelpTextArea = None LoadMsgWindow = None QuitMsgWindow = None SubOptionsWindow = None SubSubOptionsWindow = None if GameCheck.IsBG1(): HelpTextArea2 = None else: # just an alias to keep our logic from being plagued by too many GameCheck.IsBG1() checks HelpTextArea2 = HelpTextArea if GameCheck.IsIWD2(): WIDTH = 800 HEIGHT = 600 else: WIDTH = 640 HEIGHT = 480 ################################################### def CloseOptionsWindow():
def OnLoad(): # Lay on hands, turn undead and backstab multiplier get set by the core # set my character up MyChar = GemRB.GetVar("Slot") ClassName = GUICommon.GetClassRowName(MyChar) IsMulti = GUICommon.IsMultiClassed(MyChar, 1) Levels = [GemRB.GetPlayerStat (MyChar, IE_LEVEL), GemRB.GetPlayerStat (MyChar, IE_LEVEL2), \ GemRB.GetPlayerStat (MyChar, IE_LEVEL3)] # weapon proficiencies # set the base number of attacks; effects will add the proficiency bonus # 2 means 1 attack, because this is the number of attacks in 2 rounds GemRB.SetPlayerStat(MyChar, IE_NUMBEROFATTACKS, 2) #lore, thac0, hp, and saves GemRB.SetPlayerStat(MyChar, IE_MAXHITPOINTS, 0) GemRB.SetPlayerStat(MyChar, IE_HITPOINTS, 0) LUCommon.SetupSavingThrows(MyChar) LUCommon.SetupThaco(MyChar) LUCommon.SetupLore(MyChar) LUCommon.SetupHP(MyChar) # mage spells TableName = CommonTables.ClassSkills.GetValue(ClassName, "MAGESPELL", GTV_STR) if TableName != "*": index = 0 if IsMulti[0] > 1: #find out which class gets mage spells for i in range(IsMulti[0]): TmpClassName = GUICommon.GetClassRowName( IsMulti[i + 1], "class") if CommonTables.ClassSkills.GetValue(TmpClassName, "MAGESPELL", GTV_STR) != "*": index = i break Spellbook.SetupSpellLevels(MyChar, TableName, IE_SPELL_TYPE_WIZARD, Levels[index]) # apply class/kit abilities GUICommon.ResolveClassAbilities(MyChar, ClassName) # alignment based bhaal powers are added in FixInnates later # unless we're starting with SoA if GemRB.GetVar("oldgame") == 1: AlignmentAbbrev = CommonTables.Aligns.FindValue( "VALUE", GemRB.GetPlayerStat(MyChar, IE_ALIGNMENT)) GUICommon.AddClassAbilities(MyChar, "abstart", 6, 6, AlignmentAbbrev) # setup starting gold (uses a roll dictated by class TmpTable = GemRB.LoadTable("strtgold") temp = GemRB.Roll(TmpTable.GetValue(ClassName, "ROLLS"), TmpTable.GetValue(ClassName, "SIDES"), TmpTable.GetValue(ClassName, "MODIFIER")) GemRB.SetPlayerStat(MyChar, IE_GOLD, temp * TmpTable.GetValue(ClassName, "MULTIPLIER")) # save the appearance GUICommon.SetColorStat(MyChar, IE_HAIR_COLOR, GemRB.GetVar("HairColor")) GUICommon.SetColorStat(MyChar, IE_SKIN_COLOR, GemRB.GetVar("SkinColor")) GUICommon.SetColorStat(MyChar, IE_MAJOR_COLOR, GemRB.GetVar("MajorColor")) GUICommon.SetColorStat(MyChar, IE_MINOR_COLOR, GemRB.GetVar("MinorColor")) #GUICommon.SetColorStat (MyChar, IE_METAL_COLOR, 0x1B ) #GUICommon.SetColorStat (MyChar, IE_LEATHER_COLOR, 0x16 ) #GUICommon.SetColorStat (MyChar, IE_ARMOR_COLOR, 0x17 ) GemRB.SetPlayerStat(MyChar, IE_EA, 2) # save the name and starting xp (can level right away in game) GemRB.SetPlayerName(MyChar, GemRB.GetToken("CHARNAME"), 0) # does all the rest LargePortrait = GemRB.GetToken("LargePortrait") SmallPortrait = GemRB.GetToken("SmallPortrait") GemRB.FillPlayerInfo(MyChar, LargePortrait, SmallPortrait) # biography Bio = GemRB.GetToken("BIO") BioStrRef = 33347 if Bio: BioStrRef = 62016 GemRB.CreateString(BioStrRef, Bio) GemRB.SetPlayerString(MyChar, 74, BioStrRef) if GameCheck.IsTOB(): # will also add the starting inventory for tob GemRB.GameSetExpansion(4) # no torture, let's refresh all the spells, at least for sorcerers # TODO: autopick memorisations for mages? Did they have a memorisation choice step like in bg1? GemRB.ChargeSpells(MyChar) playmode = GemRB.GetVar("PlayMode") if playmode >= 0: GemRB.SaveCharacter(MyChar, "gembak") #LETS PLAY!! GemRB.EnterGame() GemRB.ExecuteString("EquipMostDamagingMelee()", MyChar) else: #when export is done, go to start if GameCheck.HasTOB(): GemRB.SetToken("NextScript", "Start2") else: GemRB.SetToken("NextScript", "Start") GemRB.SetNextScript("ExportFile") #export return
def OpenAutopauseOptionsWindow(): """Open autopause options window""" global SubSubOptionsWindow, HelpTextArea2 Window = SubSubOptionsWindow CloseSubSubOptionsWindow() Window = GemRB.LoadWindow(10) HelpTextArea2 = GUIOPTControls.OptHelpText('AutopauseOptions', Window, 15, 18044) GUIOPTControls.OptDone(CloseAutopauseOptionsWindow, Window, 11) GUIOPTControls.OptCancel(CloseAutopauseOptionsWindow, Window, 14) # checkboxes OR the values if they associate to the same variable GUIOPTControls.OptCheckbox(18044, 18032, HelpTextArea2, Window, 1, 17, 17155, 'Auto Pause State', None, 4) # hit GUIOPTControls.OptCheckbox(18044, 18033, HelpTextArea2, Window, 2, 18, 17156, 'Auto Pause State', None, 8) # wounded GUIOPTControls.OptCheckbox(18044, 18034, HelpTextArea2, Window, 3, 19, 17157, 'Auto Pause State', None, 16) # dead GUIOPTControls.OptCheckbox(18044, 18035, HelpTextArea2, Window, 4, 20, 17158, 'Auto Pause State', None, 2) # attacked GUIOPTControls.OptCheckbox(18044, 18036, HelpTextArea2, Window, 5, 21, 17159, 'Auto Pause State', None, 1) # weapon unusable GUIOPTControls.OptCheckbox(18044, 18037, HelpTextArea2, Window, 13, 22, 17160, 'Auto Pause State', None, 32) # target gone GUIOPTControls.OptCheckbox(18044, 10640, HelpTextArea2, Window, 25, 24, 10639, 'Auto Pause State', None, 64) # end of round if GameCheck.IsIWD2(): GUIOPTControls.OptCheckbox(18044, 23514, HelpTextArea2, Window, 30, 31, 23516, 'Auto Pause State', None, 128) # enemy sighted GUIOPTControls.OptCheckbox(18044, 18560, HelpTextArea2, Window, 26, 28, 16519, 'Auto Pause State', None, 256) # trap found GUIOPTControls.OptCheckbox(18044, 26311, HelpTextArea2, Window, 36, 37, 26310, 'Auto Pause State', None, 512) # spell cast GUIOPTControls.OptCheckbox(18044, 24888, HelpTextArea2, Window, 33, 34, 10574, 'Auto Pause Center', None, 1) elif not GameCheck.IsIWD1() and Window.HasControl(26, IE_GUI_BUTTON): GUIOPTControls.OptCheckbox(18044, 23514, HelpTextArea2, Window, 26, 27, 23516, 'Auto Pause State', None, 128) # enemy sighted if GameCheck.IsBG2(): GUIOPTControls.OptCheckbox(18044, 58171, HelpTextArea2, Window, 31, 30, 31875, 'Auto Pause State', None, 512) # spell cast GUIOPTControls.OptCheckbox(18044, 31872, HelpTextArea2, Window, 34, 33, 57354, 'Auto Pause State', None, 256) # trap found GUIOPTControls.OptCheckbox(18044, 10571, HelpTextArea2, Window, 37, 36, 10574, 'Auto Pause Center', None, 1) SubSubOptionsWindow = Window Window.ShowModal(MODAL_SHADOW_GRAY) return
GemRB.GameSetScreenFlags(Expand + GSFlags, OP_SET) ################################################################## # functions dealing with containers ################################################################## import GUICommon import GUIClasses import GUIWORLD from ie_stats import * from GUIDefines import * ContainerWindow = None Container = None if GameCheck.IsIWD2(): leftdiv = 5 ground_size = 10 else: leftdiv = 3 ground_size = 6 if GameCheck.IsPST(): import GUICommonWindows def UpdateContainerWindow(): global Container Window = ContainerWindow
def DisplayItem (slotItem, type): global ItemInfoWindow item = GemRB.GetItem (slotItem["ItemResRef"]) ItemInfoWindow = Window = GemRB.LoadWindow (5) if GameCheck.IsPST(): strrefs = [ 1403, 4256, 4255, 4251, 4252, 4254, 4279 ] else: strrefs = [ 11973, 14133, 11960, 19392, 17104, item["DialogName"], 17108 ] # item name Label = Window.GetControl (0x10000000) if (type&2): text = item["ItemName"] else: text = item["ItemNameIdentified"] Label.SetText (text) #item icon Button = Window.GetControl (2) if GameCheck.IsPST(): Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_NO_IMAGE, OP_SET) Button.SetItemIcon (slotItem["ItemResRef"]) else: Button.SetFlags (IE_GUI_BUTTON_PICTURE, OP_OR) Button.SetItemIcon (slotItem["ItemResRef"], 0) Button.SetState (IE_GUI_BUTTON_LOCKED) #middle button Button = Window.GetControl (4) Button.SetText (strrefs[0]) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, CloseItemInfoWindow) Button.SetFlags (IE_GUI_BUTTON_CANCEL|IE_GUI_BUTTON_DEFAULT, OP_OR) #textarea Text = Window.GetControl (5) if (type&2): text = item["ItemDesc"] else: text = item["ItemDescIdentified"] Text.Clear () Text.Append (text) #left button Button = Window.GetControl(8) select = (type&1) and (item["Function"]&ITM_F_ABILITIES) if type&2: Button.SetText (strrefs[1]) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, IdentifyItemWindow) elif select and not GameCheck.IsPST(): Button.SetText (strrefs[2]) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, AbilitiesItemWindow) else: Button.SetState (IE_GUI_BUTTON_LOCKED) Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET) # description icon (not present in iwds) if not GameCheck.IsIWD1() and not GameCheck.IsIWD2(): Button = Window.GetControl (7) Button.SetFlags (IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_CENTER_PICTURES | IE_GUI_BUTTON_NO_IMAGE, OP_OR) if GameCheck.IsPST(): Button.SetItemIcon (slotItem["ItemResRef"], 1) # no DescIcon else: Button.SetItemIcon (slotItem["ItemResRef"], 2) Button.SetState (IE_GUI_BUTTON_LOCKED) #right button Button = Window.GetControl(9) drink = (type&1) and (item["Function"]&ITM_F_DRINK) read = (type&1) and (item["Function"]&ITM_F_READ) # sorcerers cannot learn spells pc = GemRB.GameGetSelectedPCSingle () if Spellbook.HasSorcererBook (pc): read = 0 container = (type&1) and (item["Function"]&ITM_F_CONTAINER) dialog = (type&1) and (item["Dialog"]!="" and item["Dialog"]!="*") familiar = (type&1) and (item["Type"] == 38) # perhaps it's true everywhere, but it's definitely needed in pst # and yes, the check is reversed, so the bit name is a misnomer in this case if GameCheck.IsPST() and slotItem["Flags"] & IE_INV_ITEM_CONVERSABLE: dialog = False drink = True # "Use" if drink: Button.SetText (strrefs[3]) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ConsumeItem) elif read: Button.SetText (strrefs[4]) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ReadItemWindow) elif container: # Just skip the redundant info page and go directly to the container if GemRB.GetVar("GUIEnhancements")&GE_ALWAYS_OPEN_CONTAINER_ITEMS: OpenItemWindow() return if GameCheck.IsIWD2() or GameCheck.IsHOW(): Button.SetText (24891) # Open Container elif GameCheck.IsBG2(): Button.SetText (44002) # open container else: # a fallback, since the originals have nothing appropriate # FIXME: where do mods add the new string? This is untranslatable Button.SetText ("Open container") Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenItemWindow) elif dialog: Button.SetText (strrefs[5]) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DialogItemWindow) elif familiar and not GameCheck.IsPST(): # PST earings share a type with familiars, so no # mods that allow familiars would be possible in PST Button.SetText (4373) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, ReleaseFamiliar) else: Button.SetState (IE_GUI_BUTTON_LOCKED) Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET) Label = Window.HasControl(0x1000000b) if Label: Label = Window.GetControl (0x1000000b) if (type&2): # NOT IDENTIFIED Label.SetText (strrefs[6]) else: Label.SetText ("") # in pst one can cycle through all the items from the description window if Window.HasControl (14): #left scroll Button = Window.GetControl (13) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIINV.LeftItemScroll) #right scroll Button = Window.GetControl (14) Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIINV.RightItemScroll) ItemInfoWindow.ShowModal(MODAL_SHADOW_GRAY) return
def OpenContainerWindow(): global ContainerWindow, Container if ContainerWindow: return hideflag = GemRB.HideGUI() GemRB.LoadWindowPack(GUICommon.GetWindowPack()) ContainerWindow = Window = GemRB.LoadWindow(8) #stop gears from interfering if GameCheck.IsPST(): GUIWORLD.OldPortraitWindow = GUIClasses.GWindow( GemRB.GetVar("PortraitWindow")) GUICommonWindows.DisableAnimatedWindows() if GameCheck.IsIWD2(): GUIWORLD.OldMessageWindow = GUIClasses.GWindow( GemRB.GetVar("MessageWindow")) GemRB.SetVar("MessageWindow", Window.ID) else: GUIWORLD.OldActionsWindow = GUIClasses.GWindow( GemRB.GetVar("ActionsWindow")) GUIWORLD.OldMessageWindow = GUIClasses.GWindow( GemRB.GetVar("MessageWindow")) GemRB.SetVar("MessageWindow", -1) GemRB.SetVar("ActionsWindow", Window.ID) Container = GemRB.GetContainer(0) # Gears (time) when options pane is down if GameCheck.IsBG2(): Button = Window.GetControl(62) Label = Button.CreateLabelOnButton(0x1000003e, "NORMAL", IE_FONT_SINGLE_LINE) Label.SetAnimation("CPEN") Button.SetAnimation("CGEAR") Button.SetBAM("CDIAL", 0, 0) Button.SetState(IE_GUI_BUTTON_ENABLED) Button.SetFlags( IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_ANIMATED | IE_GUI_BUTTON_NORMAL, OP_SET) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUICommon.GearsClicked) GUICommon.SetGamedaysAndHourToken() Button.SetTooltip(16041) # 0-5 - Ground Item for i in range(ground_size): Button = Window.GetControl(i) Button.SetVarAssoc("LeftIndex", i) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, TakeItemContainer) if GameCheck.IsPST(): Button.SetFont("NUMBER") Button.SetFlags( IE_GUI_BUTTON_ALIGN_RIGHT | IE_GUI_BUTTON_ALIGN_BOTTOM, OP_OR) # 10-13 - Personal Item for i in range(4): Button = Window.GetControl(i + 10) Button.SetVarAssoc("RightIndex", i) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, DropItemContainer) if GameCheck.IsPST(): Button.SetFont("NUMBER") Button.SetFlags( IE_GUI_BUTTON_ALIGN_RIGHT | IE_GUI_BUTTON_ALIGN_BOTTOM, OP_OR) # left scrollbar (container) ScrollBar = Window.GetControl(52) ScrollBar.SetEvent(IE_GUI_SCROLLBAR_ON_CHANGE, RedrawContainerWindow) # right scrollbar (inventory) ScrollBar = Window.GetControl(53) ScrollBar.SetEvent(IE_GUI_SCROLLBAR_ON_CHANGE, RedrawContainerWindow) # encumbrance and inventory icon # iwd has a handy button if Window.HasControl(54): Button = Window.GetControl(54) if GameCheck.IsPST(): Button.SetFont("NUMBER") Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE, OP_SET) Button.CreateLabelOnButton( 0x10000043, "NUMBER", IE_FONT_ALIGN_LEFT | IE_FONT_ALIGN_TOP | IE_FONT_SINGLE_LINE) Button.CreateLabelOnButton( 0x10000044, "NUMBER", IE_FONT_ALIGN_RIGHT | IE_FONT_ALIGN_BOTTOM | IE_FONT_SINGLE_LINE) else: Label = Window.CreateLabel( 0x10000043, 323, 14, 60, 15, "NUMBER", "0:", IE_FONT_ALIGN_LEFT | IE_FONT_ALIGN_TOP | IE_FONT_SINGLE_LINE) Label = Window.CreateLabel( 0x10000044, 323, 20, 80, 15, "NUMBER", "0:", IE_FONT_ALIGN_RIGHT | IE_FONT_ALIGN_TOP | IE_FONT_SINGLE_LINE) # container icon Button = Window.GetControl(50) if GameCheck.IsPST(): Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE, OP_SET) Button.SetState(IE_GUI_BUTTON_LOCKED) if not GameCheck.IsPST(): Table = GemRB.LoadTable("containr") row = Container['Type'] tmp = Table.GetValue(row, 0) if tmp != '*': GemRB.PlaySound(tmp) tmp = Table.GetValue(row, 1) if tmp != '*': Button.SetSprites(tmp, 0, 0, 0, 0, 0) # Done Button = Window.GetControl(51) if GameCheck.IsPST(): Button.SetText(1403) else: Button.SetText("") Button.SetFlags(IE_GUI_BUTTON_CANCEL, OP_OR) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, LeaveContainer) GemRB.SetVar("LeftTopIndex", 0) GemRB.SetVar("RightTopIndex", 0) UpdateContainerWindow() if hideflag: GemRB.UnhideGUI()
def GetGUISpellButtonCount(): if GameCheck.HasHOW() or GameCheck.IsBG2(): return 24 else: return 20
# GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # GUIOPTControls.py - control functions for the GUIOPT winpack: ################################################### import GameCheck from GUIDefines import * ################################################### # strrefs if GameCheck.IsPST(): STR_OPT_DONE = 1403 STR_OPT_CANCEL = 4196 else: STR_OPT_DONE = 11973 STR_OPT_CANCEL = 13727 ################################################### # These functions help to setup controls found # in Video, Audio, Gameplay, Feedback and Autopause # options windows # These controls are usually made from an active # control (button, slider ...) and a label
def OpenFloatMenuWindow(x, y): if GameCheck.IsPST(): import FloatMenuWindow FloatMenuWindow.OpenFloatMenuWindow(x, y) else: GemRB.GameControlSetTargetMode(TARGET_MODE_NONE)
import collections import GemRB import GameCheck import GUICommon import Portrait from GUIDefines import * from ie_stats import IE_SEX, IE_RACE, IE_MC_FLAGS, MC_EXPORTABLE from ie_restype import RES_WAV CustomizeWindow = None ExportWindow = None NameField = ExportDoneButton = None ScriptsTable = None RevertButton = None if GameCheck.IsBG2() or GameCheck.IsBG1(): BioStrRefSlot = 74 else: BioStrRefSlot = 63 if GameCheck.IsBG2() or GameCheck.IsIWD2(): PortraitNameSuffix = "L" else: PortraitNameSuffix = "G" PortraitPictureButton = None PortraitList1 = PortraitList2 = RowCount1 = RowCount2 = None # the available sounds if GameCheck.IsIWD1() or GameCheck.IsIWD2(): SoundSequence = [ '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', \
def RemoveKnownSpells (pc, type, level1=1, level2=1, noslots=0, kit=0): """Removes all known spells of a given type between two spell levels. If noslots is true, all memorization counts are set to 0. Kit is used to identify the priest spell mask of the spells to be removed; this is only used when removing spells in a dualclass.""" # choose the correct limit based upon class type if type == IE_SPELL_TYPE_WIZARD or GameCheck.IsIWD2(): limit = 9 elif type == IE_SPELL_TYPE_PRIEST: limit = 7 # make sure that we get the original kit, if we have one if kit: import GUICommon originalkit = GUICommon.GetKitIndex (pc) if originalkit: # kitted; find the class value originalkit = CommonTables.KitList.GetValue (originalkit, 7) else: # just get the class value originalkit = GemRB.GetPlayerStat (pc, IE_CLASS) originalkit = GUICommon.GetClassRowName (originalkit, "class") # this is is specifically for dual-classes and will not work to remove only one # spell type from a ranger/cleric multi-class if CommonTables.ClassSkills.GetValue (originalkit, "DRUIDSPELL", GTV_STR) != "*": # knows druid spells originalkit = 0x8000 elif CommonTables.ClassSkills.GetValue (originalkit, "CLERICSPELL", GTV_STR) != "*": # knows cleric spells originalkit = 0x4000 else: # don't know any other spells originalkit = 0 # don't know how this would happen, but better to be safe if originalkit == kit: originalkit = 0 elif type == IE_SPELL_TYPE_INNATE: limit = 1 else: # can't do anything if an improper spell type is sent return 0 if GameCheck.IsIWD2(): kit = 0 # just skip the dualclass logic # make sure we're within parameters if level1 < 1 or level2 > limit or level1 > level2: return 0 # remove all spells for each level for level in range (level1-1, level2): # we need the count because we remove each spell in reverse order count = GemRB.GetKnownSpellsCount (pc, type, level) mod = count-1 for spell in range (count): # see if we need to check for kit if type == IE_SPELL_TYPE_PRIEST and kit: # get the spell's ref data ref = GemRB.GetKnownSpell (pc, type, level, mod-spell) ref = GemRB.GetSpell (ref['SpellResRef'], 1) # we have to look at the originalkit as well specifically for ranger/cleric dual-classes # we wouldn't want to remove all cleric spells and druid spells if we lost our cleric class # only the cleric ones if kit&ref['SpellDivine'] or (originalkit and not originalkit&ref['SpellDivine']): continue # remove the spell GemRB.RemoveSpell (pc, type, level, mod-spell) # remove memorization counts if desired if noslots: GemRB.SetMemorizableSpellsCount (pc, 0, type, level) # return success return 1
def OpenCustomizeWindow(): import GUIREC global CustomizeWindow, ScriptsTable, Gender pc = GemRB.GameGetSelectedPCSingle() if GemRB.GetPlayerStat(pc, IE_MC_FLAGS) & MC_EXPORTABLE: Exportable = 1 else: Exportable = 0 ScriptsTable = GemRB.LoadTable("SCRPDESC") GUIREC.ColorTable = GemRB.LoadTable("CLOWNCOL") Gender = GemRB.GetPlayerStat(pc, IE_SEX) CustomizeWindow = GemRB.LoadWindow(17) PortraitSelectButton = CustomizeWindow.GetControl(0) PortraitSelectButton.SetText(11961) if not Exportable: PortraitSelectButton.SetState(IE_GUI_BUTTON_DISABLED) SoundButton = CustomizeWindow.GetControl(1) SoundButton.SetText(10647) if not Exportable: SoundButton.SetState(IE_GUI_BUTTON_DISABLED) if not GameCheck.IsIWD2(): ColorButton = CustomizeWindow.GetControl(2) ColorButton.SetText(10646) ColorButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, GUIREC.OpenColorWindow) if not Exportable: ColorButton.SetState(IE_GUI_BUTTON_DISABLED) ScriptButton = CustomizeWindow.GetControl(3) ScriptButton.SetText(17111) #This button does not exist in bg1 and pst, but theoretically we could create it here if not (GameCheck.IsBG1() or GameCheck.IsPST()): BiographyButton = CustomizeWindow.GetControl(9) BiographyButton.SetText(18003) BiographyButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenBiographyEditWindow) if not Exportable: BiographyButton.SetState(IE_GUI_BUTTON_DISABLED) TextArea = CustomizeWindow.GetControl(5) TextArea.SetText(11327) CustomizeDoneButton = CustomizeWindow.GetControl(7) CustomizeDoneButton.SetText(11973) CustomizeDoneButton.SetState(IE_GUI_BUTTON_ENABLED) CancelButton = CustomizeWindow.GetControl(8) CancelButton.SetText(13727) CancelButton.MakeEscape() PortraitSelectButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenPortraitSelectWindow) SoundButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenSoundWindow) ScriptButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenScriptWindow) CustomizeDoneButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, lambda: CustomizeWindow.Close()) CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, lambda: CustomizeWindow.Close( )) # FIXME: this should revert changes I assume CustomizeWindow.ShowModal(MODAL_SHADOW_GRAY) return
def OpenSpellsWindow(actor, table, level, diff, kit=0, gen=0, recommend=True): """Opens the spells selection window. table should refer to the name of the classes MXSPLxxx.2da. level contains the current level of the actor. diff contains the difference from the old level. kit should always be GetKitIndex except when dualclassing. gen is true if this is for character generation. recommend is used in bg2 for spell recommendation / autopick.""" global SpellsWindow, DoneButton, SpellsSelectPointsLeft, Spells, chargen, SpellPointsLeftLabel global SpellsTextArea, SpellsKnownTable, SpellTopIndex, SpellBook, SpellLevel, pc, SpellStart global KitMask, EnhanceGUI, Memorization #enhance GUI? if (GemRB.GetVar("GUIEnhancements") & GE_SCROLLBARS): EnhanceGUI = 1 # save our pc pc = actor chargen = gen # this ensures compatibility with chargen, sorc, and dual-classing if kit == 0: KitMask = 0x4000 else: # need to implement this if converted to CharGen KitMask = kit # make sure there is an entry at the given level (bard) SpellsKnownTable = GemRB.LoadTable(table) if not SpellsKnownTable.GetValue(str(level), str(1), 1): if chargen: if GameCheck.IsBG2(): # HACK GemRB.SetNextScript("GUICG6") elif GameCheck.IsBG1(): # HACK from CharGenCommon import next next() return # load our window if chargen: GemRB.LoadWindowPack("GUICG", 640, 480) SpellsWindow = GemRB.LoadWindow(7) if not recommend: GUICommon.CloseOtherWindow(SpellsWindow.Unload) DoneButton = SpellsWindow.GetControl(0) SpellsTextArea = SpellsWindow.GetControl(27) SpellPointsLeftLabel = SpellsWindow.GetControl(0x1000001b) if (EnhanceGUI): SpellsWindow.CreateScrollBar(1000, 325, 42, 16, 252) HideUnhideScrollBar(1) SpellStart = 2 # cancel button only applicable for chargen SpellsCancelButton = SpellsWindow.GetControl(29) SpellsCancelButton.SetState(IE_GUI_BUTTON_ENABLED) SpellsCancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SpellsCancelPress) SpellsCancelButton.SetText(13727) SpellsCancelButton.SetFlags(IE_GUI_BUTTON_CANCEL, OP_OR) if (recommend): # recommended spell picks SpellsPickButton = SpellsWindow.GetControl(30) SpellsPickButton.SetState(IE_GUI_BUTTON_ENABLED) SpellsPickButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SpellsPickPress) SpellsPickButton.SetText(34210) else: SpellsWindow = GemRB.LoadWindow(8) DoneButton = SpellsWindow.GetControl(28) SpellsTextArea = SpellsWindow.GetControl(26) SpellPointsLeftLabel = SpellsWindow.GetControl(0x10000018) if (EnhanceGUI): SpellsWindow.CreateScrollBar(1000, 290, 142, 16, 252) HideUnhideScrollBar(1) #25th spell button for sorcerers SpellsWindow.CreateButton(24, 231, 345, 42, 42) SpellStart = 0 # setup our variables GemRB.SetVar("SpellTopIndex", 0) Memorization = 0 # the done button also doubles as a next button DoneButton.SetState(IE_GUI_BUTTON_DISABLED) DoneButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, SpellsDonePress) DoneButton.SetText(11973) DoneButton.SetFlags(IE_GUI_BUTTON_DEFAULT, OP_OR) AlreadyShown = 0 for i in range(9): # make sure we always have a value to minus (bards) SecondPoints = SpellsKnownTable.GetValue(str(level - diff), str(i + 1), 1) if not SecondPoints: SecondPoints = 0 # make sure we get more spells of each class before continuing SpellsSelectPointsLeft[i] = SpellsKnownTable.GetValue( str(level), str(i + 1), 1) - SecondPoints if SpellsSelectPointsLeft[i] <= 0: continue elif chargen and KitMask != 0x4000: # specialists get an extra spell per level SpellsSelectPointsLeft[i] += 1 # chargen character seem to get more spells per level (this is kinda dirty hack) # except sorcerers if chargen and GemRB.GetPlayerStat(pc, IE_CLASS) != 19: SpellsSelectPointsLeft[i] += 1 # get all the spells of the given level Spells[i] = Spellbook.GetMageSpells( KitMask, GemRB.GetPlayerStat(pc, IE_ALIGNMENT), i + 1) # dump all the spells we already know NumDeleted = 0 for j in range(len(Spells[i])): CurrentIndex = j - NumDeleted # this ensure we don't go out of range if Spellbook.HasSpell(pc, IE_SPELL_TYPE_WIZARD, i, Spells[i][CurrentIndex][0]) >= 0: del Spells[i][CurrentIndex] NumDeleted += 1 # display these spells if it's the first non-zero level if AlreadyShown == 0: # save the level and spellbook data SpellLevel = i SpellBook = [0] * len(Spells[i]) if (EnhanceGUI): # setup the scrollbar ScrollBar = SpellsWindow.GetControl(1000) ScrollBar.SetEvent(IE_GUI_SCROLLBAR_ON_CHANGE, ShowSpells) ScrollBar.SetDefaultScrollBar() # only scroll if we have more than 24 spells or 25 if extra 25th spell slot is available in sorcs LevelUp if len(Spells[i]) > (24 + ExtraSpellButtons()): HideUnhideScrollBar(0) if chargen: ScrollBar.SetVarAssoc( "SpellTopIndex", GUICommon.ceildiv((len(Spells[i]) - 24), 6) + 1) else: #there are five rows of 5 spells in level up of sorcs ScrollBar.SetVarAssoc( "SpellTopIndex", GUICommon.ceildiv((len(Spells[i]) - 25), 5) + 1) else: ScrollBar.SetVarAssoc("SpellTopIndex", 0) HideUnhideScrollBar(1) # show our spells ShowSpells() AlreadyShown = 1 # show the selection window if chargen: if recommend: SpellsWindow.SetVisible(WINDOW_VISIBLE) else: SpellsWindow.ShowModal(MODAL_SHADOW_NONE) else: SpellsWindow.ShowModal(MODAL_SHADOW_GRAY) return
def UpdateMageWindow(): global MageMemorizedSpellList, MageKnownSpellList MageMemorizedSpellList = [] MageKnownSpellList = [] Window = MageWindow pc = GemRB.GameGetSelectedPCSingle() type = IE_SPELL_TYPE_WIZARD level = MageSpellLevel max_mem_cnt = GemRB.GetMemorizableSpellsCount(pc, type, level, 1) Label = Window.GetControl(0x10000032) if GameCheck.IsBG2(): GemRB.SetToken("SPELLLEVEL", str(level + 1)) Label.SetText(10345) else: GemRB.SetToken('LEVEL', str(level + 1)) Label.SetText(12137) Name = GemRB.GetPlayerName(pc, 0) Label = Window.GetControl(0x10000035) Label.SetText(Name) known_cnt = GemRB.GetKnownSpellsCount(pc, type, level) mem_cnt = GemRB.GetMemorizedSpellsCount(pc, type, level, False) true_mem_cnt = GemRB.GetMemorizedSpellsCount(pc, type, level, True) if not BookType: for i in range(12): Button = Window.GetControl(3 + i) Button.SetAnimation("") if i < mem_cnt: ms = GemRB.GetMemorizedSpell(pc, type, level, i) Button.SetSpellIcon(ms['SpellResRef'], 0) Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE, OP_NAND) Button.SetFlags(IE_GUI_BUTTON_PICTURE | IE_GUI_BUTTON_PLAYONCE, OP_OR) if ms['Flags']: Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, OpenMageSpellUnmemorizeWindow) else: Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, OnMageUnmemorizeSpell) Button.SetEvent(IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenMageSpellInfoWindow) MageMemorizedSpellList.append(ms['SpellResRef']) Button.SetVarAssoc("SpellButton", i) Button.EnableBorder(0, ms['Flags'] == 0) spell = GemRB.GetSpell(ms['SpellResRef']) if not spell: print "Missing memorised spell!", ms['SpellResRef'] continue Button.SetTooltip(spell['SpellName']) else: if i < max_mem_cnt: Button.SetFlags( IE_GUI_BUTTON_NORMAL | IE_GUI_BUTTON_PLAYONCE, OP_SET) else: Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE, OP_SET) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, None) Button.SetEvent(IE_GUI_BUTTON_ON_RIGHT_PRESS, None) Button.SetTooltip('') Button.EnableBorder(0, 0) else: label = Window.GetControl(0x10000040) if known_cnt: # we give sorcerers all charges for all the spells, so some extra math is needed label.SetText( GemRB.GetString(61256) + " " + str(true_mem_cnt / known_cnt) + "/" + str(max_mem_cnt)) else: label.SetText("") for i in range(GUICommon.GetGUISpellButtonCount()): Button = Window.GetControl(27 + i) Button.SetAnimation("") if i < known_cnt: ks = GemRB.GetKnownSpell(pc, type, level, i) Button.SetSpellIcon(ks['SpellResRef'], 0) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, OnMageMemorizeSpell) Button.SetEvent(IE_GUI_BUTTON_ON_RIGHT_PRESS, OpenMageSpellInfoWindow) MageKnownSpellList.append(ks['SpellResRef']) Button.SetVarAssoc("SpellButton", 100 + i) spell = GemRB.GetSpell(ks['SpellResRef']) if not spell: print "Missing known spell!", ms['SpellResRef'] continue Button.SetTooltip(spell['SpellName']) else: Button.SetFlags(IE_GUI_BUTTON_PICTURE, OP_NAND) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, None) Button.SetEvent(IE_GUI_BUTTON_ON_RIGHT_PRESS, None) Button.SetTooltip('') Button.EnableBorder(0, 0) CantCast = CommonTables.ClassSkills.GetValue(GUICommon.GetClassRowName(pc), "MAGESPELL") == "*" GUICommon.AdjustWindowVisibility(Window, pc, CantCast) return
def SetupProfsWindow (pc, type, window, callback, level1=[0,0,0], level2=[1,1,1], classid=0, scroll=True, profTableOffset=8): """Opens the proficiency selection window. type specifies the type of selection we are doing; choices are above. window specifies the window to be updated. callback specifies the function to call on changes. classid is sent only during dualclassing to specify the new class.""" global ProfsOffsetSum, ProfsOffsetButton1, ProfsOffsetLabel, ProfsOffsetStar, OddIDs global ProfsOffsetPress, ProfsPointsLeft, ProfsNumButtons, ProfsTopIndex global ProfsScrollBar, ProfsTableOffset, ProfsType global ProfsWindow, ProfsCallback, ProfsTextArea, ProfsColumn, ProfsTable, ProfCount global Profs2ndOffsetButton1, Profs2ndOffsetStar, Profs2ndOffsetLabel, ClassNameSave, ClassWeaponsTable # make sure we're within ranges GemRB.SetVar ("ProfsPointsLeft", 0) if not window or not callback or len(level1)!=len(level2): return # save the values we'll point to ProfsWindow = window ProfsCallback = callback ProfsTableOffset = profTableOffset ProfsType = type if type == LUPROFS_TYPE_CHARGEN and GameCheck.IsBG2(): #chargen ProfsOffsetSum = 9 ProfsOffsetButton1 = 11 ProfsOffsetStar = 27 ProfsOffsetLabel = 1 ProfsOffsetPress = 69 ProfsNumButtons = 8 ProfsTextArea = ProfsWindow.GetControl (68) ProfsTextArea.SetText (9588) if (scroll): ProfsScrollBar = ProfsWindow.GetControl (78) elif type == LUPROFS_TYPE_CHARGEN and GameCheck.IsBG1(): #chargen ProfsOffsetSum = 9 ProfsOffsetButton1 = 11 ProfsOffsetStar = 27 ProfsOffsetLabel = 1 ProfsOffsetPress = 69 ProfsNumButtons = 8 ProfsTextArea = ProfsWindow.GetControl (68) ProfsTextArea.SetText (9588) if (scroll): ProfsScrollBar = ProfsWindow.GetControl (78) elif type == LUPROFS_TYPE_LEVELUP and GameCheck.IsBG2(): #levelup ProfsOffsetSum = 36 ProfsOffsetButton1 = 1 ProfsOffsetStar = 48 ProfsOffsetLabel = 24 ProfsOffsetPress = 112 ProfsNumButtons = 7 ProfsTextArea = ProfsWindow.GetControl (110) ProfsScrollBar = ProfsWindow.GetControl (108) elif type == LUPROFS_TYPE_LEVELUP and GameCheck.IsBG1(): #levelup ProfsOffsetSum = 36 ProfsOffsetButton1 = 1 ProfsOffsetStar = 48 ProfsOffsetLabel = 24 ProfsOffsetPress = 17 ProfsNumButtons = 8 ProfsTextArea = ProfsWindow.GetControl (42) if (scroll): ProfsScrollBar = ProfsWindow.GetControl (108) elif type == LUPROFS_TYPE_LEVELUP and GameCheck.IsIWD1(): #levelup ProfsOffsetSum = 36 ProfsOffsetButton1 = 1 ProfsOffsetStar = 48 ProfsOffsetLabel = 24 ProfsOffsetPress = -1 ProfsNumButtons = 15 # 8+7, the 7 are done with the following vars Profs2ndOffsetButton1 = 150 Profs2ndOffsetStar = 115 Profs2ndOffsetLabel = 108 ProfsTextArea = ProfsWindow.GetControl (42) if (scroll): ProfsScrollBar = ProfsWindow.GetControl (108) OddIDs = 0 elif type == LUPROFS_TYPE_DUALCLASS and GameCheck.IsIWD1(): #dualclass ProfsOffsetSum = 40 ProfsOffsetButton1 = 50 ProfsOffsetStar = 0 ProfsOffsetLabel = 41 ProfsOffsetPress = -1 #66 ProfsNumButtons = 15 Profs2ndOffsetButton1 = 78 Profs2ndOffsetStar = 92 Profs2ndOffsetLabel = 126 ProfsTextArea = ProfsWindow.GetControl (74) ProfsTextArea.SetText (9588) if (scroll): ProfsScrollBar = ProfsWindow.GetControl (None) OddIDs = 1 elif type == LUPROFS_TYPE_DUALCLASS and GameCheck.IsBG1(): #dualclass ProfsOffsetSum = 40 ProfsOffsetButton1 = 50 ProfsOffsetStar = 0 ProfsOffsetLabel = 41 ProfsOffsetPress = -1 #FIXME ProfsNumButtons = 8 ProfsTextArea = ProfsWindow.GetControl (74) ProfsTextArea.SetText (9588) if (scroll): ProfsScrollBar = ProfsWindow.GetControl (None) elif type == LUPROFS_TYPE_DUALCLASS: #dualclass ProfsOffsetSum = 40 ProfsOffsetButton1 = 50 ProfsOffsetStar = 0 ProfsOffsetLabel = 41 ProfsOffsetPress = 66 ProfsNumButtons = 8 ProfsTextArea = ProfsWindow.GetControl (74) ProfsTextArea.SetText (9588) if (scroll): ProfsScrollBar = ProfsWindow.GetControl (78) else: #unknown return #nullify internal variables GemRB.SetVar ("ProfsTopIndex", 0) ProfsPointsLeft = 0 ProfsTopIndex = 0 ProfsTable = GemRB.LoadTable ("profs") if GameCheck.IsIWD1() or GameCheck.IsBG1(): ClassWeaponsTable = GemRB.LoadTable ("clasweap") else: ClassWeaponsTable = None #get the class name IsDual = GUICommon.IsDualClassed (pc, 1) if classid: #for dual classes when we can't get the class dualing to Class = classid elif IsDual[0]: Class = GUICommon.GetClassRowName(IsDual[2], "index") Class = CommonTables.Classes.GetValue (Class, "ID") else: Class = GemRB.GetPlayerStat (pc, IE_CLASS) ClassName = GUICommon.GetClassRowName (Class, "class") # profs.2da has entries for everyone, so no need to muck around ProfsRate = ProfsTable.GetValue (ClassName, "RATE") #figure out how many prof points we have if sum (level1) == 0: #character is being generated (either chargen or dual) ProfsPointsLeft = ProfsTable.GetValue (ClassName, "FIRST_LEVEL") ProfIndex = 0 IsMulti = GUICommon.IsMultiClassed (pc, 1) if IsMulti[0] > 1: if sum (level1) == 0: #character is being generated (either chargen or dual) # don't give too many points; exact formula unknown, but this works with f/m and f/m/t ProfsPointsLeft += sum(level2)/IsMulti[0]/ProfsRate else: # just look at the fastest prof-gaining class in the bunch and consider their level # eg. a m/t should get a point at 3/4 and 7/8 (rate of 4) BestRate = 100 for cls in IsMulti[1:]: if cls == 0: break ClsName = GUICommon.GetClassRowName (cls, "class") Rate = ProfsTable.GetValue (ClsName, "RATE") if Rate < BestRate: BestRate = Rate ProfIndex = IsMulti[1:].index(cls) ProfsPointsLeft += level2[ProfIndex]/ProfsRate - level1[ProfIndex]/ProfsRate else: if GUICommon.IsDualSwap (pc): ProfIndex = 1 #we need these 2 number to floor before subtracting ProfsPointsLeft += level2[ProfIndex]/ProfsRate - level1[ProfIndex]/ProfsRate #setup prof vars for passing between functions ProfsTable = GemRB.LoadTable ("weapprof") # weapprof has no sorcerer entry if ClassName == "SORCERER": ClassName = "MAGE" ClassNameSave = ClassName # if we have the classweapons table, use it if ClassWeaponsTable: ProfsColumn = ClassWeaponsTable.GetRowIndex (ClassName) else: Kit = GUICommon.GetKitIndex (pc) if Kit and type != LUPROFS_TYPE_DUALCLASS and IsMulti[0]<2 and not IsDual[0]: #if we do kit with dualclass, we'll get the old kit #also don't want to worry about kitted multis ProfsColumn = CommonTables.KitList.GetValue (Kit, 5) else: ProfsColumn = ProfsTable.GetColumnIndex (ClassName) #setup some basic counts RowCount = ProfsTable.GetRowCount () - ProfsTableOffset + 1 ProfCount = RowCount-ProfsNumButtons #decrease it with the number of controls ProfsAssignable = 0 TwoWeapIndex = ProfsTable.GetRowIndex ("2WEAPON") for i in range(RowCount): ProfName = ProfsTable.GetValue (i+ProfsTableOffset, 1) #decrease it with the number of invalid proficiencies if ProfName > 0x1000000 or ProfName < 0: ProfCount -= 1 #we only need the low 3 bits for proficiencies on levelup; otherwise #we just set them all to 0 currentprof = 0 if type == LUPROFS_TYPE_LEVELUP: stat = ProfsTable.GetValue (i+ProfsTableOffset, 0) if GameCheck.IsBG1(): stat = stat + IE_PROFICIENCYBASTARDSWORD currentprof = GemRB.GetPlayerStat (pc, stat)&0x07 else: #rangers always get 2 points in 2 weapons style if (i+ProfsTableOffset) == TwoWeapIndex and "RANGER" in ClassName.split("_"): currentprof = 2 GemRB.SetVar ("Prof "+str(i), currentprof) GemRB.SetVar ("ProfBase "+str(i), currentprof) #see if we can assign to this prof if ClassWeaponsTable: # this table has profs as rows, so ignore the wierd use of the column var # it also has different ordering than ProfsTable col = ClassWeaponsTable.GetColumnIndex (ProfsTable.GetRowName(i)) maxprof = ClassWeaponsTable.GetValue (ProfsColumn, col) else: maxprof = ProfsTable.GetValue(i+ProfsTableOffset, ProfsColumn) if maxprof > currentprof: ProfsAssignable += maxprof-currentprof #correct the profs left if we can't assign that much if ProfsPointsLeft > ProfsAssignable: ProfsPointsLeft = ProfsAssignable GemRB.SetVar ("ProfsPointsLeft", ProfsPointsLeft) # setup the +/- and info controls for i in range (ProfsNumButtons): if ProfsOffsetPress != -1: Button=ProfsWindow.GetControl(i+ProfsOffsetPress) Button.SetVarAssoc("Prof", i) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, ProfsJustPress) cid = i*2+ProfsOffsetButton1 if Profs2ndOffsetButton1 != -1 and i > 7: cid = (i-8)*2+Profs2ndOffsetButton1 Button=ProfsWindow.GetControl(cid) Button.SetVarAssoc("Prof", i) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, ProfsLeftPress) Button=ProfsWindow.GetControl(cid+1) Button.SetVarAssoc("Prof", i) Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, ProfsRightPress) if(ProfsScrollBar): # proficiencies scrollbar ProfsScrollBar.SetEvent(IE_GUI_SCROLLBAR_ON_CHANGE, ProfsScrollBarPress) ProfsScrollBar.SetDefaultScrollBar () ProfsScrollBar.SetVarAssoc ("ProfsTopIndex", ProfCount) ProfsRedraw (1) return
def OpenConfirmWindow(): global ConfirmWindow, NameField, SaveButton if ConfirmWindow != None: ConfirmWindow.Unload() ConfirmWindow = None GemRB.SetVar("FloatWindow", -1) return Pos = GemRB.GetVar("TopIndex") + GemRB.GetVar("SaveIdx") ConfirmWindow = GemRB.LoadWindow(1) GemRB.SetVar("FloatWindow", ConfirmWindow.ID) # Slot name if Pos < len(Games): Slotname = Games[Pos].GetName() save_strref = strs['overwrite'] else: Slotname = "" save_strref = strs['save'] NameField = ConfirmWindow.GetControl(ctrl_offset[7]) NameField.SetText(Slotname) NameField.SetEvent(IE_GUI_EDIT_ON_CHANGE, EditChange) #game hours (should be generated from game) if Pos < len(Games): if GameCheck.IsBG2(): Chapter = GemRB.GetGameVar("CHAPTER") & 0x7fffffff Slotname = GemRB.GetString( str_chapter[Chapter - 1]) + " " + Games[Pos].GetGameDate() else: Slotname = Games[Pos].GetGameDate() else: Slotname = "" Label = ConfirmWindow.GetControl(ctrl_offset[8]) Label.SetText(Slotname) # Areapreview if not GameCheck.IsIWD2(): Button = ConfirmWindow.GetControl(0) if Pos < len(Games): Button.SetSprite2D(Games[Pos].GetPreview()) else: Button.SetPicture("") # PC portraits for j in range(min(6, MAX_PARTY_SIZE)): Button = ConfirmWindow.GetControl(ctrl_offset[9] + j) if Pos < len(Games): Button.SetSprite2D(Games[Pos].GetPortrait(j)) else: Button.SetPicture("") # Save/Overwrite SaveButton = ConfirmWindow.GetControl(ctrl_offset[10]) SaveButton.SetText(save_strref) SaveButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, ConfirmedSaveGame) SaveButton.SetFlags(IE_GUI_BUTTON_DEFAULT, OP_OR) if Slotname == "": SaveButton.SetState(IE_GUI_BUTTON_DISABLED) # Cancel CancelButton = ConfirmWindow.GetControl(ctrl_offset[11]) CancelButton.SetText(strs['cancel']) CancelButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, AbortedSaveGame) CancelButton.SetFlags(IE_GUI_BUTTON_CANCEL, OP_OR) ConfirmWindow.SetVisible(WINDOW_VISIBLE) ConfirmWindow.ShowModal(MODAL_SHADOW_NONE) NameField.SetStatus( IE_GUI_CONTROL_FOCUSED) # ShowModal will happily reset this.. return