1# -*-python-*- 2# GemRB - Infinity Engine Emulator 3# Copyright (C) 2010 The GemRB Project 4# 5# This program is free software; you can redistribute it and/or 6# modify it under the terms of the GNU General Public License 7# as published by the Free Software Foundation; either version 2 8# of the License, or (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18# 19 20import GemRB 21import GameCheck 22import GUIClasses 23import GUICommon 24import GUIWORLD 25import InventoryCommon 26from ie_stats import * 27from GUIDefines import * 28 29def SetGameGUIHidden(hide): 30 op = OP_OR if hide else OP_NAND 31 GemRB.GameSetScreenFlags(GS_HIDEGUI, op) 32 33def IsGameGUIHidden(): 34 return GemRB.GetGUIFlags() & GS_HIDEGUI 35 36# for keymap.2da 37def ToggleGUIHidden(): 38 SetGameGUIHidden(not IsGameGUIHidden()) 39 40 41################################################################## 42# functions dealing with containers 43################################################################## 44 45HideOnClose = False 46ContainerWindow = None 47Container = None 48if GameCheck.IsIWD2(): 49 leftdiv = 5 50 ground_size = 10 51else: 52 leftdiv = 3 53 ground_size = 6 54 55if GameCheck.IsPST(): 56 import GUICommonWindows 57 58def UpdateContainerWindow (): 59 global Container 60 61 Window = ContainerWindow 62 63 pc = GemRB.GameGetFirstSelectedPC () 64 if GameCheck.IsPST(): 65 GUICommon.SetEncumbranceLabels (Window, 54, None, pc) 66 else: 67 GUICommon.SetEncumbranceLabels (Window, 0x10000045, 0x10000046, pc) 68 69 party_gold = GemRB.GameGetPartyGold () 70 Text = Window.GetControl (0x10000036) 71 Text.SetText (str (party_gold)) 72 73 Container = GemRB.GetContainer (0) #will use first selected pc anyway 74 LeftCount = Container['ItemCount'] 75 ScrollBar = Window.GetControl (52) 76 Count = max (0, (LeftCount - ground_size + leftdiv - 1) // leftdiv) 77 ScrollBar.SetVarAssoc ("LeftTopIndex", GemRB.GetVar ("LeftTopIndex"), 0, Count) 78 79 inventory_slots = GemRB.GetSlots (pc, 0x8000) 80 RightCount = len(inventory_slots) 81 ScrollBar = Window.GetControl (53) 82 Count = max (0, (RightCount - 4 + 1) // 2) 83 ScrollBar.SetVarAssoc ("RightTopIndex", GemRB.GetVar ("RightTopIndex"), 0, Count) 84 85 RedrawContainerWindow () 86 87def RedrawContainerWindow (): 88 Window = ContainerWindow 89 90 # scroll in multiples of the number of columns 91 LeftTopIndex = GemRB.GetVar ("LeftTopIndex") * leftdiv 92 RightTopIndex = GemRB.GetVar ("RightTopIndex") * 2 93 pc = GemRB.GameGetFirstSelectedPC () 94 inventory_slots = GemRB.GetSlots (pc, 0x8000) 95 RightCount = len(inventory_slots) 96 97 for i in range (ground_size): 98 #this is an autoselected container, but we could use PC too 99 Slot = GemRB.GetContainerItem (0, i+LeftTopIndex) 100 Button = Window.GetControl (i) 101 if Slot: 102 Button.SetVarAssoc ("LeftIndex", LeftTopIndex+i) 103 function = TakeItemContainer 104 else: 105 Button.SetVarAssoc ("LeftIndex", -1) 106 function = None 107 if GameCheck.IsPST(): 108 GUICommonWindows.SetItemButton (Window, Button, Slot, function, None) 109 else: 110 InventoryCommon.UpdateInventorySlot (pc, Button, Slot, "container") 111 112 for i in range (4): 113 if i+RightTopIndex < RightCount: 114 Slot = GemRB.GetSlotItem (pc, inventory_slots[i+RightTopIndex]) 115 else: 116 Slot = None 117 Button = Window.GetControl (i+10) 118 119 #pst had a redundant call here, reenable if it turns out it isn't redundant: 120 #GUICommonWindows.SetItemButton (Window, Button, Slot, None, None) 121 122 if Slot: 123 Button.SetVarAssoc ("RightIndex", RightTopIndex+i) 124 function = DropItemContainer 125 else: 126 Button.SetVarAssoc ("RightIndex", -1) 127 function = None 128 if GameCheck.IsPST(): 129 GUICommonWindows.SetItemButton (Window, Button, Slot, function, None) 130 else: 131 InventoryCommon.UpdateInventorySlot (pc, Button, Slot, "inventory") 132 133 # shade the inventory icon if it is full 134 Button = Window.GetControl (54) 135 if Button: 136 free_slots = GemRB.GetSlots (pc, 0x8000, -1) 137 if free_slots == (): 138 Button.SetState (IE_GUI_BUTTON_PRESSED) 139 else: 140 Button.SetState (IE_GUI_BUTTON_LOCKED) 141 142def OpenContainerWindow (): 143 global ContainerWindow, Container 144 145 if ContainerWindow: 146 return 147 148 global HideOnClose 149 HideOnClose = IsGameGUIHidden() 150 151 if HideOnClose: 152 SetGameGUIHidden(False) 153 # must use a timed event because SetGameGUIHidden(False) sets a flag to unhide the gui next frame 154 # AFIK not needed, commented out in case it turns out there are conditions we will need it 155 # GemRB.SetTimedEvent (lambda: GemRB.GetView ("MSGWIN").SetVisible(False), 1) 156 else: 157 GemRB.GetView ("MSGWIN").SetVisible (False) 158 ActWin = GemRB.GetView ("ACTWIN") 159 if ActWin: 160 ActWin.SetVisible (False) 161 162 ContainerWindow = Window = GemRB.LoadWindow (8, GUICommon.GetWindowPack(), WINDOW_BOTTOM|WINDOW_HCENTER) 163 # fix wrong height in the guiw10.chu and reposition 164 # that chu is also used as a base for some arbitrary resolutions 165 if GameCheck.IsBG2 () and GemRB.GetSystemVariable (SV_HEIGHT) >= 768: 166 Size = Window.GetSize () 167 Pos = Window.GetPos () 168 Window.SetSize (Size[0], 90) 169 Window.SetPos (Pos[0], GemRB.GetSystemVariable (SV_HEIGHT) - 90) 170 171 if not GameCheck.IsIWD2 () and not GameCheck.IsGemRBDemo () and not GameCheck.IsPST (): 172 # container window shouldnt be in front 173 GemRB.GetView("OPTWIN").Focus() 174 GemRB.GetView("PORTWIN").Focus() 175 176 Container = GemRB.GetContainer(0) 177 178 # Gears (time) when options pane is down 179 if GameCheck.IsBG2(): 180 Button = Window.GetControl (62) 181 if Button: # the demo lacks this button 182 Label = Button.CreateLabel (0x10000047, "NORMAL", "", IE_FONT_SINGLE_LINE) 183 184 Label.SetAnimation ("CPEN") 185 Button.SetAnimation ("CGEAR") 186 Button.SetBAM ("CDIAL", 0, 0) 187 Button.SetState (IE_GUI_BUTTON_ENABLED) 188 Button.SetFlags (IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_ANIMATED|IE_GUI_BUTTON_NORMAL, OP_SET) 189 Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUICommon.GearsClicked) 190 GUICommon.SetGamedaysAndHourToken() 191 Button.SetTooltip(16041) 192 193 # 0-5 - Ground Item 194 for i in range (ground_size): 195 Button = Window.GetControl (i) 196 Button.SetVarAssoc ("LeftIndex", i) 197 Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, TakeItemContainer) 198 if GameCheck.IsPST(): 199 Button.SetFont ("NUMBER") 200 Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT | IE_GUI_BUTTON_ALIGN_BOTTOM, OP_OR) 201 202 # 10-13 - Personal Item 203 for i in range (4): 204 Button = Window.GetControl (i+10) 205 Button.SetVarAssoc ("RightIndex", i) 206 Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, DropItemContainer) 207 if GameCheck.IsPST(): 208 Button.SetFont ("NUMBER") 209 Button.SetFlags (IE_GUI_BUTTON_ALIGN_RIGHT | IE_GUI_BUTTON_ALIGN_BOTTOM, OP_OR) 210 211 # left scrollbar (container) 212 ScrollBar = Window.GetControl (52) 213 ScrollBar.SetVisible(True) # unhide because in PST it is linked to a TextArea 214 ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, RedrawContainerWindow) 215 216 # right scrollbar (inventory) 217 ScrollBar = Window.GetControl (53) 218 ScrollBar.SetVisible(True) # unhide because in PST it is linked to a TextArea 219 ScrollBar.SetEvent (IE_GUI_SCROLLBAR_ON_CHANGE, RedrawContainerWindow) 220 221 # encumbrance and inventory icon 222 # iwd has a handy button 223 Button = Window.GetControl (54) 224 if Button: 225 if GameCheck.IsPST(): 226 Button.SetFont ("NUMBER") 227 Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET) 228 Button.CreateLabel (0x10000045, "NUMBER", "", IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_TOP|IE_FONT_SINGLE_LINE) 229 Button.CreateLabel (0x10000046, "NUMBER", "", IE_FONT_ALIGN_RIGHT|IE_FONT_ALIGN_BOTTOM|IE_FONT_SINGLE_LINE) 230 else: 231 Window.CreateLabel (0x10000045, 323, 14, 60, 15, "NUMBER", "0:", IE_FONT_ALIGN_LEFT|IE_FONT_ALIGN_TOP|IE_FONT_SINGLE_LINE) 232 Window.CreateLabel (0x10000046, 323, 20, 80, 15, "NUMBER", "0:", IE_FONT_ALIGN_RIGHT|IE_FONT_ALIGN_TOP|IE_FONT_SINGLE_LINE) 233 234 # container icon 235 Button = Window.GetControl (50) 236 if GameCheck.IsPST(): 237 Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET) 238 Button.SetState (IE_GUI_BUTTON_LOCKED) 239 240 if not GameCheck.IsPST(): 241 Table = GemRB.LoadTable ("containr") 242 row = Container['Type'] 243 tmp = Table.GetValue (row, 0) 244 if tmp!='*': 245 GemRB.PlaySound (tmp) 246 tmp = Table.GetValue (row, 1) 247 if tmp!='*': 248 Button.SetSprites (tmp, 0, 0, 0, 0, 0 ) 249 250 # Done 251 Button = Window.GetControl (51) 252 if GameCheck.IsPST(): 253 Button.SetText (1403) 254 else: 255 Button.SetText ("") 256 257 Button.MakeEscape() 258 Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, LeaveContainer) 259 260 GemRB.SetVar ("LeftTopIndex", 0) 261 GemRB.SetVar ("RightTopIndex", 0) 262 UpdateContainerWindow () 263 264def CloseContainerWindow (): 265 global ContainerWindow 266 267 if not ContainerWindow: 268 return 269 270 ContainerWindow.Close () 271 ContainerWindow = None 272 GemRB.GetView ("MSGWIN").SetVisible (True) 273 if GemRB.GetView ("ACTWIN"): 274 GemRB.GetView ("ACTWIN").SetVisible (True) 275 SetGameGUIHidden(HideOnClose) 276 277 Table = GemRB.LoadTable ("containr") 278 row = Container['Type'] 279 tmp = Table.GetValue (row, 2) 280 #play closing sound if applicable 281 if tmp!='*': 282 GemRB.PlaySound (tmp) 283 284#doing this way it will inform the core system too, which in turn will call 285#CloseContainerWindow () 286def LeaveContainer (): 287 GemRB.LeaveContainer() 288 289def DropItemContainer (): 290 RightIndex = GemRB.GetVar ("RightIndex") 291 if RightIndex < 0: 292 return 293 294 #we need to get the right slot number 295 pc = GemRB.GameGetFirstSelectedPC () 296 inventory_slots = GemRB.GetSlots (pc, 0x8000) 297 if RightIndex >= len(inventory_slots): 298 return 299 300 GemRB.ChangeContainerItem (0, inventory_slots[RightIndex], 0) 301 UpdateContainerWindow () 302 303def TakeItemContainer (): 304 LeftIndex = GemRB.GetVar ("LeftIndex") 305 if LeftIndex < 0: 306 return 307 308 if LeftIndex >= Container['ItemCount']: 309 return 310 311 GemRB.ChangeContainerItem (0, LeftIndex, 1) 312 UpdateContainerWindow () 313