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