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# common character generation display code
20import GemRB
21from ie_stats import *
22from GUIDefines import *
23import GameCheck
24import GUICommon
25import CommonTables
26import Spellbook
27from ie_restype import RES_BMP
28
29CharGenWindow = 0
30TextAreaControl = 0
31PortraitName = ""
32
33def PositionCharGenWin(window, offset = 0):
34	global CharGenWindow
35
36	CGFrame = CharGenWindow.GetFrame()
37	WFrame = window.GetFrame()
38	window.SetPos(CGFrame['x'], offset + CGFrame['y'] + (CGFrame['h'] - WFrame['h']))
39
40
41def DisplayOverview(step):
42	"""Sets up the primary character generation window."""
43
44	global CharGenWindow, TextAreaControl, PortraitName
45
46	CharGenWindow = GemRB.LoadWindow (0, "GUICG")
47	GemRB.SetVar ("Step", step)
48
49	###
50	# Buttons
51	###
52	PortraitButton = CharGenWindow.GetControl (12)
53	PortraitButton.SetFlags(IE_GUI_BUTTON_PICTURE|IE_GUI_BUTTON_NO_IMAGE,OP_SET)
54	PortraitName = GemRB.GetToken ("LargePortrait")
55	if PortraitName != None:
56		if GemRB.HasResource (PortraitName, RES_BMP, 1) or GemRB.HasResource ("NOPORTMD", RES_BMP, 1):
57			PortraitButton.SetPicture (PortraitName, "NOPORTMD")
58	PortraitButton.SetState (IE_GUI_BUTTON_LOCKED)
59
60	GenderButton = CharGenWindow.GetControl (0)
61	GenderButton.SetText (11956)
62	SetButtonStateFromStep ("GenderButton", GenderButton, step)
63
64	RaceButton = CharGenWindow.GetControl (1)
65	RaceButton.SetText (11957)
66	SetButtonStateFromStep ("RaceButton", RaceButton, step)
67
68	ClassButton = CharGenWindow.GetControl (2)
69	ClassButton.SetText (11959)
70	SetButtonStateFromStep ("ClassButton", ClassButton, step)
71
72	AlignmentButton = CharGenWindow.GetControl (3)
73	AlignmentButton.SetText (11958)
74	SetButtonStateFromStep ("AlignmentButton", AlignmentButton, step)
75
76	AbilitiesButton = CharGenWindow.GetControl (4)
77	AbilitiesButton.SetText (11960)
78	SetButtonStateFromStep ("AbilitiesButton", AbilitiesButton, step)
79
80	SkillButton = CharGenWindow.GetControl (5)
81	SkillButton.SetText (17372)
82	SetButtonStateFromStep ("SkillButton", SkillButton, step)
83
84	AppearanceButton = CharGenWindow.GetControl (6)
85	AppearanceButton.SetText (11961)
86	SetButtonStateFromStep ("AppearanceButton", AppearanceButton, step)
87
88	NameButton = CharGenWindow.GetControl (7)
89	NameButton.SetText (11963)
90	SetButtonStateFromStep ("NameButton", NameButton, step)
91
92	BackButton = CharGenWindow.GetControl (11)
93	BackButton.SetText (15416)
94	BackButton.SetState (IE_GUI_BUTTON_ENABLED)
95	BackButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, BackPress)
96	BackButton.MakeEscape()
97
98	AcceptButton = CharGenWindow.GetControl (8)
99	playmode = GemRB.GetVar ("PlayMode")
100	if playmode>=0:
101		AcceptButton.SetText (11962)
102	else:
103		AcceptButton.SetText (13956)
104	SetButtonStateFromStep ("AcceptButton", AcceptButton, step)
105	#AcceptButton.MakeDefault()
106	AcceptButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, NextPress)
107
108	# now automatically ignored and added instead
109	#ScrollBar = CharGenWindow.GetControl (10)
110	#ScrollBar.SetDefaultScrollBar ()
111
112	ImportButton = CharGenWindow.GetControl (13)
113	ImportButton.SetText (13955)
114	ImportButton.SetState (IE_GUI_BUTTON_ENABLED)
115	ImportButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, ImportPress)
116
117	CancelButton = CharGenWindow.GetControl (15)
118	if step == 1:
119		CancelButton.SetText (13727) # Cancel
120	else:
121		CancelButton.SetText (8159) # Start over
122	CancelButton.SetState (IE_GUI_BUTTON_ENABLED)
123	CancelButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, CancelPress)
124
125	BiographyButton = CharGenWindow.GetControl (16)
126	BiographyButton.SetText (18003)
127	BiographyButton.SetEvent (IE_GUI_BUTTON_ON_PRESS, BiographyPress)
128	if step == 9:
129		BiographyButton.SetState (IE_GUI_BUTTON_ENABLED)
130	else:
131		BiographyButton.SetState (IE_GUI_BUTTON_DISABLED)
132
133	###
134	# Stat overview
135	###
136	AbilityTable = GemRB.LoadTable ("ability")
137
138	MyChar = GemRB.GetVar ("Slot")
139	TextAreaControl= CharGenWindow.GetControl (9)
140	TextAreaControl.SetText ("")
141
142	for part in range(1, step+1):
143		if part == 1:
144			if step == 1:
145				TextAreaControl.SetText (GemRB.GetString(16575))
146			elif step == 9:
147				TextAreaControl.SetText ("")
148		elif part == 2:
149			if step == 9:
150				TextAreaControl.Append (GemRB.GetString(1047) + ": " + GemRB.GetToken ("CHARNAME") + "\n")
151
152			if GemRB.GetPlayerStat (MyChar, IE_SEX) == 1:
153				gender = GemRB.GetString (1050)
154			else:
155				gender = GemRB.GetString (1051)
156			TextAreaControl.Append (GemRB.GetString(12135) + ": " + gender + "\n")
157		elif part == 3:
158			stat = GemRB.GetPlayerStat(MyChar, IE_RACE)
159			v = CommonTables.Races.FindValue (3, stat)
160			TextAreaControl.Append (GemRB.GetString (1048) + ": " + CommonTables.Races.GetValue (v, 2, GTV_REF) + "\n")
161		elif part == 4:
162			ClassTitle = GUICommon.GetActorClassTitle (MyChar)
163			TextAreaControl.Append (GemRB.GetString(12136) + ": " + ClassTitle + "\n")
164		elif part == 5:
165			stat = GemRB.GetPlayerStat (MyChar, IE_ALIGNMENT)
166			v = CommonTables.Aligns.FindValue (3, stat)
167			TextAreaControl.Append (GemRB.GetString(1049) + ": " + CommonTables.Aligns.GetValue (v, 2, GTV_REF) + "\n")
168		elif part == 6:
169			TextAreaControl.Append ("\n")
170			ClassName = GUICommon.GetClassRowName (MyChar)
171			strextra = GemRB.GetPlayerStat (MyChar, IE_STREXTRA)
172			for i in range(6):
173				v = AbilityTable.GetValue (i, 2, GTV_REF)
174				StatID = AbilityTable.GetValue (i, 3)
175				stat = GemRB.GetPlayerStat (MyChar, StatID)
176				if (i == 0) and (strextra > 0) and (stat==18):
177					TextAreaControl.Append (v + ": " + str(stat) + "/" + str(strextra) + "\n")
178				else:
179					TextAreaControl.Append (v + ": " + str(stat) + "\n")
180		elif part == 7:
181			# thieving and other skills
182			info = ""
183			SkillTable = GemRB.LoadTable ("skills")
184			RangerSkills = CommonTables.ClassSkills.GetValue (ClassName, "RANGERSKILL")
185			BardSkills = CommonTables.ClassSkills.GetValue (ClassName, "BARDSKILL")
186			KitName = GUICommon.GetKitIndex (MyChar)
187			if KitName == 0:
188				KitName = ClassName
189			else:
190				KitName = CommonTables.KitList.GetValue (KitName, 0)
191
192			if SkillTable.GetValue ("RATE", KitName) != -1:
193				for skill in range(SkillTable.GetRowCount () - 2):
194					name = SkillTable.GetValue (skill+2, 1, GTV_REF)
195					available = SkillTable.GetValue (SkillTable.GetRowName (skill+2), KitName)
196					statID = SkillTable.GetValue (skill+2, 2)
197					value = GemRB.GetPlayerStat (MyChar, statID, 1)
198					if value >= 0 and available != -1:
199						info += name + ": " + str(value) + "\n"
200			elif BardSkills != "*" or RangerSkills != "*":
201				for skill in range(SkillTable.GetRowCount () - 2):
202					name = SkillTable.GetValue (skill+2, 1, GTV_REF)
203					StatID = SkillTable.GetValue (skill+2, 2)
204					value = GemRB.GetPlayerStat (MyChar, StatID, 1)
205					if value > 0:
206						info += name + ": " + str(value) + "\n"
207			if info != "":
208				TextAreaControl.Append ("\n" + GemRB.GetString(8442) + "\n" + info)
209
210			# arcane spells
211			info = Spellbook.GetKnownSpellsDescription (MyChar, IE_SPELL_TYPE_WIZARD)
212			if info != "":
213				TextAreaControl.Append ("\n" + GemRB.GetString(11027) + "\n" + info)
214
215			# divine spells
216			info = Spellbook.GetKnownSpellsDescription (MyChar, IE_SPELL_TYPE_PRIEST)
217			if info != "":
218				TextAreaControl.Append ("\n" + GemRB.GetString(11028) + "\n" + info)
219
220			# racial enemy
221			info = ""
222			Race = GemRB.GetVar ("HatedRace")
223			if Race:
224				HateRaceTable = GemRB.LoadTable ("HATERACE")
225				Row = HateRaceTable.FindValue (1, Race)
226				info = HateRaceTable.GetValue (Row, 0, GTV_REF) + "\n"
227				if info != "":
228					TextAreaControl.Append ("\n" + GemRB.GetString(15982) + "\n" + info)
229
230			# weapon proficiencies
231			TextAreaControl.Append ("\n")
232			TextAreaControl.Append (9466)
233			TextAreaControl.Append ("\n")
234			TmpTable=GemRB.LoadTable ("weapprof")
235			ProfCount = TmpTable.GetRowCount ()
236			#bg2 weapprof.2da contains the bg1 proficiencies too, skipping those
237			for i in range(ProfCount-8):
238				# 4294967296 overflows to -1 on some arches, so we use a smaller invalid strref
239				strref = TmpTable.GetValue (i+8, 1)
240				if strref == -1 or strref > 500000:
241					continue
242				Weapon = GemRB.GetString (strref)
243				StatID = TmpTable.GetValue (i+8, 0)
244				Value = GemRB.GetPlayerStat (MyChar, StatID )
245				if Value:
246					pluses = " "
247					for plus in range(0, Value):
248						pluses += "+"
249					TextAreaControl.Append (Weapon + pluses + "\n")
250
251		elif part == 8:
252			break
253
254	CharGenWindow.Focus()
255	return
256
257def SetButtonStateFromStep (buttonName, button, step):
258	"""Updates selectable buttons based upon current step."""
259
260	global CharGenWindow
261
262	state = IE_GUI_BUTTON_DISABLED
263	if buttonName == "GenderButton":
264		if step == 1:
265			state = IE_GUI_BUTTON_ENABLED
266	elif buttonName == "RaceButton":
267		if step == 2:
268			state = IE_GUI_BUTTON_ENABLED
269	elif buttonName == "ClassButton":
270		if step == 3:
271			state = IE_GUI_BUTTON_ENABLED
272	elif buttonName == "AlignmentButton":
273		if step == 4:
274			state = IE_GUI_BUTTON_ENABLED
275	elif buttonName == "AbilitiesButton":
276		if step == 5:
277			state = IE_GUI_BUTTON_ENABLED
278	elif buttonName == "SkillButton":
279		if step == 6:
280			state = IE_GUI_BUTTON_ENABLED
281	elif buttonName == "AppearanceButton":
282		if step == 7:
283			state = IE_GUI_BUTTON_ENABLED
284	elif buttonName == "NameButton":
285		if step == 8:
286			state = IE_GUI_BUTTON_ENABLED
287	elif buttonName == "AcceptButton":
288		if step == 9:
289			state = IE_GUI_BUTTON_ENABLED
290		elif GameCheck.IsBG2Demo ():
291			state = IE_GUI_BUTTON_LOCKED
292	button.SetState (state)
293
294	if state == IE_GUI_BUTTON_ENABLED:
295		button.Focus()
296		button.SetEvent (IE_GUI_BUTTON_ON_PRESS, NextPress)
297	return
298
299def CancelPress():
300	"""Revert back to the first step; if there, free the actor."""
301
302	global CharGenWindow
303	if CharGenWindow:
304		CharGenWindow.Unload ()
305
306	step = GemRB.GetVar ("Step")
307	if step == 1:
308		#free up the slot before exiting
309		MyChar = GemRB.GetVar ("Slot")
310		GemRB.CreatePlayer ("", MyChar | 0x8000 )
311	else:
312		GemRB.SetNextScript ("CharGen")
313		GemRB.SetToken ("LargePortrait", "")
314		GemRB.SetToken ("SmallPortrait", "")
315	return
316
317def ImportPress():
318	"""Opens the character import window."""
319
320	step = GemRB.GetVar ("Step")
321	# TODO: check why this is handled differently
322	if step == 1:
323		GemRB.SetNextScript("GUICG24")
324	else:
325		GemRB.SetToken ("NextScript", "CharGen9")
326		GemRB.SetNextScript ("ImportFile") #import
327	return
328
329def BackPress():
330	"""Moves to the previous step."""
331
332	global CharGenWindow
333	if CharGenWindow:
334		CharGenWindow.Unload ()
335
336	step = GemRB.GetVar ("Step")
337	if step == 2:
338		GemRB.SetNextScript ("CharGen")
339	elif step != 1:
340		GemRB.SetNextScript ("CharGen" + str(step-1))
341	return
342
343def NextPress():
344	"""Moves to the next step."""
345
346	step = GemRB.GetVar ("Step")
347	if step == 1:
348		GemRB.SetNextScript ("GUICG1")
349	elif step == 2:
350		GemRB.SetNextScript ("GUICG8")
351	elif step == 6:
352		GemRB.SetNextScript ("GUICG15")
353	elif step == 7:
354		GemRB.SetNextScript ("GUICG13")
355	elif step == 8:
356		GemRB.SetNextScript ("GUICG5")
357	elif step == 9:
358		GemRB.SetNextScript ("CharGenEnd")
359	else: # 3, 4, 5
360		GemRB.SetNextScript ("GUICG" + str(step-1))
361	return
362
363def BiographyPress():
364	"""Opens the biography window."""
365	GemRB.SetNextScript("GUICG23") #biography
366	return
367