1# -*-python-*-
2# GemRB - Infinity Engine Emulator
3# Copyright (C) 2003 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
20
21# GUIREC.py - scripts to control stats/records windows from GUIREC winpack
22
23# GUIREC:
24# 0,1,2 - common windows (time, message, menu)
25# 3 - main statistics window
26# 4 - level up win
27# 5 - info - kills, weapons ...
28# 6 - dual class list ???
29# 7 - class panel
30# 8 - skills panel
31# 9 - choose mage spells panel
32# 10 - some small win, 1 button
33# 11 - some small win, 2 buttons
34# 12 - biography?
35# 13 - specialist mage panel
36# 14 - proficiencies
37# 15 - some 2 panel window
38# 16 - some 2 panel window
39# 17 - some 2 panel window
40
41
42# MainWindow:
43# 0 - main textarea
44# 1 - its scrollbar
45# 2 - WMCHRP character portrait
46# 5 - STALIGN alignment
47# 6 - STFCTION faction
48# 7,8,9 - STCSTM (info, reform party, level up)
49# 0x1000000a - name
50#0x1000000b - ac
51#0x1000000c, 0x1000000d hp now, hp max
52#0x1000000e str
53#0x1000000f int
54#0x10000010 wis
55#0x10000011 dex
56#0x10000012 con
57#0x10000013 chr
58#x10000014 race
59#x10000015 sex
60#0x10000016 class
61
62#31-36 stat buts
63#37 ac but
64#38 hp but?
65
66###################################################
67import GemRB
68import GUICommon
69import CommonTables
70import LevelUp
71import LUCommon
72import GUICommonWindows
73import NewLife
74from GUIDefines import *
75from ie_stats import *
76import GUIWORLD
77import LUSkillsSelection
78
79###################################################
80LevelUpWindow = None
81RecordsWindow = None
82InformationWindow = None
83BiographyWindow = None
84
85###################################################
86
87LevelDiff = 0
88Level = 0
89Classes = 0
90NumClasses = 0
91
92###################################################
93
94def InitRecordsWindow (Window):
95	global RecordsWindow
96	global StatTable
97
98	RecordsWindow = Window
99	StatTable = GemRB.LoadTable("abcomm")
100
101	# Information
102	Button = Window.GetControl (7)
103	Button.SetText (4245)
104	Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenInformationWindow)
105
106	# Reform Party
107	Button = Window.GetControl (8)
108	Button.SetText (4244)
109	Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, GUIWORLD.OpenReformPartyWindow)
110
111	# Level Up
112	Button = Window.GetControl (9)
113	Button.SetText (4246)
114	Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenLevelUpWindow)
115
116	statevents = (OnRecordsHelpStrength, OnRecordsHelpIntelligence, OnRecordsHelpWisdom, OnRecordsHelpDexterity, OnRecordsHelpConstitution, OnRecordsHelpCharisma)
117	# stat buttons
118	for i in range (6):
119		Button = Window.GetControl (31 + i)
120		Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE, OP_SET)
121		Button.SetSprites("", 0, 0, 0, 0, 0)
122		Button.SetState (IE_GUI_BUTTON_LOCKED)
123		Button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, statevents[i])
124		Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, OnRecordsButtonLeave)
125
126	# AC button
127	Button = Window.GetControl (37)
128	Button.SetFlags(IE_GUI_BUTTON_NO_IMAGE, OP_SET)
129	Button.SetSprites("", 0, 0, 0, 0, 0)
130	Button.SetState (IE_GUI_BUTTON_LOCKED)
131	Button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, OnRecordsHelpArmorClass)
132	Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, OnRecordsButtonLeave)
133
134
135	# HP button
136	Button = Window.GetControl (38)
137	Button.SetFlags (IE_GUI_BUTTON_NO_IMAGE, OP_SET)
138	Button.SetSprites ("", 0, 0, 0, 0, 0)
139	Button.SetState (IE_GUI_BUTTON_LOCKED)
140	Button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, OnRecordsHelpHitPoints)
141	Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, OnRecordsButtonLeave)
142
143	return
144
145
146stats_overview = None
147faction_help = ''
148alignment_help = ''
149avatar_header = {'PrimClass': "", 'SecoClass': "", 'PrimLevel': 0, 'SecoLevel': 0, 'XP': 0, 'PrimNextLevXP': 0, 'SecoNextLevXP': 0}
150
151def UpdateRecordsWindow (Window):
152	global stats_overview, faction_help, alignment_help
153
154	pc = GemRB.GameGetSelectedPCSingle ()
155
156	# Setting up the character information
157	GetCharacterHeader (pc)
158
159	# Checking whether character has leveled up.
160	Button = Window.GetControl (9)
161	if LUCommon.CanLevelUp (pc):
162		Button.SetState (IE_GUI_BUTTON_ENABLED)
163	else:
164		Button.SetState (IE_GUI_BUTTON_DISABLED)
165
166	# name
167	Label = Window.GetControl (0x1000000a)
168	Label.SetText (GemRB.GetPlayerName (pc, 1))
169
170	# portrait
171	Image = Window.GetControl (2)
172	Image.SetState (IE_GUI_BUTTON_LOCKED)
173	Image.SetFlags(IE_GUI_BUTTON_NO_IMAGE | IE_GUI_BUTTON_PICTURE, OP_SET)
174	Image.SetPicture (GUICommonWindows.GetActorPortrait (pc, 'STATS'))
175
176	# armorclass
177	Label = Window.GetControl (0x1000000b)
178	Label.SetText (str (GemRB.GetPlayerStat (pc, IE_ARMORCLASS)))
179	Label.SetTooltip (4197)
180
181	# hp now
182	Label = Window.GetControl (0x1000000c)
183	Label.SetText (str (GemRB.GetPlayerStat (pc, IE_HITPOINTS)))
184	Label.SetTooltip (4198)
185
186	# hp max
187	Label = Window.GetControl (0x1000000d)
188	Label.SetText (str (GemRB.GetPlayerStat (pc, IE_MAXHITPOINTS)))
189	Label.SetTooltip (4199)
190
191	# stats
192
193	sstr = GemRB.GetPlayerStat (pc, IE_STR)
194	bstr = GemRB.GetPlayerStat (pc, IE_STR,1)
195	sstrx = GemRB.GetPlayerStat (pc, IE_STREXTRA)
196	bstrx = GemRB.GetPlayerStat (pc, IE_STREXTRA,1)
197	if (sstrx > 0) and (sstr==18):
198		sstr = "%d/%02d" %(sstr, sstrx % 100)
199	if (bstrx > 0) and (bstr==18):
200		bstr = "%d/%02d" %(bstr, bstrx % 100)
201	sint = GemRB.GetPlayerStat (pc, IE_INT)
202	bint = GemRB.GetPlayerStat (pc, IE_INT,1)
203	swis = GemRB.GetPlayerStat (pc, IE_WIS)
204	bwis = GemRB.GetPlayerStat (pc, IE_WIS,1)
205	sdex = GemRB.GetPlayerStat (pc, IE_DEX)
206	bdex = GemRB.GetPlayerStat (pc, IE_DEX,1)
207	scon = GemRB.GetPlayerStat (pc, IE_CON)
208	bcon = GemRB.GetPlayerStat (pc, IE_CON,1)
209	schr = GemRB.GetPlayerStat (pc, IE_CHR)
210	bchr = GemRB.GetPlayerStat (pc, IE_CHR,1)
211
212	stats = (sstr, sint, swis, sdex, scon, schr)
213	basestats = (bstr, bint, bwis, bdex, bcon, bchr)
214	for i in range (6):
215		Label = Window.GetControl (0x1000000e + i)
216		if stats[i]!=basestats[i]:
217			Label.SetTextColor ({'r' : 255, 'g' : 0, 'b' : 0})
218		else:
219			Label.SetTextColor ({'r' : 255, 'g' : 255, 'b' : 255})
220		Label.SetText (str (stats[i]))
221
222	# race
223
224	# this is -1 to lookup the value in the table
225	race = GemRB.GetPlayerStat (pc, IE_SPECIES) - 1
226
227	# workaround for original saves that don't have the characters species stat set properly
228	if race == -1:
229		if GemRB.GetPlayerStat (pc, IE_SPECIFIC) == 3: # Vhailor
230			race = 50 # Changes from GHOST to RESTLESS_SPIRIT
231		elif  GemRB.GetPlayerStat (pc, IE_SPECIFIC) == 9: # Morte
232			race = 44 # Changes from HUMAN to MORTE. Morte is Morte :)
233		else:
234			race = GemRB.GetPlayerStat (pc, IE_RACE) - 1
235
236	text = CommonTables.Races.GetValue (race, 0)
237
238	Label = Window.GetControl (0x10000014)
239	Label.SetText (text)
240
241
242	# sex
243	GenderTable = GemRB.LoadTable ("GENDERS")
244	text = GenderTable.GetValue (GemRB.GetPlayerStat (pc, IE_SEX) - 1, GTV_STR)
245
246	Label = Window.GetControl (0x10000015)
247	Label.SetText (text)
248
249
250	# class
251	text = CommonTables.Classes.GetValue (GUICommon.GetClassRowName (pc), "NAME_REF")
252
253	Label = Window.GetControl (0x10000016)
254	Label.SetText (text)
255
256	# alignment
257	align = GemRB.GetPlayerStat (pc, IE_ALIGNMENT)
258	ss = GemRB.LoadSymbol ("ALIGN")
259	sym = ss.GetValue (align)
260
261	AlignmentTable = GemRB.LoadTable ("ALIGNS")
262	alignment_help = AlignmentTable.GetValue (sym, 'DESC_REF', GTV_REF)
263	frame = (3 * int (align / 16) + align % 16) - 4
264
265	Button = Window.GetControl (5)
266	Button.SetState (IE_GUI_BUTTON_LOCKED)
267	Button.SetSprites ('STALIGN', 0, frame, 0, 0, 0)
268	Button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, OnRecordsHelpAlignment)
269	Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, OnRecordsButtonLeave)
270
271
272	# faction
273	faction = GemRB.GetPlayerStat (pc, IE_FACTION)
274	FactionTable = GemRB.LoadTable ("FACTIONS")
275	faction_help = FactionTable.GetValue (faction, 0, GTV_REF)
276	frame = FactionTable.GetValue (faction, 1)
277
278	Button = Window.GetControl (6)
279	Button.SetState (IE_GUI_BUTTON_LOCKED)
280	Button.SetSprites ('STFCTION', 0, frame, 0, 0, 0)
281	Button.SetEvent (IE_GUI_MOUSE_ENTER_BUTTON, OnRecordsHelpFaction)
282	Button.SetEvent (IE_GUI_MOUSE_LEAVE_BUTTON, OnRecordsButtonLeave)
283
284	# help, info textarea
285	stats_overview = GetStatOverview (pc)
286	Text = Window.GetControl (0)
287	Text.SetText (stats_overview)
288	return
289
290ToggleRecordsWindow = GUICommonWindows.CreateTopWinLoader(3, "GUIREC", GUICommonWindows.ToggleWindow, InitRecordsWindow, UpdateRecordsWindow, WINDOW_TOP|WINDOW_HCENTER, True)
291OpenRecordsWindow = GUICommonWindows.CreateTopWinLoader(3, "GUIREC", GUICommonWindows.OpenWindowOnce, InitRecordsWindow, UpdateRecordsWindow, WINDOW_TOP|WINDOW_HCENTER, True)
292
293# puts default info to textarea (overview of PC's bonuses, saves, etc.
294def OnRecordsButtonLeave ():
295	OnRecordsHelpStat (-1, 0, stats_overview)
296	return
297
298def OnRecordsHelpFaction ():
299	Help = GemRB.GetString (20106) + "\n\n" + faction_help
300	OnRecordsHelpStat (-1, 0, Help)
301	return
302
303def OnRecordsHelpArmorClass ():
304	OnRecordsHelpStat (-1, 0, 18493)
305	return
306
307def OnRecordsHelpHitPoints ():
308	OnRecordsHelpStat (-1, 0, 18494)
309	return
310
311def OnRecordsHelpAlignment ():
312	Help = GemRB.GetString (20105) + "\n\n" + alignment_help
313	OnRecordsHelpStat (-1, 0, Help)
314	return
315
316#Bio:
317# 38787 no
318# 39423 morte
319# 39424 annah
320# 39425 dakkon
321# 39426 ffg
322# 39427 ignus
323# 39428 nordom
324# 39429 vhailor
325
326def OnRecordsHelpStat (row, col, strref, bon1=0, bon2=0):
327	TextArea = RecordsWindow.GetControl (0)
328	TextArea.SetText (strref)
329	if row != -1:
330		TextArea.Append ("\n\n" + GemRB.StatComment (StatTable.GetValue(str(row),col), bon1, bon2) )
331	return
332
333def OnRecordsHelpStrength ():
334	# These are used to get the stats
335	pc = GemRB.GameGetSelectedPCSingle ()
336
337	# Getting the character's strength
338	s = GemRB.GetPlayerStat (pc, IE_STR)
339	e = GemRB.GetPlayerStat (pc, IE_STREXTRA)
340
341	x = CommonTables.StrMod.GetValue(s, 0) + CommonTables.StrModEx.GetValue(e, 0)
342	y = CommonTables.StrMod.GetValue(s, 1) + CommonTables.StrModEx.GetValue(e, 1)
343	if x==0:
344		x=y
345		y=0
346	if e>60:
347		s=19
348
349	OnRecordsHelpStat (s, "STR", 18489, x, y)
350	return
351
352def OnRecordsHelpDexterity ():
353	# Loading table of modifications
354	Table = GemRB.LoadTable("dexmod")
355
356	# These are used to get the stats
357	pc = GemRB.GameGetSelectedPCSingle ()
358
359	# Getting the character's dexterity
360	Dex = GemRB.GetPlayerStat (pc, IE_DEX)
361
362	# Getting the dexterity description
363	x = -Table.GetValue(Dex,2)
364
365	OnRecordsHelpStat (Dex, "DEX", 18487, x)
366	return
367
368def OnRecordsHelpIntelligence ():
369	# These are used to get the stats
370	pc = GemRB.GameGetSelectedPCSingle ()
371
372	# Getting the character's intelligence
373	Int = GemRB.GetPlayerStat (pc, IE_INT)
374	OnRecordsHelpStat (Int, "INT", 18488)
375	return
376
377def OnRecordsHelpWisdom ():
378	# These are used to get the stats
379	pc = GemRB.GameGetSelectedPCSingle ()
380
381	# Getting the character's wisdom
382	Wis = GemRB.GetPlayerStat (pc, IE_WIS)
383	OnRecordsHelpStat (Wis, "WIS", 18490)
384	return
385
386def OnRecordsHelpConstitution ():
387	# Loading table of modifications
388	Table = GemRB.LoadTable("hpconbon")
389
390	# These are used to get the stats
391	pc = GemRB.GameGetSelectedPCSingle ()
392
393	# Getting the character's constitution
394	Con = GemRB.GetPlayerStat (pc, IE_CON)
395
396	# Getting the constitution description
397	x = Table.GetValue(Con-1,1)
398
399	OnRecordsHelpStat (Con, "CON", 18491, x)
400	return
401
402def OnRecordsHelpCharisma ():
403	# These are used to get the stats
404	pc = GemRB.GameGetSelectedPCSingle ()
405
406	# Getting the character's charisma
407	Cha = GemRB.GetPlayerStat (pc, IE_CHR)
408	OnRecordsHelpStat (Cha, "CHR", 1903)
409	return
410
411def GetCharacterHeader (pc):
412	global avatar_header
413
414	Class = GemRB.GetPlayerStat (pc, IE_CLASS) - 1
415	Multi = GUICommon.HasMultiClassBits (pc)
416
417	# Nameless is a special case (dual class)
418	if GUICommon.IsNamelessOne(pc):
419		avatar_header['PrimClass'] = CommonTables.Classes.GetRowName (Class)
420		avatar_header['SecoClass'] = "*"
421
422		avatar_header['SecoLevel'] = 0
423
424		if avatar_header['PrimClass'] == "FIGHTER":
425			avatar_header['PrimLevel'] = GemRB.GetPlayerStat (pc, IE_LEVEL)
426			avatar_header['XP'] = GemRB.GetPlayerStat (pc, IE_XP)
427		elif avatar_header['PrimClass'] == "MAGE":
428			avatar_header['PrimLevel'] = GemRB.GetPlayerStat (pc, IE_LEVEL2)
429			avatar_header['XP'] = GemRB.GetPlayerStat (pc, IE_XP_MAGE)
430		else:
431			avatar_header['PrimLevel'] = GemRB.GetPlayerStat (pc, IE_LEVEL3)
432			avatar_header['XP'] = GemRB.GetPlayerStat (pc, IE_XP_THIEF)
433
434		avatar_header['PrimNextLevXP'] = GetNextLevelExp (avatar_header['PrimLevel'], avatar_header['PrimClass'])
435		avatar_header['SecoNextLevXP'] = 0
436	else:
437		# PC is not NAMELESS_ONE
438		avatar_header['PrimLevel'] = GemRB.GetPlayerStat (pc, IE_LEVEL)
439		avatar_header['XP'] = GemRB.GetPlayerStat (pc, IE_XP)
440		if Multi:
441			avatar_header['XP'] = avatar_header['XP'] / 2
442			avatar_header['SecoLevel'] = GemRB.GetPlayerStat (pc, IE_LEVEL2)
443
444			avatar_header['PrimClass'] = "FIGHTER"
445			if Multi == 3:
446				#fighter/mage
447				Class = 0
448			else:
449				#fighter/thief
450				Class = 3
451			avatar_header['SecoClass'] = CommonTables.Classes.GetRowName (Class)
452
453			avatar_header['PrimNextLevXP'] = GetNextLevelExp (avatar_header['PrimLevel'], avatar_header['PrimClass'])
454			avatar_header['SecoNextLevXP'] = GetNextLevelExp (avatar_header['SecoLevel'], avatar_header['SecoClass'])
455
456			# Converting to the displayable format
457			avatar_header['SecoClass'] = CommonTables.Classes.GetValue (avatar_header['SecoClass'], "NAME_REF", GTV_REF)
458		else:
459			avatar_header['SecoLevel'] = 0
460			avatar_header['PrimClass'] = CommonTables.Classes.GetRowName (Class)
461			avatar_header['SecoClass'] = "*"
462			avatar_header['PrimNextLevXP'] = GetNextLevelExp (avatar_header['PrimLevel'], avatar_header['PrimClass'])
463			avatar_header['SecoNextLevXP'] = 0
464
465	# Converting to the displayable format
466	avatar_header['PrimClass'] = CommonTables.Classes.GetValue (avatar_header['PrimClass'], "NAME_REF", GTV_REF)
467
468
469
470def GetNextLevelExp (Level, Class):
471	if (Level < 20):
472		NextLevel = CommonTables.NextLevel.GetValue (Class, str (Level + 1))
473	else:
474		After21ExpTable = GemRB.LoadTable ("LVL21PLS")
475		ExpGap = After21ExpTable.GetValue (Class, 'XPGAP')
476		LevDiff = Level - 19
477		Lev20Exp = CommonTables.NextLevel.GetValue (Class, "20")
478		NextLevel = Lev20Exp + (LevDiff * ExpGap)
479
480	return NextLevel
481
482
483def GetStatOverview (pc):
484	won = "[color=FFFFFF]"
485	woff = "[/color]"
486	str_None = GemRB.GetString (41275)
487
488	GS = lambda s, pc=pc: GemRB.GetPlayerStat (pc, s)
489
490	stats = []
491
492	# Displaying Class, Level, Experience and Next Level Experience
493	if (avatar_header['SecoLevel'] == 0):
494		stats.append ((avatar_header['PrimClass'], "", 'd'))
495		stats.append ((48156, avatar_header['PrimLevel'], ''))
496		stats.append ((19673, avatar_header['XP'], ''))
497		stats.append ((19674, avatar_header['PrimNextLevXP'], ''))
498	else:
499		stats.append ((19414, "", ''))
500		stats.append (None)
501		stats.append ((avatar_header['PrimClass'], "", 'd'))
502		stats.append ((48156, avatar_header['PrimLevel'], ''))
503		stats.append ((19673, avatar_header['XP'], ''))
504		stats.append ((19674, avatar_header['PrimNextLevXP'], ''))
505		stats.append (None)
506		stats.append ((avatar_header['SecoClass'], "", 'd'))
507		stats.append ((48156, avatar_header['SecoLevel'], ''))
508		stats.append ((19673, avatar_header['XP'], ''))
509		stats.append ((19674, avatar_header['SecoNextLevXP'], ''))
510
511	# 59856 Current State
512	stats.append (None)
513	StatesTable = GemRB.LoadTable ("states")
514	StateID = GS (IE_STATE_ID)
515	State = StatesTable.GetValue (str (StateID), "NAME_REF", GTV_REF)
516	stats.append ((won + GemRB.GetString (59856) + woff, "", 'd'))
517	stats.append ((State, "", 'd'))
518	stats.append (None)
519
520	# 67049 AC Bonuses
521	stats.append (67049)
522	#   67204 AC vs. Slashing
523	stats.append ((67204, GS (IE_ACSLASHINGMOD), ''))
524	#   67205 AC vs. Piercing
525	stats.append ((67205, GS (IE_ACPIERCINGMOD), ''))
526	#   67206 AC vs. Crushing
527	stats.append ((67206, GS (IE_ACCRUSHINGMOD), ''))
528	#   67207 AC vs. Missile
529	stats.append ((67207, GS (IE_ACMISSILEMOD), ''))
530	stats.append (None)
531
532
533	# 67208 Resistances
534	stats.append (67208)
535	#   67209 Normal Fire
536	stats.append ((67209, GS (IE_RESISTFIRE), '%'))
537	#   67210 Magic Fire
538	stats.append ((67210, GS (IE_RESISTMAGICFIRE), '%'))
539	#   67211 Normal Cold
540	stats.append ((67211, GS (IE_RESISTCOLD), '%'))
541	#   67212 Magic Cold
542	stats.append ((67212, GS (IE_RESISTMAGICCOLD), '%'))
543	#   67213 Electricity
544	stats.append ((67213, GS (IE_RESISTELECTRICITY), '%'))
545	#   67214 Acid
546	stats.append ((67214, GS (IE_RESISTACID), '%'))
547	#   67215 Magic
548	stats.append ((67215, GS (IE_RESISTMAGIC), '%'))
549	#   67216 Slashing Attacks
550	stats.append ((67216, GS (IE_RESISTSLASHING), '%'))
551	#   67217 Piercing Attacks
552	stats.append ((67217, GS (IE_RESISTPIERCING), '%'))
553	#   67218 Crushing Attacks
554	stats.append ((67218, GS (IE_RESISTCRUSHING), '%'))
555	#   67219 Missile Attacks
556	stats.append ((67219, GS (IE_RESISTMISSILE), '%'))
557	stats.append (None)
558
559	# 4220 Proficiencies
560	stats.append (4220)
561	#   4208 THAC0
562	stats.append ((4208, GS (IE_TOHIT), ''))
563	#   4209 Number of Attacks
564	tmp = GemRB.GetCombatDetails(pc, 0)["APR"]
565
566	if (tmp&1):
567		tmp2 = str(tmp/2) + chr(189)
568	else:
569		tmp2 = str(tmp/2)
570
571	stats.append ((4209, tmp2, ''))
572	#   4210 Lore
573	stats.append ((4210, GS (IE_LORE), ''))
574	#   4211 Open Locks
575	stats.append ((4211, GS (IE_LOCKPICKING), '%'))
576	#   4212 Stealth
577	stats.append ((4212, GS (IE_STEALTH), '%'))
578	#   4213 Find/Remove Traps
579	stats.append ((4213, GS (IE_TRAPS), '%'))
580	#   4214 Pick Pockets
581	stats.append ((4214, GS (IE_PICKPOCKET), '%'))
582	#   4215 Tracking
583	stats.append ((4215, GS (IE_TRACKING), ''))
584	#   4216 Reputation
585	stats.append ((4216, GS (IE_REPUTATION), ''))
586	#   4217 Turn Undead Level
587	stats.append ((4217, GS (IE_TURNUNDEADLEVEL), ''))
588	#   4218 Lay on Hands Amount
589	stats.append ((4218, GS (IE_LAYONHANDSAMOUNT), ''))
590	#   4219 Backstab Damage
591	stats.append ((4219, GS (IE_BACKSTABDAMAGEMULTIPLIER), 'x'))
592	stats.append (None)
593
594	# 4221 Saving Throws
595	stats.append (4221)
596	#   4222 Paralyze/Poison/Death
597	stats.append ((4222, GS (IE_SAVEVSDEATH), ''))
598	#   4223 Rod/Staff/Wand
599	stats.append ((4223, GS (IE_SAVEVSWANDS), ''))
600	#   4224 Petrify/Polymorph
601	stats.append ((4224, GS (IE_SAVEVSPOLY), ''))
602	#   4225 Breath Weapon
603	stats.append ((4225, GS (IE_SAVEVSBREATH), ''))
604	#   4226 Spells
605	stats.append ((4226, GS (IE_SAVEVSSPELL), ''))
606	stats.append (None)
607
608	# 4227 Weapon Proficiencies
609	stats.append (4227)
610	#   55011 Unused Slots
611	stats.append ((55011, GS (IE_FREESLOTS), ''))
612	#   33642 Fist
613	stats.append ((33642, GS (IE_PROFICIENCYBASTARDSWORD), '+'))
614	#   33649 Edged Weapon
615	stats.append ((33649, GS (IE_PROFICIENCYLONGSWORD), '+'))
616	#   33651 Hammer
617	stats.append ((33651, GS (IE_PROFICIENCYSHORTSWORD), '+'))
618	#   44990 Axe
619	stats.append ((44990, GS (IE_PROFICIENCYAXE), '+'))
620	#   33653 Club
621	stats.append ((33653, GS (IE_PROFICIENCYTWOHANDEDSWORD), '+'))
622	#   33655 Bow
623	stats.append ((33655, GS (IE_PROFICIENCYKATANA), '+'))
624	stats.append (None)
625
626	# 4228 Ability Bonuses
627	stats.append (4228)
628	#   4229 To Hit
629	#   4230 Damage
630	#   4231 Open Doors
631	#   4232 Weight Allowance
632	#   4233 Armor Class Bonus
633	#   4234 Missile Adjustment
634	stats.append ((4234, GS (IE_ACMISSILEMOD), ''))
635	#   4236 CON HP Bonus/Level
636	#   4240 Reaction
637	stats.append (None)
638
639	# 4238 Magical Defense Adjustment
640	stats.append (4238)
641	#   4239 Bonus Priest Spells
642	stats.append ((4239, GS (IE_CASTINGLEVELBONUSCLERIC), ''))
643	stats.append (None)
644
645	# 4237 Chance to learn spell
646	#SpellLearnChance = won + GemRB.GetString (4237) + woff
647
648	# ??? 4235 Reaction Adjustment
649
650	res = []
651	lines = 0
652	for s in stats:
653		try:
654			strref, val, stattype = s
655			if val == 0 and stattype != '0':
656				continue
657			if stattype == '+':
658				res.append (GemRB.GetString (strref) + ' '+ '+' * val)
659			elif stattype == 'd': #strref is an already resolved string
660				res.append (strref)
661			elif stattype == 'x':
662				res.append (GemRB.GetString (strref) + ': x' + str (val))
663			else:
664				res.append (GemRB.GetString (strref) + ': ' + str (val) + stattype)
665
666			lines = 1
667		except:
668			if s != None:
669				res.append (won + GemRB.GetString (s) + woff)
670				lines = 0
671			else:
672				if not lines:
673					res.append (str_None)
674				res.append ("")
675				lines = 0
676
677	return "\n".join (res)
678
679def OpenInformationWindow ():
680	global InformationWindow
681
682	if InformationWindow != None:
683		if BiographyWindow: OpenBiographyWindow ()
684
685		if InformationWindow:
686			InformationWindow.Unload ()
687		InformationWindow = None
688
689		return
690
691	InformationWindow = Window = GemRB.LoadWindow (5)
692
693	# Biography
694	Button = Window.GetControl (1)
695	Button.SetText (4247)
696	Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyWindow)
697
698	# Done
699	Button = Window.GetControl (0)
700	Button.SetText (1403)
701	Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenInformationWindow)
702	Button.MakeEscape()
703
704	TotalPartyExp = 0
705	TotalPartyKills = 0
706	for i in range (1, GemRB.GetPartySize() + 1):
707		stat = GemRB.GetPCStats(i)
708		TotalPartyExp = TotalPartyExp + stat['KillsTotalXP']
709		TotalPartyKills = TotalPartyKills + stat['KillsTotalCount']
710
711	# These are used to get the stats
712	pc = GemRB.GameGetSelectedPCSingle ()
713	stat = GemRB.GetPCStats (pc)
714
715	Label = Window.GetControl (0x10000001)
716	Label.SetText (GemRB.GetPlayerName (pc, 1))
717
718	# class
719	ClassTitle = GUICommon.GetActorClassTitle (pc)
720	Label = Window.GetControl (0x1000000A)
721	Label.SetText (ClassTitle)
722
723	Label = Window.GetControl (0x10000002)
724	if stat['BestKilledName'] == -1:
725		Label.SetText (GemRB.GetString (41275))
726	else:
727		Label.SetText (GemRB.GetString (stat['BestKilledName']))
728
729	Label = Window.GetControl (0x10000003)
730	GUICommon.SetCurrentDateTokens (stat, True)
731	Label.SetText (41277)
732
733	Label = Window.GetControl (0x10000004)
734	Label.SetText (stat['FavouriteSpell'])
735
736	Label = Window.GetControl (0x10000005)
737	Label.SetText (stat['FavouriteWeapon'])
738
739	Label = Window.GetControl (0x10000006)
740	if TotalPartyExp != 0:
741		PartyExp = int ((stat['KillsTotalXP'] * 100) / TotalPartyExp)
742		Label.SetText (str (PartyExp) + '%')
743	else:
744		Label.SetText ("0%")
745
746	Label = Window.GetControl (0x10000007)
747	if TotalPartyKills != 0:
748		PartyKills = int ((stat['KillsTotalCount'] * 100) / TotalPartyKills)
749		Label.SetText (str (PartyKills) + '%')
750	else:
751		Label.SetText ("0%")
752
753	Label = Window.GetControl (0x10000008)
754	Label.SetText (str (stat['KillsTotalXP']))
755
756	Label = Window.GetControl (0x10000009)
757	Label.SetText (str (stat['KillsTotalCount']))
758
759	White = {'r' : 255, 'g' : 255, 'b' : 255}
760	Label = Window.GetControl (0x1000000B)
761	Label.SetTextColor (White)
762
763	Label = Window.GetControl (0x1000000C)
764	Label.SetTextColor (White)
765
766	Label = Window.GetControl (0x1000000D)
767	Label.SetTextColor (White)
768
769	Label = Window.GetControl (0x1000000E)
770	Label.SetTextColor (White)
771
772	Label = Window.GetControl (0x1000000F)
773	Label.SetTextColor (White)
774
775	Label = Window.GetControl (0x10000010)
776	Label.SetTextColor (White)
777
778	Label = Window.GetControl (0x10000011)
779	Label.SetTextColor (White)
780
781	Label = Window.GetControl (0x10000012)
782	Label.SetTextColor (White)
783
784	Window.ShowModal (MODAL_SHADOW_GRAY)
785
786
787def OpenBiographyWindow ():
788	global BiographyWindow
789
790	if BiographyWindow != None:
791		if BiographyWindow:
792			BiographyWindow.Unload ()
793		BiographyWindow = None
794
795		InformationWindow.ShowModal (MODAL_SHADOW_GRAY)
796		return
797
798	BiographyWindow = Window = GemRB.LoadWindow (12)
799
800	# These are used to get the bio
801	pc = GemRB.GameGetSelectedPCSingle ()
802
803	BioTable = GemRB.LoadTable ("bios")
804	Specific = GemRB.GetPlayerStat (pc, IE_SPECIFIC)
805	BioText = int (BioTable.GetValue (BioTable.GetRowName (Specific), 'BIO'))
806
807	TextArea = Window.GetControl (0)
808	TextArea.SetText (BioText)
809
810
811	# Done
812	Button = Window.GetControl (2)
813	Button.SetText (1403)
814	Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, OpenBiographyWindow)
815	Button.MakeEscape()
816
817	Window.ShowModal (MODAL_SHADOW_GRAY)
818
819
820def AcceptLevelUp():
821	#do level up
822	pc = GemRB.GameGetSelectedPCSingle ()
823	GemRB.SetPlayerStat (pc, IE_SAVEVSDEATH, SavThrows[0])
824	GemRB.SetPlayerStat (pc, IE_SAVEVSWANDS, SavThrows[1])
825	GemRB.SetPlayerStat (pc, IE_SAVEVSPOLY, SavThrows[2])
826	GemRB.SetPlayerStat (pc, IE_SAVEVSBREATH, SavThrows[3])
827	GemRB.SetPlayerStat (pc, IE_SAVEVSSPELL, SavThrows[4])
828	oldhp = GemRB.GetPlayerStat (pc, IE_MAXHITPOINTS, 1)
829	GemRB.SetPlayerStat (pc, IE_MAXHITPOINTS, HPGained+oldhp)
830	oldhp = GemRB.GetPlayerStat (pc, IE_HITPOINTS, 1)
831	GemRB.SetPlayerStat (pc, IE_HITPOINTS, HPGained+oldhp)
832
833	# Weapon Proficiencies
834	if WeapProfType != -1:
835		# Companion NPC's get points added directly to their chosen weapon
836		GemRB.SetPlayerStat (pc, IE_PROFICIENCYBASTARDSWORD+WeapProfType, CurrWeapProf + WeapProfGained)
837	else:
838		# TNO has points added to the "Unused Slots" dummy proficiency
839		freeSlots = GemRB.GetPlayerStat(pc, IE_FREESLOTS)
840		GemRB.SetPlayerStat (pc, IE_FREESLOTS, freeSlots + WeapProfGained)
841
842	SwitcherClass = GUICommon.NamelessOneClass(pc)
843	if SwitcherClass:
844		# Handle saving of TNO class level in the correct CRE stat
845		Levels = { "FIGHTER" : GemRB.GetPlayerStat (pc, IE_LEVEL) , "MAGE": GemRB.GetPlayerStat (pc, IE_LEVEL2), "THIEF": GemRB.GetPlayerStat (pc, IE_LEVEL3) }
846		LevelStats = { "FIGHTER" : IE_LEVEL , "MAGE": IE_LEVEL2, "THIEF": IE_LEVEL3 }
847		GemRB.SetPlayerStat (pc, LevelStats[SwitcherClass], Levels[SwitcherClass]+NumOfPrimLevUp)
848	else:
849		GemRB.SetPlayerStat (pc, IE_LEVEL, GemRB.GetPlayerStat (pc, IE_LEVEL)+NumOfPrimLevUp)
850		if avatar_header['SecoLevel'] != 0:
851			GemRB.SetPlayerStat (pc, IE_LEVEL2, GemRB.GetPlayerStat (pc, IE_LEVEL2)+NumOfSecoLevUp)
852
853	LUSkillsSelection.SkillsSave (pc)
854
855	# Spells
856	LevelUp.pc = pc
857	LevelUp.Classes = Classes
858	LevelUp.NumClasses = NumClasses
859	# (we need to override the globals this function uses there since they wouldn't have been set)
860	LevelUp.SaveNewSpells()
861
862	LevelUpWindow.Close()
863	NewLife.OpenLUStatsWindow()
864
865def RedrawSkills():
866	DoneButton = LevelUpWindow.GetControl(0)
867
868	if GemRB.GetVar ("SkillPointsLeft") == 0:
869		DoneButton.SetState(IE_GUI_BUTTON_ENABLED)
870	else:
871		DoneButton.SetState(IE_GUI_BUTTON_DISABLED)
872	return
873
874def OpenLevelUpWindow ():
875	global LevelUpWindow
876	global SavThrows
877	global HPGained
878	global WeapProfType, CurrWeapProf, WeapProfGained
879	global NumOfPrimLevUp, NumOfSecoLevUp
880
881	global LevelDiff, Level, Classes, NumClasses
882
883	LevelUpWindow = Window = GemRB.LoadWindow (4, "GUIREC") # since we get called from NewLife
884
885	# Accept
886	Button = Window.GetControl (0)
887	Button.SetText (4192)
888	Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, AcceptLevelUp)
889
890	pc = GemRB.GameGetSelectedPCSingle ()
891
892	# These are used to identify Nameless One
893	BioTable = GemRB.LoadTable ("bios")
894	Specific = GemRB.GetPlayerStat (pc, IE_SPECIFIC)
895	AvatarName = BioTable.GetRowName (Specific)
896
897	# These will be used for saving throws
898	SavThrUpdated = False
899	SavThrows = [0,0,0,0,0]
900	SavThrows[0] = GemRB.GetPlayerStat (pc, IE_SAVEVSDEATH)
901	SavThrows[1] = GemRB.GetPlayerStat (pc, IE_SAVEVSWANDS)
902	SavThrows[2] = GemRB.GetPlayerStat (pc, IE_SAVEVSPOLY)
903	SavThrows[3] = GemRB.GetPlayerStat (pc, IE_SAVEVSBREATH)
904	SavThrows[4] = GemRB.GetPlayerStat (pc, IE_SAVEVSSPELL)
905
906	HPGained = 0
907	ConHPBon = 0
908	Thac0Updated = False
909	Thac0 = 0
910	WeapProfGained = 0
911
912	WeapProfType = -1
913	CurrWeapProf = 0
914
915	# Count the number of existing weapon procifiencies
916	if GUICommon.IsNamelessOne(pc):
917		# TNO: Count the total amount of unassigned proficiencies
918		CurrWeapProf = GemRB.GetPlayerStat(pc, IE_FREESLOTS)
919	else:
920		# Scan the weapprof table for the characters favoured weapon proficiency (WeapProfType)
921		# This does not apply to Nameless since he uses unused slots system
922		for i in range (6):
923			WeapProfName = CommonTables.WeapProfs.GetRowName (i)
924			value = CommonTables.WeapProfs.GetValue (WeapProfName,AvatarName)
925			if value == 1:
926				WeapProfType = i
927				break
928
929	for i in range (6):
930		CurrWeapProf += GemRB.GetPlayerStat (pc, IE_PROFICIENCYBASTARDSWORD + i)
931
932	# What is the avatar's class (Which we can use to lookup XP)
933	Class = GUICommon.GetClassRowName (pc)
934
935	# name
936	Label = Window.GetControl (0x10000000)
937	Label.SetText (GemRB.GetPlayerName (pc, 1))
938
939	# class
940	Label = Window.GetControl (0x10000001)
941	Label.SetText (CommonTables.Classes.GetValue (Class, "NAME_REF"))
942
943	# Armor Class
944	Label = Window.GetControl (0x10000023)
945	Label.SetText (str (GemRB.GetPlayerStat (pc, IE_ARMORCLASS)))
946
947	# our multiclass variables
948	IsMulti = GUICommon.IsMultiClassed (pc, 1)
949	Classes = [IsMulti[1], IsMulti[2], IsMulti[3]]
950	NumClasses = IsMulti[0] # 2 or 3 if IsMulti; 0 otherwise
951	IsMulti = NumClasses > 1
952
953	if not IsMulti:
954		NumClasses = 1
955		Classes = [GemRB.GetPlayerStat (pc, IE_CLASS)]
956
957	if GUICommon.IsNamelessOne(pc):
958		# Override the multiclass info for TNO
959		IsMulti = 1
960		NumClasses = 3
961		# Fighter, Mage, Thief ID
962		Classes = [2, 1, 4]
963
964	Level = LUCommon.GetNextLevels(pc, Classes)
965	LevelDiff = LUCommon.GetLevelDiff(pc, Level)
966
967	# calculate the new spells (results are stored in global variables in LevelUp)
968	LevelUp.GetNewSpells(pc, Classes, Level, LevelDiff)
969
970	# Thief Skills
971	Level1 = []
972	for i in range (len (Level)):
973		Level1.append (Level[i]-LevelDiff[i])
974	LUSkillsSelection.SetupSkillsWindow (pc, LUSkillsSelection.LUSKILLS_TYPE_LEVELUP, LevelUpWindow, RedrawSkills, Level1, Level, 0, False)
975	RedrawSkills()
976
977	# Is avatar multi-class?
978	if avatar_header['SecoLevel'] == 0:
979		# avatar is single class
980		# What will be avatar's next level?
981		NextLevel = avatar_header['PrimLevel'] + 1
982		while avatar_header['XP'] >= GetNextLevelExp (NextLevel, Class):
983			NextLevel = NextLevel + 1
984		NumOfPrimLevUp = NextLevel - avatar_header['PrimLevel'] # How many levels did we go up?
985
986		#How many weapon procifiencies we get
987		for i in range (NumOfPrimLevUp):
988			WeapProfGained += GainedWeapProfs (pc, CurrWeapProf + WeapProfGained, avatar_header['PrimLevel'] + i, AvatarName)
989
990		# Hit Points Gained and Hit Points from Constitution Bonus
991		for i in range (NumOfPrimLevUp):
992			HPGained = HPGained + GetSingleClassHP (Class, avatar_header['PrimLevel'])
993		if Class == "FIGHTER":
994			CONType = 0
995		else:
996			CONType = 1
997		ConHPBon = GetConHPBonus (pc, NumOfPrimLevUp, 0, CONType)
998
999		# Thac0
1000		Thac0 = GetThac0 (Class, NextLevel)
1001		# Is the new thac0 better than old? (The smaller, the better)
1002		if Thac0 < GemRB.GetPlayerStat (pc, IE_TOHIT, 1):
1003			Thac0Updated = True
1004
1005		# Saving Throws
1006		if GUICommon.IsNamelessOne(pc):
1007			# Nameless One always uses the best possible save from each class
1008			FigSavThrTable = GemRB.LoadTable ("SAVEWAR")
1009			MagSavThrTable = GemRB.LoadTable ("SAVEWIZ")
1010			ThiSavThrTable = GemRB.LoadTable ("SAVEROG")
1011
1012			FighterLevel = GemRB.GetPlayerStat (pc, IE_LEVEL) - 1
1013			MageLevel = GemRB.GetPlayerStat (pc, IE_LEVEL2) - 1
1014			ThiefLevel = GemRB.GetPlayerStat (pc, IE_LEVEL3) - 1
1015
1016			# We are leveling up one of those levels. Therefore, one of them has to be updated.
1017			if Class == "FIGHTER":
1018				FighterLevel = NextLevel - 1
1019			elif Class == "MAGE":
1020				MageLevel = NextLevel - 1
1021			else:
1022				ThiefLevel = NextLevel - 1
1023
1024			# Now we need to update the saving throws with the best values from those tables.
1025			# The smaller the number, the better saving throw it is.
1026			# We also need to check if any of the levels are larger than 21, since
1027			# after that point the table runs out, and the throws remain the
1028			# same
1029			if FighterLevel < 21:
1030				for i in range (5):
1031					Throw = FigSavThrTable.GetValue (i, FighterLevel)
1032					if Throw < SavThrows[i]:
1033						SavThrows[i] = Throw
1034						SavThrUpdated = True
1035			if MageLevel < 21:
1036				for i in range (5):
1037					Throw = MagSavThrTable.GetValue (i, MageLevel)
1038					if Throw < SavThrows[i]:
1039						SavThrows[i] = Throw
1040						SavThrUpdated = True
1041			if ThiefLevel < 21:
1042				for i in range (5):
1043					Throw = ThiSavThrTable.GetValue (i, ThiefLevel)
1044					if Throw < SavThrows[i]:
1045						SavThrows[i] = Throw
1046						SavThrUpdated = True
1047		else:
1048			SavThrTable = GemRB.LoadTable (CommonTables.Classes.GetValue (Class, "SAVE"))
1049			# Updating the current saving throws. They are changed only if the
1050			# new ones are better than current. The smaller the number, the better.
1051			# We need to substract one from the NextLevel, so that we get right values.
1052			# We also need to check if NextLevel is larger than 21, since after that point
1053			# the table runs out, and the throws remain the same
1054			if NextLevel < 22:
1055				for i in range (5):
1056					Throw = SavThrTable.GetValue (i, NextLevel-1)
1057					if Throw < SavThrows[i]:
1058						SavThrows[i] = Throw
1059						SavThrUpdated = True
1060
1061
1062
1063	else:
1064		# avatar is multi class
1065		# we have only fighter/X multiclasses, so this
1066		# part is a bit hardcoded
1067		PrimNextLevel = 0
1068		SecoNextLevel = 0
1069		NumOfPrimLevUp = 0
1070		NumOfSecoLevUp = 0
1071
1072		# What will be avatar's next levels?
1073		PrimNextLevel = avatar_header['PrimLevel']
1074		while avatar_header['XP'] >= GetNextLevelExp (PrimNextLevel, "FIGHTER"):
1075			PrimNextLevel = PrimNextLevel + 1
1076		# How many primary levels did we go up?
1077		NumOfPrimLevUp = PrimNextLevel - avatar_header['PrimLevel']
1078
1079		for i in range (NumOfPrimLevUp):
1080			WeapProfGained += GainedWeapProfs (pc, CurrWeapProf + WeapProfGained, avatar_header['PrimLevel'] + i, AvatarName)
1081
1082		# Saving Throws
1083		FigSavThrTable = GemRB.LoadTable ("SAVEWAR")
1084		if PrimNextLevel < 22:
1085			for i in range (5):
1086				Throw = FigSavThrTable.GetValue (i, PrimNextLevel - 1)
1087				if Throw < SavThrows[i]:
1088					SavThrows[i] = Throw
1089					SavThrUpdated = True
1090		# Which multi class is it?
1091		if GemRB.GetPlayerStat (pc, IE_CLASS) == 7:
1092			# avatar is Fighter/Mage (Dak'kon)
1093			Class = "MAGE"
1094			SavThrTable = GemRB.LoadTable ("SAVEWIZ")
1095		else:
1096			# avatar is Fighter/Thief (Annah)
1097			Class = "THIEF"
1098			SavThrTable = GemRB.LoadTable ("SAVEROG")
1099
1100		SecoNextLevel = avatar_header['SecoLevel']
1101		while avatar_header['XP'] >= GetNextLevelExp (SecoNextLevel, Class):
1102			SecoNextLevel = SecoNextLevel + 1
1103		# How many secondary levels did we go up?
1104		NumOfSecoLevUp = SecoNextLevel - avatar_header['SecoLevel']
1105		if SecoNextLevel < 22:
1106			for i in range (5):
1107				Throw = SavThrTable.GetValue (i, SecoNextLevel - 1)
1108				if Throw < SavThrows[i]:
1109					SavThrows[i] = Throw
1110					SavThrUpdated = True
1111
1112		# Hit Points Gained and Hit Points from Constitution Bonus (multiclass)
1113		for i in range (NumOfPrimLevUp):
1114			HPGained = HPGained + GetSingleClassHP ("FIGHTER", avatar_header['PrimLevel'])/2
1115
1116		for i in range (NumOfSecoLevUp):
1117			HPGained = HPGained + GetSingleClassHP (Class, avatar_header['SecoLevel'])/2
1118		ConHPBon = GetConHPBonus (pc, NumOfPrimLevUp, NumOfSecoLevUp, 2)
1119
1120		# Thac0
1121		# Multi class use the primary class level to determine Thac0
1122		Thac0 = GetThac0 (Class, PrimNextLevel)
1123		# Is the new thac0 better than old? (The smaller the better)
1124		if Thac0 < GemRB.GetPlayerStat (pc, IE_TOHIT, 1):
1125			Thac0Updated = True
1126
1127
1128	# Displaying the saving throws
1129	# Death
1130	Label = Window.GetControl (0x10000019)
1131	Label.SetText (str (SavThrows[0]))
1132	# Wand
1133	Label = Window.GetControl (0x1000001B)
1134	Label.SetText (str (SavThrows[1]))
1135	# Polymorph
1136	Label = Window.GetControl (0x1000001D)
1137	Label.SetText (str (SavThrows[2]))
1138	# Breath
1139	Label = Window.GetControl (0x1000001F)
1140	Label.SetText (str (SavThrows[3]))
1141	# Spell
1142	Label = Window.GetControl (0x10000021)
1143	Label.SetText (str (SavThrows[4]))
1144
1145	FinalCurHP = GemRB.GetPlayerStat (pc, IE_HITPOINTS) + HPGained
1146	FinalMaxHP = GemRB.GetPlayerStat (pc, IE_MAXHITPOINTS) + HPGained
1147
1148	# Current HP
1149	Label = Window.GetControl (0x10000025)
1150	Label.SetText (str (FinalCurHP))
1151
1152	# Max HP
1153	Label = Window.GetControl (0x10000027)
1154	Label.SetText (str (FinalMaxHP))
1155
1156	# Displaying level up info
1157	overview = ""
1158	if CurrWeapProf!=-1 and WeapProfGained>0:
1159		overview = overview + GemRB.GetString (38715) + '\n' + '+' + str (WeapProfGained) + '\n'
1160
1161	overview = overview + str (HPGained) + " " + GemRB.GetString (38713) + '\n'
1162	overview = overview + str (ConHPBon) + " " + GemRB.GetString (38727) + '\n'
1163
1164	if SavThrUpdated:
1165		overview = overview + GemRB.GetString (38719) + '\n'
1166	if Thac0Updated:
1167		GemRB.SetPlayerStat (pc, IE_TOHIT, Thac0)
1168		overview = overview + GemRB.GetString (38718) + '\n'
1169
1170	Text = Window.GetControl (3)
1171	Text.SetText (overview)
1172
1173	Window.ShowModal (MODAL_SHADOW_GRAY)
1174
1175def GetSingleClassHP (Class, Level):
1176	HPTable = GemRB.LoadTable (CommonTables.Classes.GetValue (Class, "HP"))
1177
1178	# We need to check if Level is larger than 20, since after that point
1179	# the table runs out, and the formula remain the same.
1180	if Level > 20:
1181		Level = 20
1182
1183	# We need the Level as a string, so that we can use the column names
1184	Level = str (Level)
1185
1186	Sides = HPTable.GetValue (Level, "SIDES")
1187	Rolls = HPTable.GetValue (Level, "ROLLS")
1188	Modif = HPTable.GetValue (Level, "MODIFIER")
1189
1190
1191	return GemRB.Roll (Rolls, Sides, Modif)
1192
1193def GetConHPBonus (pc, numPrimLevels, numSecoLevels, levelUpType):
1194	ConHPBonTable = GemRB.LoadTable ("HPCONBON")
1195
1196	con = str (GemRB.GetPlayerStat (pc, IE_CON))
1197	if levelUpType == 0:
1198		# Pure fighter
1199		return ConHPBonTable.GetValue (con, "WARRIOR") * numPrimLevels
1200	if levelUpType == 1:
1201		# Mage, Priest or Thief
1202		return ConHPBonTable.GetValue (con, "OTHER") * numPrimLevels
1203	return ConHPBonTable.GetValue (con, "WARRIOR") * numPrimLevels / 2 + ConHPBonTable.GetValue (con, "OTHER") * numSecoLevels / 2
1204
1205def GetThac0 (Class, Level):
1206	Thac0Table = GemRB.LoadTable ("THAC0")
1207	# We need to check if Level is larger than 60, since after that point
1208	# the table runs out, and the value remains the same.
1209	if Level > 60:
1210		Level = 60
1211
1212	return Thac0Table.GetValue (Class, str (Level))
1213
1214# each gained level is checked for how many new prof points gained
1215def GainedWeapProfs (pc, currProf, currLevel, AvatarName):
1216
1217	# Actually looking at the next level
1218	nextLevel = currLevel + 1
1219
1220	# The table stops at level 20
1221	if nextLevel < 21:
1222		maxProf = CommonTables.CharProfs.GetValue(str(nextLevel), AvatarName)
1223		return maxProf - currProf
1224
1225	# Nameless continues gaining points forever	at a rate of 1 every 3 levels
1226	elif GUICommon.IsNamelessOne(pc) and (currProf-3) <= (nextLevel / 3):
1227		return 1
1228
1229	return 0
1230
1231###################################################
1232# End of file GUIREC.py
1233