1# GemRB - Infinity Engine Emulator 2# Copyright (C) 2003 The GemRB Project 3# 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. 8# 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. 13# 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. 17# 18# 19# Some small attempt to re-use code in character generation. 20# Attempting to emulate lynx's loop method from BG2 GUI 21 22# Should be called CharGenCommon for continuity but I started 23# this with something else in mind and then changed it 24# - Fyorl 25 26# CharOverview.py (GUICG) 27 28import GemRB 29from GUIDefines import * 30from ie_stats import * 31 32CharGenWindow = 0 33TextAreaControl = 0 34PortraitButton = 0 35StepButtons = {} 36PersistButtons = {} 37Steps = ['Gender', 'Race', 'Class', 'Alignment', 'Abilities', 'Enemy', 'Appearance', 'Name'] 38GlobalStep = 0 39 40### Utility functions 41def AddText(strref, newlines=0): 42 TextAreaControl.Append (strref) 43 TextAreaControl.Append ("\n" * newlines) 44### End utility functions 45 46def PositionCharGenWin(window, offset = 0): 47 global CharGenWindow 48 49 CGFrame = CharGenWindow.GetFrame() 50 WFrame = window.GetFrame() 51 window.SetPos(CGFrame['x'] + CGFrame['w'] - WFrame['w'] - 18, 52 offset + CGFrame['y'] + (CGFrame['h'] - WFrame['h'] - 24)) 53 54def UpdateOverview(CurrentStep): 55 global CharGenWindow, TextAreaControl, PortraitButton 56 global StepButtons, Steps, PersistButtons, GlobalStep 57 58 GlobalStep = CurrentStep 59 60 CharGenWindow = GemRB.LoadWindow(0, "GUICG") 61 CharGenWindow.SetFlags (IE_GUI_VIEW_IGNORE_EVENTS, OP_OR) 62 63 PortraitButton = CharGenWindow.GetControl(12) 64 PortraitButton.SetFlags(IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET) 65 66 # Handle portrait 67 PortraitName = GemRB.GetToken('LargePortrait') 68 if PortraitName != '' and CurrentStep > 1: 69 PortraitButton.SetPicture(PortraitName, 'NOPORTLG') 70 71 # Handle step buttons 72 TextLookup = [11956, 11957, 11959, 11958, 11960, 11983, 11961, 11963] 73 for i, Step in enumerate(Steps): 74 StepButtons[Step] = CharGenWindow.GetControl(i) 75 StepButtons[Step].SetText(TextLookup[i]) 76 State = IE_GUI_BUTTON_DISABLED 77 if CurrentStep - 1 == i: 78 State = IE_GUI_BUTTON_ENABLED 79 StepButtons[Step].MakeDefault() 80 StepButtons[Step].SetEvent(IE_GUI_BUTTON_ON_PRESS, NextPress) 81 StepButtons[Step].SetState(State) 82 83 # Handle (not so) persistent buttons 84 # This array handles all the default values for the buttons 85 # Exceptions are handled within the loop 86 ControlLookup = { 87 'Bio': [16, 18003, 0, None], 88 'Import': [13, 13955, 0, None], 89 'Back': [11, 15416, 1, BackPress], 90 'Next': [8, 28210, 0, None], 91 'Start': [15, 36788, 1, StartOver] 92 } 93 States = [IE_GUI_BUTTON_DISABLED, IE_GUI_BUTTON_ENABLED] 94 for Key in ControlLookup: 95 PersistButtons[Key] = CharGenWindow.GetControl(ControlLookup[Key][0]) 96 Text = ControlLookup[Key][1] 97 State = States[ControlLookup[Key][2]] 98 Event = ControlLookup[Key][3] 99 100 if Key == 'Bio' and CurrentStep == 9: 101 State = States[1] 102 import CharGen9 103 Event = CharGen9.BioPress 104 105 if Key == 'Import' and CurrentStep == 1: 106 State = States[1] 107 Event = ImportPress 108 109 if Key == 'Back': 110 if CurrentStep == 1: 111 State = States[0] 112 Event = None 113 else: 114 PersistButtons[Key].MakeEscape() 115 116 if Key == 'Next' and CurrentStep == 9: 117 State = 1 118 Event = NextPress 119 PersistButtons[Key].MakeDefault() 120 121 if Key == 'Start' and CurrentStep == 1: 122 Text = 13727 123 Event = CancelPress 124 PersistButtons[Key].MakeEscape() 125 126 PersistButtons[Key].SetText(Text) 127 PersistButtons[Key].SetState(State) 128 129 if Event: 130 PersistButtons[Key].SetEvent(IE_GUI_BUTTON_ON_PRESS, Event) 131 132 # Handle character overview information 133 TextAreaControl = CharGenWindow.GetControl(9) 134 Tables = [] 135 for tbl in ['races', 'classes', 'aligns', 'ability', 'skillsta', 'skills', 'featreq', 'feats']: 136 Tables.append(GemRB.LoadTable(tbl)) 137 138 if GemRB.GetVar('Gender') > 0: 139 name = GemRB.GetToken('CHARNAME') 140 if not name: 141 TextAreaControl.SetText(12135) 142 else: 143 TextAreaControl.SetText(1047) 144 AddText(': ' + GemRB.GetToken('CHARNAME'), 1) 145 AddText(12135) 146 AddText(': ') 147 strref = 1049 + GemRB.GetVar('Gender') 148 AddText(strref, 1) 149 150 if GemRB.GetVar('Race') > 0: 151 AddText(1048) 152 AddText(': ') 153 AddText(Tables[0].GetValue(Tables[0].FindValue(3, GemRB.GetVar('Race')), 2), 1) 154 155 if GemRB.GetVar('Class') > 0: 156 AddText(11959) 157 AddText(': ') 158 AddText(Tables[1].GetValue(GemRB.GetVar('Class') - 1, 0), 1) 159 160 if GemRB.GetVar('Alignment') > 0: 161 AddText(11958) 162 AddText(': ') 163 AddText(Tables[2].GetValue(GemRB.GetVar('Alignment') - 1, 0), 1) 164 165 if GemRB.GetVar('Ability 0') > 0: 166 AddText('\n[color=FFFF00]' + GemRB.GetString(17088) + '[/color]', 1) 167 for i in range(0, 6): 168 strref = Tables[3].GetValue(i, 2) 169 AddText(strref) 170 abl = GemRB.GetVar('Ability ' + str(i)) 171 AddText(': %d (%+d)' % (abl, abl / 2 - 5), 1) 172 173 if CurrentStep > 6: 174 AddText('\n[color=FFFF00]' + GemRB.GetString(11983) + '[/color]', 1) 175 176 ClassColumn = Tables[1].GetValue(GemRB.GetVar('Class') - 1, 3, GTV_INT) # Finds base class row id 177 if ClassColumn < 1: ClassColumn = GemRB.GetVar('Class') - 1 # If 0 then already a base class so need actual row 178 else: ClassColumn -= 1 # 'CLASS' column in classes.2da is out by 1 for some reason 179 ClassColumn += 4 # There are 4 columns before the classes in skills.2da 180 # At the moment only cleric kits get skill bonuses but their column names in skills.2da don't match up 181 # to their kit names. All classes aren't covered in skills.2da either which is why I have to resort 182 # to calculating the base class. This isn't ideal. Recommend a new 2DA be created with *all* classes 183 # as rows and skills as columns. Something like SKILCLAS.2DA 184 185 ### Cleric kit hack: 186 if GemRB.GetVar('Class') in range(27, 36): 187 ClassColumn = GemRB.GetVar('Class') - 12 188 189 RaceName = Tables[0].GetRowName(Tables[0].FindValue(3, GemRB.GetVar('Race'))) 190 SkillColumn = Tables[0].GetValue(RaceName, 'SKILL_COLUMN', GTV_INT) + 1 191 Lookup = {'STR': 0, 'DEX': 1, 'CON': 2, 'INT': 3, 'WIS': 4, 'CHR': 5} # Probably a better way to do this 192 for i in range(Tables[4].GetRowCount()): 193 SkillName = Tables[5].GetRowName(i) 194 Abl = Tables[4].GetValue(i, 1, GTV_STR) 195 Ranks = GemRB.GetVar('Skill ' + str(i)) 196 value = Ranks 197 value += (GemRB.GetVar('Ability ' + str(Lookup[Abl])) / 2 - 5) 198 value += Tables[5].GetValue(i, SkillColumn, GTV_INT) 199 value += Tables[5].GetValue(i, ClassColumn, GTV_INT) 200 201 untrained = Tables[5].GetValue(i, 3, GTV_INT) 202 if not untrained and Ranks < 1: 203 value = 0 204 205 if value: 206 strref = Tables[5].GetValue(i, 1) 207 AddText(strref) 208 strn = ': ' + str(value) 209 if value != Ranks: strn += ' (' + str(Ranks) + ')' 210 AddText(strn, 1) 211 212 AddText('\n[color=FFFF00]' + GemRB.GetString(36310) + '[/color]', 1) 213 214 for i in range(Tables[6].GetRowCount()): 215 value = GemRB.GetVar('Feat ' + str(i)) 216 if value: 217 strref = Tables[7].GetValue(i, 1) 218 AddText(strref) 219 multiple = Tables[6].GetValue(i, 0) 220 if multiple != 0: 221 AddText(': ' + str(value)) 222 AddText('\n') 223 224 AddText('\n') 225 import CommonTables 226 import Spellbook 227 MyChar = GemRB.GetVar ("Slot") 228 BookTypes = { IE_IWD2_SPELL_BARD:39341, IE_IWD2_SPELL_CLERIC:11028, \ 229 IE_IWD2_SPELL_DRUID:39342, IE_IWD2_SPELL_PALADIN:39343, IE_IWD2_SPELL_RANGER:39344, \ 230 IE_IWD2_SPELL_SORCERER:39345, IE_IWD2_SPELL_WIZARD:11027, IE_IWD2_SPELL_DOMAIN:0 } 231 for bt in BookTypes: 232 KnownSpells = Spellbook.GetKnownSpells(MyChar, bt) 233 if len(KnownSpells): 234 BTName = BookTypes[bt] 235 # individual domains, luckily in kit order 236 if BTName == 0: 237 KitIndex = GemRB.GetVar ("Class") - 1 238 KitIndex -= CommonTables.Classes.FindValue ("CLASS", GemRB.GetVar ("BaseClass")) 239 BTName = 39346 + KitIndex 240 AddText ('\n[color=FFFF00]') 241 AddText (BTName) 242 AddText ('[/color]\n') 243 for ks in KnownSpells: 244 AddText (GemRB.GetString(ks['SpellName'])+"\n") 245 246 # And we're done, w00t! 247 CharGenWindow.Focus() 248 return 249 250def NextPress(): 251 if len(Steps) > GlobalStep - 1: 252 GemRB.SetNextScript(Steps[GlobalStep - 1]) 253 else: #start the game 254 import CharGen9 255 CharGen9.NextPress() 256 return 257 258def CancelPress(): 259 #destroy the half generated character 260 slot = GemRB.GetVar("Slot") 261 GemRB.CreatePlayer("", slot|0x8000) 262 if CharGenWindow: 263 CharGenWindow.Unload() 264 GemRB.SetNextScript('SPPartyFormation') 265 return 266 267def StartOver(): 268 StartOverWindow = GemRB.LoadWindow(53) 269 270 def RestartGen(): 271 StartOverWindow.Close() 272 CharGenWindow.Close() 273 GemRB.SetNextScript('CharGen') 274 return 275 276 YesButton = StartOverWindow.GetControl(0) 277 YesButton.SetText(13912) 278 YesButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, RestartGen) 279 280 NoButton = StartOverWindow.GetControl(1) 281 NoButton.SetText(13913) 282 NoButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, lambda: StartOverWindow.Close()) 283 284 TextAreaControl = StartOverWindow.GetControl(2) 285 TextAreaControl.SetText(40275) 286 return 287 288def ImportPress(): 289 GemRB.SetToken('NextScript', 'CharGen') 290 GemRB.SetNextScript('ImportFile') 291 return 292 293def BackPress(): 294 # Need to clear relevant variables 295 if GlobalStep == 2: GemRB.SetVar('Gender', 0) 296 elif GlobalStep == 3: GemRB.SetVar('Race', 0) 297 elif GlobalStep == 4: GemRB.SetVar('Class', 0) 298 elif GlobalStep == 5: GemRB.SetVar('Alignment', 0) 299 elif GlobalStep == 6: 300 for i in range(0, 7): 301 GemRB.SetVar('Ability ' + str(i), 0) 302 303 elif GlobalStep == 9: GemRB.SetToken('CHARNAME', '') 304 305 ScrName = 'CharGen' + str(GlobalStep - 1) 306 if GlobalStep == 2: ScrName = 'CharGen' 307 GemRB.SetNextScript(ScrName) 308 return 309