1# -*-python-*- 2# GemRB - Infinity Engine Emulator 3# Copyright (C) 2003-2004 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 21from GUIDefines import * 22from ie_stats import * 23from ie_restype import RES_2DA 24from ie_slots import * 25import GameCheck 26import GUICommon 27import Spellbook 28import CommonTables 29import LUSpellSelection 30import LUProfsSelection 31import LUSkillsSelection 32 33####################### 34pc = 0 35OldClassName = 0 36OldKitName = 0 37ClassName = 0 38NewMageSpells = 0 39NewPriestMask = 0 40NewClassId = 0 41DualClassTable = 0 42####################### 43DCMainWindow = 0 44DCMainClassButton = 0 45DCMainSkillsButton = 0 46DCMainDoneButton = 0 47DCMainStep = 0 48####################### 49DCClassWindow = 0 50DCClassDoneButton = 0 51DCClass = 0 52DCClasses = [] 53####################### 54DCProfsWindow = 0 55DCProfsDoneButton = 0 56####################### 57DCSkillsWindow = 0 58DCSkillsDoneButton = 0 59####################### 60 61def DualClassWindow (): 62 """Opens the dual class selection window.""" 63 64 global pc, OldClassName, NewMageSpells, NewPriestMask, NewClassId, OldKitName, DualClassTable 65 global DCMainWindow, DCMainClassButton, DCMainDoneButton, DCMainSkillsButton, DCMainStep 66 67 # get our basic globals 68 pc = GemRB.GameGetSelectedPCSingle () 69 DCMainStep = 1 70 71 # make sure to nullify old values 72 NewPriestMask = 0 73 NewMageSpells = 0 74 NewClassId = 0 75 76 # set up our main window 77 DCMainWindow = GemRB.LoadWindow (5) 78 79 # done button (off) 80 DCMainDoneButton = DCMainWindow.GetControl (2) 81 DCMainDoneButton.SetText (11973) 82 DCMainDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DCMainDonePress) 83 DCMainDoneButton.SetState (IE_GUI_BUTTON_DISABLED) 84 85 # cancel button (on) 86 DCMainCancelButton = DCMainWindow.GetControl (1) 87 DCMainCancelButton.SetText (13727) 88 DCMainCancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DCMainCancelPress) 89 DCMainCancelButton.SetState (IE_GUI_BUTTON_ENABLED) 90 DCMainCancelButton.MakeEscape () 91 92 # class button (on) 93 DCMainClassButton = DCMainWindow.GetControl (3) 94 DCMainClassButton.SetText (11959) 95 DCMainClassButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DCMainClassPress) 96 DCMainClassButton.SetState (IE_GUI_BUTTON_ENABLED) 97 DCMainClassButton.MakeDefault() 98 99 # skills button (off) 100 DCMainSkillsButton = DCMainWindow.GetControl (4) 101 DCMainSkillsButton.SetText (17372) 102 DCMainSkillsButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DCMainSkillsPress) 103 DCMainSkillsButton.SetState (IE_GUI_BUTTON_DISABLED) 104 105 # back button (on) 106 DCMainBackButton = DCMainWindow.GetControl (5) 107 if GameCheck.IsBG2(): 108 DCMainBackButton.SetText (15416) 109 DCMainBackButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DCMainBackPress) 110 DCMainBackButton.SetState (IE_GUI_BUTTON_ENABLED) 111 112 # picture of character 113 DCMainPictureButton = DCMainWindow.GetControl (6) 114 DCMainPictureButton.SetState (IE_GUI_BUTTON_LOCKED) 115 DCMainPictureButton.SetFlags (IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PICTURE, OP_SET) 116 DCMainPictureButton.SetPicture (GemRB.GetPlayerPortrait (pc, 0)["Sprite"], "NOPORTMD") 117 118 # text area warning 119 DCTextArea = DCMainWindow.GetControl (7) 120 DCTextArea.SetText (10811) 121 122 # character name 123 DCLabel = DCMainWindow.GetControl (0x10000008) 124 DCLabel.SetText (GemRB.GetPlayerName (pc, 0)) 125 126 # class name 127 Kit = GUICommon.GetKitIndex (pc) 128 OldClassName = GUICommon.GetClassRowName (pc) 129 if Kit: 130 OldKitName = CommonTables.KitList.GetValue (Kit, 0, GTV_STR) 131 else: 132 OldKitName = OldClassName 133 DCLabel = DCMainWindow.GetControl (0x10000009) 134 DCLabel.SetText (GUICommon.GetActorClassTitle (pc)) 135 136 # get the names of the classes we can dual to 137 DualClassTable = GemRB.LoadTable ("dualclas") 138 for i in range (DualClassTable.GetColumnCount ()): 139 DCClasses.append (DualClassTable.GetColumnName (i)) 140 141 # show our window 142 DCMainWindow.ShowModal (MODAL_SHADOW_GRAY) 143 return 144 145def DumpUnusableItems (pc): 146 """Dumps everything in the inventory that is now unusable.""" 147 148 SlotTypes = [ SLOT_ARMOUR, SLOT_SHIELD, SLOT_HELM, SLOT_RING, SLOT_CLOAK, SLOT_BOOT, SLOT_AMULET, SLOT_GLOVE, SLOT_BELT, SLOT_ITEM, SLOT_WEAPON, SLOT_QUIVER ] 149 for stype in SlotTypes: 150 Slots = GemRB.GetSlots (pc, stype) 151 if not len(Slots): 152 # nothing there 153 continue 154 155 for slot in Slots: 156 SlotType = GemRB.GetSlotType (slot, pc) 157 CREItem = GemRB.GetSlotItem (pc, slot) 158 159 if not GemRB.CanUseItemType (SlotType["Type"], CREItem["ItemResRef"], pc): 160 # move it to a free inventory slot by mimicking dragging 161 Item = GemRB.GetItem (CREItem["ItemResRef"]) 162 GemRB.DragItem (pc, slot, Item["ItemIcon"]) 163 if not GemRB.DropDraggedItem (pc, -3): # ASI_FAILED 164 # inventory was probably too full, drop to ground 165 GemRB.DropDraggedItem (pc, -2) 166 167def DCMainDonePress (): 168 """Saves our dualclass changes and closes the window. 169 170 This de-activates our old class and readjusts the basic actor stats, such as 171 THAC0, spell casting, proficiencies, and so forth, to the new class.""" 172 import GUIREC 173 global ClassName 174 175 # save our proficiencies 176 LUProfsSelection.ProfsSave (pc, LUProfsSelection.LUPROFS_TYPE_DUALCLASS) 177 178 # remove old class abilities 179 KitIndex = GUICommon.GetKitIndex (pc) 180 if KitIndex: 181 ABTable = CommonTables.KitList.GetValue (str(KitIndex), "ABILITIES") 182 else: 183 ABTable = CommonTables.ClassSkills.GetValue (OldClassName, "ABILITIES") 184 if ABTable != "*" and GemRB.HasResource (ABTable, RES_2DA, 1): 185 GUICommon.RemoveClassAbilities (pc, ABTable, GemRB.GetPlayerStat (pc, IE_LEVEL)) 186 187 # remove old class casting 188 if not NewMageSpells: 189 for i in range (9): 190 GemRB.SetMemorizableSpellsCount (pc, 0, IE_SPELL_TYPE_WIZARD, i) 191 Spellbook.RemoveKnownSpells (pc, IE_SPELL_TYPE_PRIEST, 1,7, 1) 192 193 # apply our class abilities 194 ABTable = CommonTables.ClassSkills.GetValue (ClassName, "ABILITIES") 195 if ABTable != "*" and GemRB.HasResource (ABTable, RES_2DA, 1): 196 GUICommon.AddClassAbilities (pc, ABTable) 197 198 # learn our new priest spells 199 if NewPriestMask: 200 Spellbook.LearnPriestSpells (pc, 1, NewPriestMask) 201 GemRB.SetMemorizableSpellsCount (pc, 1, IE_SPELL_TYPE_PRIEST, 0) 202 203 # save our thief skills if we have them 204 LUSkillsSelection.SkillsSave (pc) 205 206 # NOTE: the ordering here is very deliberate, don't touch! 207 # for the dc detection code to work in core, some level and mc bits info has to be there 208 # 3 PCF functions (class, kit, level) all need more info 209 # testcase: dualclassing and checking how the actionbar evolves 210 211 # mark the actor as dualclassed 212 OldMCFlags = GemRB.GetPlayerStat (pc, IE_MC_FLAGS, 1) 213 NewMCBit = CommonTables.Classes.GetValue (OldClassName, "MC_WAS_ID", GTV_INT) 214 GemRB.SetPlayerStat (pc, IE_MC_FLAGS, OldMCFlags|NewMCBit) 215 216 # calculate new dc/mc class combo 217 OldClassId = GemRB.GetPlayerStat (pc, IE_CLASS) 218 MultClassId = (1 << (NewClassId-1)) | (1 << (OldClassId-1)) 219 MultClassId = CommonTables.Classes.FindValue ("MULTI", MultClassId) 220 MultClassId = CommonTables.Classes.GetRowName (MultClassId) 221 MultClassId = CommonTables.Classes.GetValue (MultClassId, "ID") 222 223 # fake update our levels (no PCF), so the PCF can be ran later on correct values 224 # core only looks at the level difference when determining dc class order 225 DSOverride = { "old": OldClassId, "new": NewClassId, "mc": MultClassId } 226 Level1 = GemRB.GetPlayerStat (pc, IE_LEVEL) 227 if GUICommon.IsDualSwap (pc, DSOverride): 228 GemRB.SetPlayerStat (pc, IE_LEVEL2, 0, 0) 229 else: 230 GemRB.SetPlayerStat (pc, IE_LEVEL2, Level1 - 1, 0) 231 GemRB.SetPlayerStat (pc, IE_LEVEL, 0, 0) 232 233 # finally set the new class 234 GemRB.SetPlayerStat (pc, IE_CLASS, MultClassId) 235 236 # update our levels and xp 237 if GUICommon.IsDualSwap (pc, DSOverride): 238 GemRB.SetPlayerStat (pc, IE_LEVEL2, 1) 239 else: 240 GemRB.SetPlayerStat (pc, IE_LEVEL2, Level1, 0) 241 GemRB.SetPlayerStat (pc, IE_LEVEL, 1) 242 GemRB.SetPlayerStat (pc, IE_XP, 0) 243 244 # END of order matters NOTE 245 246 # new thac0 247 ThacoTable = GemRB.LoadTable ("THAC0") 248 GemRB.SetPlayerStat (pc, IE_TOHIT, ThacoTable.GetValue (NewClassId-1, 0, GTV_INT)) 249 250 # new saves 251 SavesTable = CommonTables.Classes.GetValue (ClassName, "SAVE", GTV_STR) 252 SavesTable = GemRB.LoadTable (SavesTable) 253 for i in range (5): 254 GemRB.SetPlayerStat (pc, IE_SAVEVSDEATH+i, SavesTable.GetValue (i, 0)) 255 256 # dump any equipped items that are now unusable 257 DumpUnusableItems (pc) 258 259 # close our window 260 if DCMainWindow: 261 DCMainWindow.Unload () 262 return 263 264def DCMainCancelPress (): 265 """Revert all changes and close the dual class window.""" 266 267 # simulate pressing the back button until we get back to DCMainStep = 1 268 # to unset all things from the new class 269 while DCMainStep > 1: 270 DCMainBackPress () 271 272 # close our window 273 if DCMainWindow: 274 DCMainWindow.Unload () 275 276 return 277 278def DCMainBackPress (): 279 """Reverts all current changes and reverts back to the previous step.""" 280 global DCMainStep, DCClass, NewMageSpells 281 global NewPriestMask 282 283 if DCMainStep == 2: # class selected, wait to choose skills 284 # disable the skills button and re-enable the class button 285 # the class will be reset when the class button is clicked 286 DCMainSkillsButton.SetState (IE_GUI_BUTTON_DISABLED) 287 DCMainClassButton.SetState (IE_GUI_BUTTON_ENABLED) 288 289 # back a step 290 DCMainStep = 1 291 elif DCMainStep == 3: # skills selected 292 # re-enable our skills button 293 DCMainSkillsButton.SetState (IE_GUI_BUTTON_ENABLED) 294 295 # un-learn our spells and skills 296 if NewMageSpells: 297 Spellbook.RemoveKnownSpells (pc, IE_SPELL_TYPE_WIZARD, 1,1, 1) 298 299 LUSkillsSelection.SkillsNullify () 300 NewPriestMask = 0 301 NewMageSpells = 0 302 303 # go back a step 304 DCMainStep = 2 305 return 306 307def DCMainClassPress (): 308 """Opens the class selection window.""" 309 310 global DCClassWindow, DCClassDoneButton, DCClass 311 312 # we default the class back down to -1 313 DCClass = -1 314 GemRB.SetVar ("DCClass", DCClass) 315 316 # open the window 317 DCClassWindow = GemRB.LoadWindow (6) 318 319 # string refs for the given classes 320 DCClassStrings = [] 321 for classname in DCClasses: 322 DCClassStrings.append(CommonTables.Classes.GetValue (classname, "NAME_REF", GTV_INT)) 323 324 # setup the class buttons 325 for i in range (6): 326 # get the button and associate it with the correct var 327 DCClassButton = DCClassWindow.GetControl (i+1) 328 DCClassButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DCClassSelect) 329 DCClassButton.SetVarAssoc ("DCClass", i) 330 DCClassButton.SetText (DCClassStrings[i]) 331 332 # enable only if we can dual into the given class 333 if CanDualInto (i): 334 DCClassButton.SetState (IE_GUI_BUTTON_ENABLED) 335 else: 336 DCClassButton.SetState (IE_GUI_BUTTON_DISABLED) 337 338 # done button (off) 339 DCClassDoneButton = DCClassWindow.GetControl (8) 340 DCClassDoneButton.SetText (11973) 341 DCClassDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DCClassDonePress) 342 DCClassDoneButton.SetState (IE_GUI_BUTTON_DISABLED) 343 DCClassDoneButton.MakeDefault() 344 345 # back button (on) 346 DCClassBackButton = DCClassWindow.GetControl (7) 347 DCClassBackButton.SetText (15416) 348 DCClassBackButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DCClassBackPress) 349 DCClassBackButton.SetState (IE_GUI_BUTTON_ENABLED) 350 DCClassBackButton.MakeEscape () 351 352 # setup the text area with default text 353 DCClassTextArea = DCClassWindow.GetControl (9) 354 DCClassTextArea.SetText (10949) 355 356 # show the window 357 DCClassWindow.ShowModal (MODAL_SHADOW_GRAY) 358 359 return 360 361def DCClassSelect (): 362 """Updates the current class based on the button pressed.""" 363 364 global DCClass 365 366 # un-select the old button and save and select the new one 367 if DCClass >= 0: 368 DCClassButton = DCClassWindow.GetControl (DCClass+1) 369 DCClassButton.SetState (IE_GUI_BUTTON_ENABLED) 370 371 # if we clicked the same class twice, turn the done button off (toggled) 372 if DCClass == GemRB.GetVar ("DCClass"): 373 DCClassDoneButton.SetState (IE_GUI_BUTTON_DISABLED) 374 DCClass = -1 375 376 # don't need to worry about setting a new text area, as it would be the same 377 return 378 379 # save the new class, select it's button, and enable the done button 380 DCClass = GemRB.GetVar ("DCClass") 381 DCClassButton = DCClassWindow.GetControl (DCClass+1) 382 DCClassButton.SetState (IE_GUI_BUTTON_SELECTED) 383 DCClassDoneButton.SetState (IE_GUI_BUTTON_ENABLED) 384 385 # all the possible strrefs for the different classes 386 DCClassStrings = [] 387 for classname in DCClasses: 388 DCClassStrings.append (CommonTables.Classes.GetValue (classname, "DESC_REF", GTV_INT)) 389 390 # update the text are with the new string 391 DCClassTextArea = DCClassWindow.GetControl (9) 392 DCClassTextArea.SetText (DCClassStrings [DCClass]) 393 394 return 395 396def DCClassDonePress (): 397 """Stores the selected class and moves to the next step.""" 398 399 global DCMainStep, ClassName, NewClassId 400 401 # unload our class selection window 402 if DCClassWindow: 403 DCClassWindow.Unload () 404 DCMainWindow.ShowModal (MODAL_SHADOW_GRAY) 405 406 # enable the skills button and disable the class selection button 407 DCMainClassButton.SetState (IE_GUI_BUTTON_DISABLED) 408 DCMainSkillsButton.SetState (IE_GUI_BUTTON_ENABLED) 409 410 # save the class 411 ClassName = DCClasses[DCClass] 412 NewClassId = CommonTables.Classes.GetValue (ClassName, "ID", GTV_INT) 413 414 # set our step to 2 so that the back button knows where we are 415 DCMainStep = 2 416 417 return 418 419def CanDualInto (index): 420 """Determines if a given class can be dualed into. 421 422 Index defines the position within the DCClasses list.""" 423 424 # make sure index isn't out of range 425 if index < 0 or index >= len (DCClasses): 426 return 0 427 428 # return 0 if we can't dual into the class 429 if not DualClassTable.GetValue (OldKitName, DCClasses[index], GTV_INT): 430 return 0 431 432 # make sure we aren't restricted by alignment 433 AlignmentTable = GemRB.LoadTable ("alignmnt") 434 Alignment = GemRB.GetPlayerStat (pc, IE_ALIGNMENT) # our alignment 435 Alignment = CommonTables.Aligns.FindValue (3, Alignment) 436 Alignment = CommonTables.Aligns.GetValue (Alignment, 4) # convert the alignment 437 if not AlignmentTable.GetValue (DCClasses[index], Alignment, GTV_INT): # check it 438 return 0 439 440 # make sure we have the minimum stats required for the next class 441 StatTable = GemRB.LoadTable ("abdcdsrq") 442 ClassStatIndex = StatTable.GetRowIndex (DCClasses[index]) 443 for stat in range (6): # loop through each stat 444 minimum = StatTable.GetValue (ClassStatIndex, stat) 445 name = StatTable.GetColumnName (stat) 446 if GemRB.GetPlayerStat (pc, GUICommon.SafeStatEval ("IE_" + name[4:])) < minimum: 447 return 0 448 449 # if we made it here, we can dual to the class 450 return 1 451 452def DCClassBackPress (): 453 """Unloads the class selection window without making any changes.""" 454 # close the class window 455 if DCClassWindow: 456 DCClassWindow.Unload () 457 DCMainWindow.ShowModal (MODAL_SHADOW_GRAY) 458 return 459 460def DCMainSkillsPress (): 461 """Opens the proficiency selection window. 462 463 Then follows the skills proficiency and spells windows, if required.""" 464 465 global DCSkillsWindow, DCMainStep, DCHasProfs 466 467 # we're onto the next step 468 DCMainSkillsButton.SetState (IE_GUI_BUTTON_DISABLED) 469 DCMainStep = 3 470 471 DCOpenProfsWindow () 472 return 473 474def DCOpenProfsWindow (): 475 """Opens the proficiency selection window.""" 476 477 global DCProfsWindow, DCProfsDoneButton 478 479 # load up our window and set some basic variables 480 DCProfsWindow = GemRB.LoadWindow (15) 481 NewClassId = CommonTables.Classes.GetValue (ClassName, "ID", GTV_INT) 482 if GameCheck.IsBG2(): 483 LUProfsSelection.SetupProfsWindow (pc, \ 484 LUProfsSelection.LUPROFS_TYPE_DUALCLASS, DCProfsWindow, DCProfsRedraw, classid=NewClassId) 485 else: 486 LUProfsSelection.SetupProfsWindow (pc, \ 487 LUProfsSelection.LUPROFS_TYPE_DUALCLASS, DCProfsWindow, \ 488 DCProfsRedraw, [0,0,0], [1,1,1], NewClassId, False, 0) 489 490 # setup the done and cancel 491 DCProfsDoneButton = DCProfsWindow.GetControl (76) 492 DCProfsDoneButton.SetText (11973) 493 DCProfsDoneButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DCProfsDonePress) 494 DCProfsDoneButton.SetState (IE_GUI_BUTTON_DISABLED) 495 DCProfsDoneButton.MakeDefault() 496 497 DCProfsCancelButton = DCProfsWindow.GetControl (77) 498 DCProfsCancelButton.SetText (13727) 499 DCProfsCancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, DCProfsCancelPress) 500 DCProfsCancelButton.SetState (IE_GUI_BUTTON_ENABLED) 501 DCProfsCancelButton.MakeEscape () 502 503 # show the window and draw away 504 DCProfsWindow.ShowModal (MODAL_SHADOW_GRAY) 505 DCProfsRedraw () 506 return 507 508def DCProfsRedraw (): 509 """Redraws the proficiency selection window. 510 511 Called whenever a proficiency is assigned or removed.""" 512 513 ProfsPointsLeft = GemRB.GetVar ("ProfsPointsLeft") 514 515 if ProfsPointsLeft == 0: 516 DCProfsDoneButton.SetState (IE_GUI_BUTTON_ENABLED) 517 else: 518 DCProfsDoneButton.SetState (IE_GUI_BUTTON_DISABLED) 519 return 520 521def DCProfsDonePress (): 522 """Goes to the next applicable step. 523 524 This is either skill selection, spell selection, or nothing.""" 525 526 global NewMageSpells, NewPriestMask 527 528 # check for mage spells and thief skills 529 SpellTable = CommonTables.ClassSkills.GetValue (ClassName, "MAGESPELL") 530 ClericTable = CommonTables.ClassSkills.GetValue (ClassName, "CLERICSPELL") 531 DruidTable = CommonTables.ClassSkills.GetValue (ClassName, "DRUIDSPELL") 532 if SpellTable != "*": 533 LUSpellSelection.OpenSpellsWindow (pc, SpellTable, 1, 1, 0) 534 SpellTable = GemRB.LoadTable (SpellTable) 535 GemRB.SetMemorizableSpellsCount (pc, SpellTable.GetValue (0, 0), IE_SPELL_TYPE_WIZARD, 0) 536 NewMageSpells = 1 537 if ClericTable != "*": 538 if not GemRB.HasResource(ClericTable, RES_2DA, 1): 539 ClericTable = "MXSPLPRS" # iwd1 doesn't have a DRUIDSPELL column in the table 540 # make sure we can cast spells at this level (paladins) 541 ClericTable = GemRB.LoadTable (ClericTable) 542 if ClericTable.GetRowName (0) == "1": 543 NewPriestMask = 0x4000 544 elif DruidTable != "*": 545 # make sure we can cast spells at this level (rangers) 546 if GameCheck.HasTOB (): 547 DruidTable = GemRB.LoadTable (DruidTable) 548 if DruidTable.GetRowName (0) == "1": 549 NewPriestMask = 0x8000 550 else: 551 NewPriestMask = 0x8000 552 553 # open the thieves selection window 554 OpenSkillsWindow () 555 556 # we can be done now 557 DCMainDoneButton.SetState (IE_GUI_BUTTON_ENABLED) 558 559 # close out the profs window (don't assign yet!) 560 if DCProfsWindow: 561 DCProfsWindow.Unload () 562 return 563 564def DCProfsCancelPress (): 565 """Closes the profeciency selection window.""" 566 567 # close out the profs window and go back a step 568 if DCProfsWindow: 569 DCProfsWindow.Unload () 570 DCMainWindow.ShowModal (MODAL_SHADOW_GRAY) 571 572 DCMainBackPress () 573 return 574 575def OpenSkillsWindow (): 576 """Opens the skills selection window. 577 578 This will allow the selection of thief skills for appropriate classes, or 579 auto-assign them for classes that recieve skills based on level.""" 580 581 global DCSkillsWindow, DCSkillsDoneButton 582 583 DCSkillsWindow = GemRB.LoadWindow (7) 584 if GameCheck.IsBG2(): 585 LUSkillsSelection.SetupSkillsWindow (pc, \ 586 LUSkillsSelection.LUSKILLS_TYPE_DUALCLASS, DCSkillsWindow, DCSkillsRedraw, classid=NewClassId) 587 else: 588 LUSkillsSelection.SetupSkillsWindow (pc, \ 589 LUSkillsSelection.LUSKILLS_TYPE_DUALCLASS, DCSkillsWindow, \ 590 DCSkillsRedraw, [0,0,0], [1,1,1], NewClassId, False) 591 592 #just go back if we can't assign skills 593 if GemRB.GetVar ("SkillPointsLeft") <= 0: 594 DCSkillsWindow.Close () 595 return 596 597 # setup the back and done buttons 598 BackButton = DCSkillsWindow.GetControl(24) 599 BackButton.SetText(15416) 600 BackButton.MakeEscape() 601 BackButton.SetEvent(IE_GUI_BUTTON_ON_PRESS,DCSkillsBackPress) 602 603 DCSkillsDoneButton = DCSkillsWindow.GetControl(25) 604 DCSkillsDoneButton.SetText(11973) 605 DCSkillsDoneButton.MakeDefault() 606 DCSkillsDoneButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, DCSkillsDonePress) 607 DCSkillsDoneButton.SetState(IE_GUI_BUTTON_DISABLED) 608 609 # setup the default text area 610 TextArea = DCSkillsWindow.GetControl(22) 611 TextArea.SetText(17248) 612 613 DCSkillsWindow.ShowModal (MODAL_SHADOW_GRAY) 614 DCSkillsRedraw () 615 return 616 617def DCSkillsRedraw (): 618 """Redraws the skills selection window. 619 620 Called whenever a skill is assigned or removed.""" 621 622 # no points left? we can be done! :) 623 DCSkillsLeft = GemRB.GetVar ("SkillPointsLeft") 624 if DCSkillsLeft <= 0: 625 DCSkillsDoneButton.SetState (IE_GUI_BUTTON_ENABLED) 626 else: 627 DCSkillsDoneButton.SetState (IE_GUI_BUTTON_DISABLED) 628 629def DCSkillsBackPress (): 630 """Reverts all changes to this points.""" 631 632 if DCSkillsWindow: 633 DCSkillsWindow.Unload () 634 DCMainWindow.ShowModal (MODAL_SHADOW_GRAY) 635 LUSkillsSelection.SkillsNullify () 636 DCMainBackPress () 637 return 638 639def DCSkillsDonePress (): 640 """Closes the skills selection window.""" 641 642 if DCSkillsWindow: 643 DCSkillsWindow.Unload () 644 return 645