#include once "global.bi"
#include once "iso_plog.bi"
#include once "iso_display.bi"
#include once "types.bi"
#include once "colors.bi"
#include once "decs.bi"
#include once "iso_font.bi"
#include once "crt.bi"

#define WITHINMAP(x, y) ((cast(uinteger, (x)) < (dunw)) and (cast(uinteger, (y)) < (dunh)))

#macro blit_sprite(sheet, index, x, y)
	put buf, ( (x) - sheet->sprite(index).cx, (y) - sheet->sprite(index).cy ), sheet->sprite(index).img, TRANS
#endmacro

dim shared as fb.image ptr buf
dim shared as sheet_t ptr floors, floors2, walls, chars, chars2, items, items2, walls2, curs

sub display_init _
	( _
	)

	dim as string path = "gfx" & PATSEP & "iso" & PATSEP

	buf = imagecreate( VIEW_WIDTH, VIEW_HEIGHT )

	floors  = new sheet_t( path & "jtp_cm07.png",  6,  4, 116, 126 )
	floors2 = new sheet_t( path & "jtp_cm12.png",  6, 11, 116,  53 )
	walls   = new sheet_t( path & "jtp_cmb8.png",  8,  3,  60, 126 )
	walls2  = new sheet_t( path & "walls03a.png", 12,  4,  60, 126 )
	chars   = new sheet_t( path & "jtp_mon7.png",  6,  4, 116, 126 )
	chars2  = new sheet_t( path & "jtp_mon6.png",  6,  4, 116, 126 )
	items   = new sheet_t( path & "jtp_obj1.png",  8,  5,  96, 102 )
	items2  = new sheet_t( path & "jtp_obj2.png",  8,  5,  96, 102 )
	curs    = new sheet_t( path & "jtp_curs.png",  1,  1,  54,  29 )

	font_init( )

end sub

sub display_deinit _
	( _
	)

	font_deinit( )

	delete floors
	delete floors2
	delete walls
	delete walls2
	delete chars
	delete chars2
	delete items
	delete items2
	delete curs

	imagedestroy( buf )

end sub

sub cell_coord_to_display_coord _
	( _
		byval center_cell_x as integer, _
		byval center_cell_y as integer, _
		byval cell_x as integer, _
		byval cell_y as integer, _
		byref draw_x as integer, _
		byref draw_y as integer _
	)

	' Offset from center to target tile
	dim as integer dx = (cell_x - center_cell_x)
	dim as integer dy = (cell_y - center_cell_y)

	' Real draw pos
	draw_x = (VIEW_WIDTH \ 2) + (((dy * TILE_WIDTH) + (dx * TILE_WIDTH)) \ 2)
	draw_y = (VIEW_HEIGHT \ 2) + (((dy * TILE_HEIGHT) - (dx * TILE_HEIGHT)) \ 2)

end sub

sub drawhealthbar2 _
	( _
		byval hx  as integer, _
		byval hy  as integer, _
		byval pct as single _
	)

	dim as uinteger hcolor = any

	if levels.showhealth = 0 then exit sub

	' postion above head, already in center at bottom...
	hx -= 32
	hy -= 100

	hcolor = fbRed
	if pct > .74 then
		hcolor = fbGreen
	elseif pct > .5 then
		hcolor = fbYellow
	end if

	line buf, (hx, hy - 4) - (hx + 64, hy), &hffffff, b
	line buf, (hx + 1, hy - 3) - ((hx + (64 * pct)) - 1, hy - 1), hcolor, bf

end sub

sub DrawCell(cell_x as integer, cell_y as integer, draw_x as integer, draw_y as integer)

	'mask out of range tiles
	'If    CalcDist(player.pcoord.x, cell_x, player.pcoord.y, cell_y) > currvision _
	'Or PlayerCanSee(cell_x, cell_y) = False Then
		'Get tmap,(128, 0) - (143, 15), tp
		' todo replace me  (x * 16, y * 16), tp, Trans
	'End If

	if not WITHINMAP(cell_x, cell_y) then exit sub

	' Draw front walls
	select case as const levels.map(cell_x, cell_y)
		case wall, secretwall
			if WITHINMAP(cell_x + 1, cell_y) then
				If levels.isseen(cell_x + 1, cell_y) = True Then
					select case as const levels.map(cell_x + 1, cell_y)
						case mfloor, doorew, doorns, dooropew, dooropns, mstart, mend, water
							If levels.tmaptype = cavern Then
								blit_sprite( walls2, 1, draw_x, draw_y )
							ElseIf levels.tmaptype = dungeon Then
								If levels.mapscheme Then
									blit_sprite( walls2, 25, draw_x, draw_y )
								Else
									blit_sprite( walls, 1, draw_x, draw_y )
								End If
							End If
					end select
				end if
			end if
			if WITHINMAP(cell_x, cell_y - 1) then
				If levels.isseen(cell_x, cell_y - 1) = True Then
					select case as const levels.map(cell_x, cell_y - 1)
						case mfloor, doorew, doorns, dooropew, dooropns, mstart, mend, water
							If levels.tmaptype = cavern Then
								blit_sprite( walls2, 0, draw_x, draw_y )
							ElseIf levels.tmaptype = dungeon Then
								If levels.mapscheme Then
									blit_sprite( walls2, 24, draw_x, draw_y )
								Else
									blit_sprite( walls, 0, draw_x, draw_y )
								End If
							End If
					end select
				end if
			end if
	end select

	If levels.isseen(cell_x, cell_y) = True Then
		' Draw floor tiles
		select case levels.map(cell_x, cell_y)
			case mfloor
				If levels.tmaptype = cavern Then
					blit_sprite( floors, 16, draw_x, draw_y )
				ElseIf levels.tmaptype = dungeon Then
					If levels.mapscheme Then
						blit_sprite( floors, 16, draw_x, draw_y )
					Else
						blit_sprite( floors, 16, draw_x, draw_y )
					End If
				End If
			case water
				blit_sprite( floors2, 21, draw_x, draw_y )
			case wall, secretwall
				' Draw default '?' tile for floor of wall
				blit_sprite( floors, 21, draw_x, draw_y )
			case doorew
				blit_sprite( floors, 2, draw_x, draw_y )
			case doorns
				blit_sprite( floors, 1, draw_x, draw_y )
			case dooropew
				If levels.mapscheme Then
					blit_sprite( floors, 3, draw_x, draw_y )
				Else 
					blit_sprite( floors, 3, draw_x, draw_y )
				End If
			case dooropns
				If levels.mapscheme Then
					blit_sprite( floors, 4, draw_x, draw_y )
				Else
					blit_sprite( floors, 4, draw_x, draw_y )
				End If
			case mstart
				blit_sprite( floors, 9, draw_x, draw_y )
			case mend
				blit_sprite( floors, 10, draw_x, draw_y )
		End select

		''' put a trap if found
		If levels.traps(cell_x, cell_y).istrap And _
		levels.traps(cell_x, cell_y).isseen Then
			If levels.traps(cell_x, cell_y).ttype = 1 Then
				blit_sprite( floors, 5, draw_x, draw_y )
			Else
				blit_sprite( floors, 5, draw_x, draw_y )
			End If
			
		End If

		''' put any items
		If levels.item(cell_x, cell_y).typeid <> 0 Then 
			If PlayerCanSee(cell_x, cell_y) Then
				If levels.item(cell_x, cell_y).typeid = rings Then
					blit_sprite( items, 22, draw_x, draw_y )
				ElseIf levels.item(cell_x, cell_y).typeid = wands Then
					blit_sprite( items, 20, draw_x, draw_y )
				ElseIf levels.item(cell_x, cell_y).typeid = necklaces Then
					blit_sprite( items, 14, draw_x, draw_y )
				ElseIf levels.item(cell_x, cell_y).typeid = scrolls Then
					blit_sprite( items, 19, draw_x, draw_y )
				ElseIf levels.item(cell_x, cell_y).typeid = armors Then
					blit_sprite( items, 25, draw_x, draw_y )
				ElseIf levels.item(cell_x, cell_y).typeid = shields Then
					blit_sprite( items, 13, draw_x, draw_y )
				Else
					Select Case GetItemID(levels.item(cell_x, cell_y))
						Case scoins, sbagocoins
							blit_sprite( items, 10, draw_x, draw_y )
						Case lantern
							blit_sprite( items, 30, draw_x, draw_y )
						Case shortbow, longbow, bonebow, adaminebow
							blit_sprite( items, 6, draw_x, draw_y )
						Case broadsword, longsword, greatsword, odinsword, smallsword, shortsword, scimitar, katana, claymore, hellguard
							blit_sprite( items, 21, draw_x, draw_y )
						Case redpotion, yellowpotion, greenpotion, bluepotion, magentapotion, cyanpotion, whitepotion, blackpotion
							blit_sprite( items, 18, draw_x, draw_y )
						Case dagger, longknife, rapier
							blit_sprite( items, 15, draw_x, draw_y )
						Case lightcrossbow, heavycrossbow, barrelcrossbow
							blit_sprite( items2, 24, draw_x, draw_y )
						Case bullwhip
							blit_sprite( items2, 11, draw_x, draw_y )
						Case smeat
							blit_sprite( items2, 33, draw_x, draw_y )
						Case sbread
							blit_sprite( items2, 28, draw_x, draw_y )
						Case warhammer
							blit_sprite( items, 28, draw_x, draw_y )
						Case club, warclub, cudgel
							blit_sprite( items, 38, draw_x, draw_y )
						Case redorb, blueorb, greenorb, yelloworb, whiteorb
							blit_sprite( items2, 16, draw_x, draw_y )
						Case arrows, bolts
							blit_sprite( items2, 39, draw_x, draw_y )
						Case handaxe, battleaxe, poleaxe, gothicbattleaxe, waraxe
							blit_sprite( items, 29, draw_x, draw_y )
						Case torch
							blit_sprite( items, 30, draw_x, draw_y )
						Case sbottle
							blit_sprite( items, 18, draw_x, draw_y )
						Case trident
							blit_sprite( items, 35, draw_x, draw_y )
						Case pebbles
							blit_sprite( items2, 35, draw_x, draw_y )
						Case smallmace, battlemace, spikedmace, doubleballmace, ballflail, spikedflail, battleflail, bishopsflail
							blit_sprite( items2, 12, draw_x, draw_y )
						Case quarterstaff, longstaff, polearm
							blit_sprite( items2, 27, draw_x, draw_y )
						Case lightspear, heavyspear, glaive, halberd, maul
							blit_sprite( items, 17, draw_x, draw_y )
						Case morningstar
							blit_sprite( items2, 34, draw_x, draw_y )
						'Case crown
						'Case sling
						case else
							blit_sprite( items, 0, draw_x, draw_y )
					End Select
				End If
			Else
				blit_sprite( items, 0, draw_x, draw_y )
			End If
		End If

		''Put any monsters
		If IsMonsterLoc(cell_x, cell_y) And PlayerCanSee(cell_x, cell_y) Then
			Select Case levels.monster(GetMonsterIndex(cell_x, cell_y)).id
				Case giantbat
					blit_sprite( chars, 6, draw_x, draw_y )
				Case dragon
					blit_sprite( chars, 20, draw_x, draw_y )
				Case jadegolem, golem, flamegolem, rockgolem
					blit_sprite( chars2, 22, draw_x, draw_y )
				Case skeleton, lich
					blit_sprite( chars2, 5, draw_x, draw_y )
				Case zombie, vampire, werebear
					blit_sprite( chars2, 21, draw_x, draw_y )
				Case elemental, darkangel, demonspawn, flameangel
					blit_sprite( chars2, 3, draw_x, draw_y )
				Case giant, ogre
					blit_sprite( chars2, 12, draw_x, draw_y )
				Case rovingjelly, phantomfungus
					blit_sprite( chars2, 4, draw_x, draw_y )
				Case pulsingeye
					blit_sprite( chars2, 6, draw_x, draw_y )
				Case troll
					blit_sprite( chars2, 11, draw_x, draw_y )
				Case kobold, orc, nazgul
					blit_sprite( chars2, 1, draw_x, draw_y )
				Case rogue
					blit_sprite( chars, 2, draw_x, draw_y )
				Case mage
					blit_sprite( chars, 3, draw_x, draw_y )
				Case hobgoblin
					blit_sprite( chars2, 2, draw_x, draw_y )
				Case elfwarrior
					blit_sprite( chars2, 16, draw_x, draw_y )
				Case wraith
					blit_sprite( chars2, 18, draw_x, draw_y )
				Case giantcentipede, gianttarantula, giantbeetle, giantscorpion
					blit_sprite( chars2, 7, draw_x, draw_y )
				Case wisp, harpy, incubus
					blit_sprite( chars2, 13, draw_x, draw_y )
				Case wombat
					blit_sprite( chars, 6, draw_x, draw_y )
/'
				Case kraken
				Case lamia
				Case manticore
				Case naga
				Case quorn
				Case uruk
				Case xerth
				Case yeek
				Case interloper
				Case twinhead
				Case shurik
				Case varghoul
				Case xorn
				Case yekki
				Case griffon
'/
			case else
				blit_sprite( chars, 1, draw_x, draw_y )
			End Select
			'draw monster health bar
			dim as integer midx = GetMonsterIndex(cell_x, cell_y)
			dim as double pct = levels.monster(midx).attr.currhp / levels.monster(midx).attr.maxhp
			If pct > 0 Then
				DrawHealthBar2 draw_x, draw_y, pct
			End If
		End If
	Else
		' Draw default '?' tile for floor
		blit_sprite( floors, 21, draw_x, draw_y )
	End If

	' Draw the player
	if (cell_x = player.pcoord.x) and (cell_y = player.pcoord.y) then
		blit_sprite( chars, 0, draw_x, draw_y )
		dim as double pct = player.attr.currhp / player.attr.maxhp
		DrawHealthBar2 draw_x, draw_y, pct
	end if

	' Draw back walls
	select case as const levels.map(cell_x, cell_y)
		case wall, secretwall
			if WITHINMAP(cell_x, cell_y + 1) then
				If levels.isseen(cell_x, cell_y + 1) = True Then
					select case levels.map(cell_x, cell_y + 1)
						case mfloor, doorew, doorns, dooropew, dooropns, mstart, mend, water
							If levels.tmaptype = cavern Then
								blit_sprite( walls2, 3, draw_x, draw_y )
							ElseIf levels.tmaptype = dungeon Then
								If levels.mapscheme Then
									blit_sprite( walls2, 27, draw_x, draw_y )
								Else
									blit_sprite( walls, 3, draw_x, draw_y )
								End If
							End If
					end select
				end if
			end if
			if WITHINMAP(cell_x - 1, cell_y) then
				If levels.isseen(cell_x - 1, cell_y) = True Then
					select case levels.map(cell_x - 1, cell_y)
						case mfloor, doorew, doorns, dooropew, dooropns, mstart, mend, water
							If levels.tmaptype = cavern Then
								blit_sprite( walls2, 2, draw_x, draw_y )
							ElseIf levels.tmaptype = dungeon Then
								If levels.mapscheme Then
									blit_sprite( walls2, 26, draw_x, draw_y )
								Else
									blit_sprite( walls, 2, draw_x, draw_y )
								End If
							End If
					end select
				end if
			end if
	end select

end sub

Sub DrawMapInner

	dim as integer disp_w = 9'vw \ 2 ' 6
	dim as integer disp_h = 9'vh \ 2 ' 6

	line buf, (0, 0)-(VIEW_WIDTH - 1, VIEW_HEIGHT - 1), &H000000, BF

	For y as integer = 0 To disp_h * 2
		For x as integer = disp_w * 2 To 0 step -1
			dim as integer cell_x = player.pcoord.x + x - disp_w
			dim as integer cell_y = player.pcoord.y + y - disp_h
			dim as integer draw_x = any
			dim as integer draw_y = any

			cell_coord_to_display_coord( player.pcoord.x, player.pcoord.y, cell_x, cell_y, draw_x, draw_y )

			DrawCell( cell_x, cell_y, draw_x, draw_y )
		Next
	Next

end sub

Sub DrawBox2(bcolor As Integer, row As Integer, col As Integer, bwidth As Integer, bheight As Integer)
    Dim i As Integer
    
    Color bcolor, fbBlack
    Locate row, col
    'print the top row
    Print Chr$(201);
    Print String$(col + bwidth - 2, Chr$(205));
    Print Chr$(187)
    'print the sides
    For i = row + 1 To row + bheight - 1
        Locate i, col
        Print Chr$(186);
        Print String$(col + bwidth - 2, Chr$(32));
        Print Chr$(186)
    Next i
    'print bottom row
    Locate row + bheight - 1, col
    Print Chr$(200);
    Print String$(col + bwidth - 2, Chr$(205));
    Print Chr$(188)
End Sub

'print a message to the screen
Sub PrintMessage(mess As String = "")
    Dim tmpmess As String
    Dim i As Integer
    Dim messlen As Integer = 0
    Dim As Integer row, col
    Dim bwidth As Integer = 55
    Dim bheight As Integer = (UBound(messages) * 2) + 2 ' 16 high...
    'make sure we have a message
    
    tmpmess = Trim$(mess)
    If Len(tmpmess) > 0 Then
        If Len(tmpmess) > bwidth - 2 Then
            tmpmess = Mid$(tmpmess, 1, bwidth - 2)
        End If
        If tmpmess <> messages(1) Then
            'move all messages down one slot
            For i = UBound(messages) To 2 Step -1
                messages(i) = messages(i - 1)
            Next
            messages(1) = tmpmess
        End If
    End If
    'try top right
    row = 75 - bheight
    col = 2

	ScreenSet 1, 0

    'draw the box
    DrawBox2 fbYellow, row, col, bwidth, bheight

	dim as integer x, y

	x = col * 8
	y = (row * 8) - 1

	font_print( x, y, messages(1), &HFFFF00, 18 )
	For i = 2 To UBound(messages)
		y += 16
		font_print( x, y, messages(i), &HFFFFFF, 18 )
	Next i

	ScreenCopy
	ScreenSet 0


end sub

'print a message to the screen
Sub PrintMessageNoFlip(mess As String = "")
    Dim tmpmess As String
    Dim i As Integer
    Dim messlen As Integer = 0
    Dim As Integer row, col
    Dim bwidth As Integer = 55
    Dim bheight As Integer = (UBound(messages) * 2) + 2 ' 16 high...
    'make sure we have a message
    
    tmpmess = Trim$(mess)
    If Len(tmpmess) > 0 Then
        If Len(tmpmess) > bwidth - 2 Then
            tmpmess = Mid$(tmpmess, 1, bwidth - 2)
        End If
        If tmpmess <> messages(1) Then
            'move all messages down one slot
            For i = UBound(messages) To 2 Step -1
                messages(i) = messages(i - 1)
            Next
            messages(1) = tmpmess
        End If
    End If
    'try top right
    row = 75 - bheight
    col = 2

    'draw the box
    DrawBox2 fbYellow, row, col, bwidth, bheight

	dim as integer x, y

	x = col * 8
	y = (row * 8) - 1

	font_print( x, y, messages(1), &HFFFF00, 18 )
	For i = 2 To UBound(messages)
		y += 16
		font_print( x, y, messages(i), &HFFFFFF, 18 )
	Next i

end sub

'draws the current status
sub DrawStats
	dim as string temp

	temp = ""
	temp += trim( player.pname ) & " "
	temp += "| HP: " & player.attr.currhp & "/" & player.attr.maxhp & " "
	temp += "| Exp: " & player.attr.expr

	font_print( 8, 8, temp, &HFFFFFF, 18 )

	temp = ""
	if player.righthand.typeid <> 0 then
		temp += GetInventoryItemDesc(player.righthand) & " "
	end if
	if player.lefthand.typeid <> 0 then
		temp += GetInventoryItemDesc(player.lefthand) & " "
	end if
	if player.parmor.typeid <> 0 then
		temp += GetInventoryItemDesc(player.parmor)
	end if

	font_print( 8, 24, temp, &HFFFFFF, 18 )

	font_print( 8, 40, "Dungeon Level: " & levels.currlevel, &HFFFFFF, 18 )

	temp = ""
	if levels.isdark then temp += "(Dark) "
	If levels.map(player.pcoord.x, player.pcoord.y) = water Then temp += "(Water) "
	If player.isdodging Then temp += "(Dodging) "
	If cheater Then temp += "(Cheat) "
	If easteregg Then temp += "(Egg) "
	
	font_print( 8, 56, temp, &HFFFFFF, 18 )

	PrintMessageNoFlip
End Sub

Sub DrawBlock2(x As Integer, y As Integer, fcolor As Integer, size As Integer)
    Line (x - size, y - size) - (x + size, y + size), fcolor, BF
End Sub

Sub DrawMiniMapItem2(offset As Integer, i As Integer, j As Integer, x As Integer, y As Integer, size As Integer)
    If levels.visited(i, j) = True Then        
        If levels.map(i, j) = wall Or levels.map(i, j) = secretwall Then
            DrawBlock2 x + (i * offset), y + (j * offset), fbWhite, size
        ElseIf levels.map(i, j) = doorns Or levels.map(i, j) = doorew Then
            DrawBlock2 x + (i * offset), y + (j * offset), fbTan, size
        ElseIf levels.map(i, j) = dooropns Or levels.map(i, j) = dooropew Then
            DrawBlock2 x + (i * offset), y + (j * offset), fbWarmGrey, size
        ElseIf levels.map(i, j) = water Then
            DrawBlock2 x + (i * offset), y + (j * offset), fbBlue, size
        ElseIf levels.map(i, j) = mfloor Then
            DrawBlock2 x + (i * offset), y + (j * offset), fbWarmGrey, size
        ElseIf levels.map(i, j) = mend Or levels.map(i, j) = mstart Then
            DrawBlock2 x + (i * offset), y + (j * offset), fbOrange, size
        End If
        If levels.item(i, j).typeid > 0 Then
            DrawBlock2 x + (i * offset), y + (j * offset), fbYellow, size
        End If
    Else
        DrawBlock2 x + (i * offset), y + (j * offset), fbBlack, size
    End If
    'Draw the player
    DrawBlock2 x + (player.pcoord.x * offset), y + (player.pcoord.y * offset), fbGreen, size
End Sub

Sub DrawMiniMap
    Dim x As Integer = 620
    Dim y As Integer = 420
    Dim size As Integer = 2
    Dim offset As Integer = size 
    
    Dim As Integer i, j
    
    Line (x - 3, y - 3) - (x + (dunw * size) + 2, y + (dunh * size) + 2), fbMarsOrange, BF
    For i = 0 To dunw - 1
        For j = 0 To dunh - 1
            DrawMiniMapItem2 offset, i, j, x, y, size
        Next
    Next
End Sub

Sub DrawMap
	Dim tile As Integer
	Dim As Integer currvision
	
	ScreenSet 1, 0
	'get currvision range
	currvision = GetCurrvision

	DrawMapInner

	put(0, 0), buf, PSET

	DrawStats
	DrawMiniMap
	tile = CheckMapItem
	ScreenCopy
	ScreenSet 0
	PlayMapSound tile
End Sub

Sub DrawMapNoFlip

	DrawMapInner

End Sub

Sub AnimateProjectile(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer)
	'fprintf(stderr, !"%s\n", "x1 " & x1 & " | y1 " & y1 & " | x2 " & x2 & " | y2 " & y2 )

	dim as integer d1x, d1y, d2x, d2y

	cell_coord_to_display_coord( player.pcoord.x, player.pcoord.y, x1, y1, d1x, d1y )
	cell_coord_to_display_coord( player.pcoord.x, player.pcoord.y, x2, y2, d2x, d2y )

	' player midsection?
	d1y -= 48
	d2y -= 48

	dim as double angle = atan2( d2y - d1y, d2x - d1x )
	dim as double dist = sqr( (abs( d2y - d1y ) ^ 2) + (abs( d2x - d1x ) ^ 2) )
	'fprintf(stderr, !"%s\n", "x1 " & d1x & " | y1 " & d1y & " | x2 " & d2x & " | y2 " & d2y )

	dim as double t = timer( )

	DrawMapNoFlip

	while dist >= 0
		ScreenSet 1, 0
			put (0, 0), buf, PSET

			circle (d1x, d1y), 5, &H00AAFF, , , , F
			circle (d1x, d1y), 4, &H0088FF, , , , F
			circle (d1x, d1y), 3, &H0066FF, , , , F
			circle (d1x, d1y), 2, &H0044FF, , , , F
			circle (d1x, d1y), 1, &H0022FF, , , , F
	
			DrawStats
			DrawMiniMap
		ScreenCopy
		ScreenSet 0

		sleep 1, 1

		t = (timer( ) - t)

		'plog( "" & int(t * 1000) )

		if t <= 0 then t = 1

		d1x += cos( angle ) * (t * 1000)
		d1y += sin( angle ) * (t * 1000)
		dist -= (t * 1000)

		t = timer( )
	wend

End Sub

Function GetTargetCoord() As mcoord

	ScreenSet 1, 0

	dim as mcoord result
	dim as string skey

	dim as integer draw_x, draw_y

	result.x = player.pcoord.x
	result.y = player.pcoord.y

	cell_coord_to_display_coord( player.pcoord.x, player.pcoord.y, result.x, result.y, draw_x, draw_y )

	blit_sprite( curs, 0, draw_x, draw_y )
	put(0, 0), buf, PSET
	DrawStats
	DrawMiniMap
	ScreenCopy
	ScreenSet 0
	Do
		skey = Inkey$
		select case skey
			case key_up 'north
				result.y -= 1
			case key_dn 'south
				result.y += 1
			case key_rt 'east
				result.x += 1
			case key_lt 'west
				result.x -= 1
			case key_home 'nw
				result.x -= 1
				result.y -= 1
			case key_pgup 'ne
				result.x += 1
				result.y -= 1
			case key_end 'sw
				result.x -= 1
				result.y += 1
			case key_pgdn 'se
				result.x += 1
				result.y += 1
		End select
	
		ScreenSet 1, 0
		DrawMapNoFlip

		cell_coord_to_display_coord( player.pcoord.x, player.pcoord.y, result.x, result.y, draw_x, draw_y )

		blit_sprite( curs, 0, draw_x, draw_y )
		put(0, 0), buf, PSET
		DrawStats
		DrawMiniMap
	
		ScreenCopy
		ScreenSet 0
	
		sleep 100, 1
	Loop While skey <> key_esc And skey <> key_enter

	If skey = key_esc Then
		PrintMessage "Target cancelled."
		result.x = -1
		result.y = -1
	End If

	DrawMap

function = result

End Function

Sub PrintGenAttr2
	Dim id As Integer
	Dim sdesc As String
	Dim wp As invtype
	Dim arm As invtype

	font_print_center( 96, "Current Attributes", &HFFFFFF, 36 )

	font_print_center( 160, "Strength:" & player.attr.strg, &HFFFFFF, 24 )
	font_print_center( 184, "Endurance:" & player.attr.endu, &HFFFFFF, 24 )
	font_print_center( 208, "Dexterity:" & player.attr.dext, &HFFFFFF, 24 )
	font_print_center( 232, "Agility:" & player.attr.agl, &HFFFFFF, 24 )
	font_print_center( 256, "Intelligence:" & player.attr.intl, &HFFFFFF, 24 )
	font_print_center( 280, "Vision:" & player.attr.vision, &HFFFFFF, 24 )
	font_print_center( 304, "Recovery:" & player.attr.recovery, &HFFFFFF, 24 )
	font_print_center( 328, "Max HP:" & player.attr.strg + player.attr.endu + player.attr.modstrg + player.attr.modendu, &HFFFFFF, 24 )
	font_print_center( 352, "Xp:" & player.attr.expr, &HFFFFFF, 24 )

	id = GetBestWeapon(sdesc)
	wp.typeid = weapons
	wp.weapon.id = id
	GenWeapon wp, False

	font_print_center( 376, "Weapon: " & sdesc & " (Dam: " & wp.weapon.damage & ")", &HFFFF00, 24 )

	id = GetBestArmor(sdesc)
	arm.typeid = armors
	arm.armor.id = id
	GenArmor arm, False

	font_print_center( 400, "Armor: " & sdesc & " (AC: " & arm.armor.ac & ")", &HFFFF00, 24 )

End Sub

sub GenCharacterDisp
	ScreenSet 1, 0
	cls

	font_print_center( 32, "Generate Character", &HFFFF00, 48 )
	GetAttributes
	PrintGenAttr2
	font_print_center( 448, "Press Enter to Accept, R to roll again.", &HFFFFFF, 24 )

	ScreenCopy
	ScreenSet 0
end sub

sub GenCharacter
	dim row as integer
	dim ky as string
	dim sname as string
	Dim sdesc As String
		
	#IfNDef cnosound
	PlaySoundTrack "intofray.mid"
	#endif

	GenCharacterDisp
	do
		ky = inkey$
		if ky = "R" or ky = "r" then
			GenCharacterDisp
		end if
		if ky = chr( 27 ) then end 1
	loop until ky = key_enter
	do
		font_print( 208, 496, "Enter character's name (20 chars max): ", &HFFFFFF, 24 )
		'locate (496 \ 8) + 5, (208 \ 8) + 2
		sname = font_input( 208, 496 + 32, ">", &HFFFF00, 24 )
		'input sname
	loop until len(sname) > 0
	if len(sname) > 20 then
		player.pname = mid$(sname, 1, 20)
	else
		player.pname = sname
	end if
	'give the player a food ration
	ClearInvItem player.inventory(0) 
	player.inventory(0).typeid = supplies
	player.inventory(0).supply.id = smeat
	GenSupply player.inventory(0)
	player.inventory(0).supply.eval = True
	'give the player a light
	ClearInvItem player.inventory(1) 
	player.inventory(1).typeid = lights
	player.inventory(1).light.id = torch
	GenLight player.inventory(1)
	'give the player a random scroll
	ClearInvItem player.inventory(2) 
	player.inventory(2).typeid = potions
	player.inventory(2).potion.id = GetRandom(minpotion, maxpotion)
	GenPotion player.inventory(2), True
	player.inventory(2).potion.eval = True
	player.inventory(2).potion.cursed = False
	'give the player a teleport potion
	ClearInvItem player.inventory(3) 
	player.inventory(3).typeid = scrolls
	player.inventory(3).scroll.id = teleportscroll
	player.inventory(3).scroll.dr = GetDR
	player.inventory(3).scroll.eval = True
	player.inventory(3).scroll.modifier = 0
	player.inventory(3).scroll.noise = 2
	'give the player some leather armor
	ClearInvItem player.parmor
	player.parmor.typeid = armors
	player.parmor.armor.id = GetBestArmor(sdesc)
	GenArmor player.parmor, False
	player.parmor.armor.eval = True
	'Give the player a dagger
	ClearInvItem player.righthand
	player.righthand.typeid = weapons
	player.righthand.weapon.id = GetBestWeapon(sdesc)
	GenWeapon player.righthand, False
	player.righthand.weapon.eval = True
	ClearInvItem player.lefthand
	#IfNDef cnosound
	StopSoundTrack
	#endif
	Cls
end sub

Sub PrintAttributes

#macro printstatA(nam, sta, mo, x, y)
	temp = nam & ": " & sta & " ("
	if mo >= 0 then temp += "+"
	temp += str( mo ) & ")"
	font_print( x, y, temp, &HFFFFFF, 18 )
#endmacro

#macro printstatB(nam, sta, x, y)
	temp = nam & ": "
	if sta >= 0 then temp += "+"
	temp += str( sta )
	font_print( x, y, temp, &HFFFFFF, 18 )
#endmacro

#macro printstatC(nam, sta, x, y)
	temp = nam & ": " & str( sta )
	font_print( x, y, temp, &HFFFFFF, 18 )
#endmacro

	dim as integer l_col_x = 64
	dim as integer r_col_x = 464

	Dim As Integer row, col
	dim as string temp

	font_print_center( 4, "Character Stats", fbAlizarinCrimson, 48 )

	font_print( l_col_x, 64, "Attributes (Modifier)", &HFFFF00, 24 )

	printstatA("Strength", player.attr.strg, player.attr.modstrg, l_col_x, 96)
	printstatA("Endurance", player.attr.endu, player.attr.modendu, l_col_x, 112)
	printstatA("Dexterity", player.attr.dext, player.attr.moddext, l_col_x, 128)
	printstatA("Agility", player.attr.agl, player.attr.modagl, l_col_x, 144)
	printstatA("Intelligence", player.attr.intl, player.attr.modintl, l_col_x, 160)
	printstatA("Vision", player.attr.vision, player.attr.modvision, l_col_x, 176)
	printstatA("Recovery", player.attr.recovery, player.attr.modrecov, l_col_x, 192)

	printstatB("To-Hit mod", player.modtohit, l_col_x, 224)
	printstatB("Damage mod", player.moddamage, l_col_x, 240)
	printstatB("Defense mod", player.moddefense, l_col_x, 256)
	printstatB("Armor mod", player.modarmor, l_col_x, 272)
	printstatB("Magic Att mod", player.modmagicattack, l_col_x, 288)
	printstatB("Magic Def mod", player.modmagicdef, l_col_x, 304)

	printstatC("Max HP", player.attr.maxhp, l_col_x, 336)
	printstatC("Current HP", player.attr.currhp, l_col_x, 352)
	printstatC("Experience", player.attr.expr, l_col_x, 368)
	printstatC("Total Exp", player.attr.totexp, l_col_x, 384)

	font_print( r_col_x, 64, "Skills (Modifier)", &HFFFF00, 24 )

	printstatA("Melee Combat", player.skill.melee, player.skill.modmelee, r_col_x, 96)
	printstatA("Dodge", player.skill.dodge, player.skill.moddodge, r_col_x, 112)
	printstatA("Scan", player.skill.scan, player.skill.modscan, r_col_x, 128)
	printstatA("Sword", player.skill.sword, player.skill.modsword, r_col_x, 144)
	printstatA("Axe", player.skill.axe, player.skill.modaxe, r_col_x, 160)
	printstatA("Spear", player.skill.spear, player.skill.modspear, r_col_x, 176)
	printstatA("Mace", player.skill.mace, player.skill.modmace, r_col_x, 192)
	printstatA("Flail", player.skill.flail, player.skill.modflail, r_col_x, 208)
	printstatA("Bow", player.skill.bow, player.skill.modbow, r_col_x, 224)
	printstatA("Crossbow", player.skill.crossbow, player.skill.modcrossbow, r_col_x, 240)
	printstatA("Shield", player.skill.shield, player.skill.modshield, r_col_x, 256)
	printstatA("Combat Awareness", player.skill.caware, player.skill.modcaware, r_col_x, 272)
	printstatA("Stealth", player.skill.stealth, player.skill.modstealth, r_col_x, 288)
	printstatA("Search", player.skill.search, player.skill.modsearch, r_col_x, 304)
	printstatA("Disarm Trap", player.skill.disarmtrap, player.skill.moddisarmtrap, r_col_x, 320)
	printstatA("Picklock", player.skill.picklock, player.skill.modpicklock, r_col_x, 336)
	printstatA("Read Ancient", player.skill.readancient, player.skill.modreadancient, r_col_x, 352)
	printstatA("Evalulate Magic Item", player.skill.evalmagic, player.skill.modevalmagic, r_col_x, 368)
	printstatA("Use Magic Item", player.skill.usemagicitem, player.skill.modusemagicitem, r_col_x, 384)

	font_print_center( 556, "Press any key to continue.", &HFFFF00, 36 )

end sub

function MainMenu _
	( _
	) as integer

	dim as integer chosen = 0, old_choice = -1

	do
		if chosen <> old_choice then
			dim as uinteger c
			ScreenSet 1, 0
			cls
			font_print_center( 8, "Deep Deadly Dungeons", &HFFFF00, 72 )
			font_print_center( 96, "The Search for the Crown of Alegare", &HFFFF00, 36 )
			font_print( 248, 160, "(N)ew Game", iif( chosen = 0, &HFFFF00, &HFFFFFF ), 48 )
			font_print( 248, 208, "(L)oad Game", iif( chosen = 1, &HFFFF00, &HFFFFFF ), 48 )
			font_print( 248, 256, "(Q)uit Game", iif( chosen = 2, &HFFFF00, &HFFFFFF ), 48 )
			ScreenCopy
			ScreenSet 0
			old_choice = chosen
		end if

		dim as string ky = inkey$

		select case ky
			case key_up 'up
				chosen = (chosen - 1) mod 3
			case key_dn 'down
				chosen = (chosen + 1) mod 3
			case key_esc, key_close, "Q", "q"
				return mquit
			case key_enter
				if chosen = 0 then
					return mnewgame
				elseif chosen = 1 then
					return mloadgame
				elseif chosen = 2 then
					return mquit
				end if
			case "N", "n"
				return mnewgame
			case "L", "l"
				return mloadgame
		end select
    loop

end function





























































sub PrintInventory
	dim sinv as string
	dim as string temp

	ScreenSet 1, 0
	cls

	dim as integer l_col_x = 64
	dim as integer r_col_x = 464

	font_print_center( 4, "Inventory for " + trim(player.pname), fbAlizarinCrimson, 48 )

	temp = "Found Crown: "
	if player.hasorbs.hascrown = True then
		temp += "Yes"
	else
		temp += "No"
	end if
	font_print( l_col_x, 64, temp, &HFFFFFF, 18 )

	temp = "Found Red Orb: "
	if player.hasorbs.hasredorb = True then
		temp += "Yes"
	else
		temp += "No"
	end if
	font_print( l_col_x, 96, temp, &HFFFFFF, 18 )

	temp = "Found Blue Orb: "
	if player.hasorbs.hasblueorb = True then
		temp += "Yes"
	else
		temp += "No"
	end if
	font_print( l_col_x, 112, temp, &HFFFFFF, 18 )

	temp = "Found Green Orb: "
	if player.hasorbs.hasgreenorb = True then
		temp += "Yes"
	else
		temp += "No"
	end if
	font_print( l_col_x, 128, temp, &HFFFFFF, 18 )

	temp = "Found Yellow Orb: "
	if player.hasorbs.hasyelloworb = True then
		temp += "Yes"
	else
		temp += "No"
	end if
	font_print( l_col_x, 144, temp, &HFFFFFF, 18 )

	temp = "Found White Orb: "
	if player.hasorbs.haswhiteorb = True then
		temp += "Yes"
	else
		temp += "No"
	end if
	font_print( l_col_x, 160, temp, &HFFFFFF, 18 )

	temp = "1 Right hand: "
	temp += GetInventoryItemDesc(player.righthand)
	font_print( r_col_x, 64, temp, &HFFFFFF, 18 )

	temp = "2 Left hand: "
	temp += GetInventoryItemDesc(player.lefthand)
	font_print( r_col_x, 80, temp, &HFFFFFF, 18 )

	temp = "3 Armor: "
	temp += GetInventoryItemDesc(player.parmor)
	font_print( r_col_x, 96, temp, &HFFFFFF, 18 )

	temp = "4 Ring Right: "
	temp += GetInventoryItemDesc(player.wright)
	font_print( r_col_x, 112, temp, &HFFFFFF, 18 )

	temp = "5 Ring Left: "
	temp += GetInventoryItemDesc(player.wleft)
	font_print( r_col_x, 128, temp, &HFFFFFF, 18 )

	temp = "6 Neck: "
	temp += GetInventoryItemDesc(player.wneck)
	font_print( r_col_x, 144, temp, &HFFFFFF, 18 )

	temp = "7 Light: "
	temp += GetInventoryItemDesc(player.haslight)
	font_print( r_col_x, 160, temp, &HFFFFFF, 18 )

	font_print_center( 176, string( 150, "-" ), &HFFFFFF, 18 )

	for y as integer = 0 to 12
		temp = chr( asc( "a" ) + y ) & ": "
		temp += GetInventoryItemDesc(player.inventory(y))
		font_print( l_col_x, 192 + (y * 20), temp, &HFFFFFF, 18 )
	next y

	for y as integer = 0 to 12
		temp = chr( asc( "a" ) + y + 13 ) & ": "
		temp += GetInventoryItemDesc(player.inventory(13 + y))
		font_print( r_col_x, 192 + (y * 20), temp, &HFFFFFF, 18 )
	next y


	font_print( 64, 524, "* denotes item not evaluated.", &HFFFF00, 18 )

	font_print_center( 556, "(e)val, e(x)amine, (w)ield/wear, (r)ead, re(m)ove, (d)rop, (q)uaff/eat, ESC", &HFFFF00, 24 )

	ScreenCopy
	ScreenSet 0

end sub

type cmd_t
	k as zstring ptr
	t as zstring ptr
end type

sub ShowCommands _
	( _
	)

	static as cmd_t cmds(0 to 25) = { _
		( @"Esc",           @"Exit program" ), _
		( @"Arrows/Numpad", @"Move character" ), _
		( @"+",             @"Increase music volume" ), _
		( @"-",             @"Decrease music volume" ), _
		( @"<",             @"Ascend staircase" ), _
		( @">",             @"Descend staircase" ), _
		( @"?",             @"Show commands" ), _
		( @"b",             @"Bash door" ), _
		( @"c",             @"Scan" ), _
		( @"d",             @"Dodge" ), _
		( @"g",             @"Get item" ), _
		( @"i",             @"Inventory" ), _
		( @"o",             @"Open door" ), _
		( @"p",             @"Print character stats" ), _
		( @"s",             @"Search for traps & secrets" ), _
		( @"t",             @"Target projectile weapon" ), _
		( @"v",             @"Improve character" ), _
		( @"z",             @"Zap a wand" ), _
		( @"x",             @"Expand mini-map" ), _
		( @"D",             @"Disarm trap" ), _
		( @"H",             @"Toggle health bars" ), _
		( @"Q",             @"Quit Game" ), _
		( @"R",             @"Load Game" ), _
		( @"S",             @"Toggle sound effects" ), _
		( @"W",             @"Save game" ), _
		( NULL,             NULL ) _
	}

	ScreenSet 1, 0
	cls

	font_print_center( 4, "Deep Deadly Dungeons Commands", fbAlizarinCrimson, 48 )

	for i as integer = 0 to 12
		font_print( 64, 96 + (i * 24), *cmds(i).k & ": " & *cmds(i).t, &HFFFFFF, 24 )
	next i

	for i as integer = 0 to 11
		font_print( 464, 96 + (i * 24), *cmds(i + 13).k & ": " & *cmds(i + 13).t, &HFFFFFF, 24 )
	next i

	font_print_center( 556, "Press any key to continue.", &HFFFF00, 36 )

	ScreenCopy
	ScreenSet 0

	sleep
	do while inkey$<>"":loop

end sub

function GetInvKey(prompt as string) as string

    dim ky as string

    PrintInventory
    font_print( 64, 464, prompt, &HFFFF00, 18 )

    do
        ky = inkey$
    loop until ky <> ""

    return ky

end function

sub PrintInvMessage(mess as string)

	PrintInventory
	font_print( 64, 464, mess, &HFFFF00, 18 )
	sleep

	do while inkey$<>"":loop

end sub

Sub PrintStats
	Dim As Integer row, col
	
	ScreenSet 1, 0
	cls

	'display the attribute set

	font_print_center( 4, "Improve Character", fbAlizarinCrimson, 48 )

	font_print( 64, 64, "Attributes", &HFFFF00, 24 )
	font_print( 64, 88, "1000 xp required", &HFFFF00, 24 )

	font_print( 64, 128, "1 Strength:" & player.attr.strg, &HFFFFFF, 18 )
	font_print( 64, 144, "2 Endurance:" & player.attr.endu, &HFFFFFF, 18 )
	font_print( 64, 160, "3 Dexterity:" & player.attr.dext, &HFFFFFF, 18 )
	font_print( 64, 176, "4 Agility:" & player.attr.agl, &HFFFFFF, 18 )
	font_print( 64, 192, "5 Intelligence:" & player.attr.intl, &HFFFFFF, 18 )
	font_print( 64, 208, "6 Vision:" & player.attr.vision, &HFFFFFF, 18 )
	font_print( 64, 224, "7 Recovery:" & player.attr.recovery, &HFFFFFF, 18 )
	font_print( 64, 256, "Max HP = str + end", &HFFFF00, 18 )

	font_print( 464, 64, "Skills (required xp) (attr base)", &HFFFF00, 24 )

	font_print( 464, 128, "8 (30) (agl) Melee Combat:" & player.skill.melee, &HFFFFFF, 18 )
	font_print( 464, 144, "9 (30) (agl) Dodge:" & player.skill.dodge, &HFFFFFF, 18 )
	font_print( 464, 160, "10 (40) (intl) Scan:" & player.skill.scan, &HFFFFFF, 18 )
	font_print( 464, 176, "11 (40) (dext) Sword:" & player.skill.sword, &HFFFFFF, 18 )
	font_print( 464, 192, "12 (60) (dext) Axe:" & player.skill.axe, &HFFFFFF, 18 )
	font_print( 464, 208, "13 (40) (dext) Spear:" & player.skill.spear, &HFFFFFF, 18 )
	font_print( 464, 224, "14 (30) (dext) Mace:" & player.skill.mace, &HFFFFFF, 18 )
	font_print( 464, 240, "15 (60) (dext) Flail:" & player.skill.flail, &HFFFFFF, 18 )
	font_print( 464, 256, "16 (50) (dext) Bow:" & player.skill.bow, &HFFFFFF, 18 )
	font_print( 464, 272, "17 (30) (dext) Crossbow:" & player.skill.crossbow, &HFFFFFF, 18 )
	font_print( 464, 288, "18 (40) (agl) Shield:" & player.skill.shield, &HFFFFFF, 18 )
	font_print( 464, 304, "19 (30) (intl) Combat Awareness:" & player.skill.caware, &HFFFFFF, 18 )
	font_print( 464, 320, "20 (50) (agl) Stealth:" & player.skill.stealth, &HFFFFFF, 18 )
	font_print( 464, 336, "21 (40) (intl) Search:" & player.skill.search, &HFFFFFF, 18 )
	font_print( 464, 352, "22 (50) (dext) Disarm Trap:" & player.skill.disarmtrap, &HFFFFFF, 18 )
	font_print( 464, 368, "23 (40) (dext) Picklock:" & player.skill.picklock, &HFFFFFF, 18 )
	font_print( 464, 384, "24 (40) (intl) Read Ancient:" & player.skill.readancient, &HFFFFFF, 18 )
	font_print( 464, 400, "25 (30) (intl) Evalulate Magic Item:" & player.skill.evalmagic, &HFFFFFF, 18 )
	font_print( 464, 416, "26 (60) (intl) Use Magic Item:" & player.skill.usemagicitem, &HFFFFFF, 18 )

	font_print_center( 440, "Available Experience:" & player.attr.expr, &HFFFFFF, 18 )
	font_print_center( 456, "Enter number of stat to improve. Q to quit.", &HFFFF00, 24 )

	ScreenCopy
	ScreenSet 0

end sub

sub ImproveError(byref s as string)
	font_print_center( 488, s, &HFFFF00, 24 )
end sub

sub DoImproveCharacter
    Dim ky As String
    Dim As Integer kn, row, col
    
    row = 58
    col = 2
    Cls
    PrintStats
    do
	locate 62, 25
	input ky
        If Len(ky) > 0 Then
            If ky = "iamacheater" Then
                If cheater = True Then
                    cheater = False
                Else
                    cheater = True
                    'print cheat codes
                End If
            End If
            If ky = "easteregg" Then
                If easteregg = True Then
                    easteregg = False
                Else
                    easteregg = True
                End If
            End If
            kn = val(ky)
            If kn > 0 And kn < 8 Then 'upgrading attributes
                If player.attr.expr >= 1000 Then
                    If kn = 1 Then
                        'increase the strength
                        player.attr.strg += 1
                        player.attr.expr -= 1000
                        'update the max hp
                        UpdateHp
                        'Update all strength based skills
                    ElseIf kn = 2 Then
                        'increase the endurance
                        player.attr.endu += 1
                        player.attr.expr -= 1000
                        'update the max hp
                        UpdateHP
                    ElseIf kn = 3 Then
                        'increase the dexterity
                        player.attr.dext += 1
                        player.attr.expr -= 1000
                        UpdateDexSkills
                    ElseIf kn = 4 Then
                        'increase the agility
                        player.attr.agl += 1
                        player.attr.expr -= 1000
                        'Update all agility based skills
                        UpdateAglSkills
                    ElseIf kn = 5 Then
                        'increase the intellignce
                        player.attr.intl += 1
                        player.attr.expr -= 1000
                        'Update all intelligence based skills
                        UpdateIntSkills
                    ElseIf kn = 6 Then
                        If player.attr.vision < vh Then
                            'increase the vision
                            player.attr.vision += 1
                            player.attr.expr -= 1000
                        Else
                            ImproveError "Vision is already at max amount."
                        End If
                    ElseIf kn = 7 Then
                        If player.attr.recovery < 99 Then 
                            'increase recovery
                            player.attr.recovery += 1
                            player.attr.expr -= 1000
                        Else
                            ImproveError "Recovery is already at max amount."
                        End If
                    end if
                else
                    ImproveError "Attributes require at least 1000 xp to upgrade."
                End If
            ElseIf kn > 7 And kn < 27 Then 'upgrading skills
                If kn = 8 Then
                    If player.attr.expr >= 30 Then
                        player.skill.melee += ImproveSkill(player.skill.melee)
                        player.attr.expr -= 30
                    else
			ImproveError "Melee requires 30 xp to upgrade."
                    End If
                ElseIf kn = 9 Then
                    If player.attr.expr >= 30 Then
                        player.skill.dodge += ImproveSkill(player.skill.dodge)
                        player.attr.expr -= 30
                    else
			ImproveError "Dodge requires 30 xp to upgrade."
                    End If
                ElseIf kn = 10 Then
                    If player.attr.expr >= 40 Then
                        player.skill.scan += ImproveSkill(player.skill.scan)
                        player.attr.expr -= 40
                    else
			ImproveError "Scan requires 40 xp to upgrade."
                    End If
                ElseIf kn = 11 Then
                    If player.attr.expr >= 40 Then
                        player.skill.sword += ImproveSkill(player.skill.sword) 
                        player.attr.expr -= 40
                    else
			ImproveError "Sword requires 40 xp to upgrade."
                    End If
                ElseIf kn = 12 Then
                    If player.attr.expr >= 60 Then
                        player.skill.axe += ImproveSkill(player.skill.axe)
                        player.attr.expr -= 60
                    else
                        ImproveError "Axe requires 60 xp to upgrade."
                    End If
                ElseIf kn = 13 Then
                    If player.attr.expr >= 40 Then
                        player.skill.spear += ImproveSkill(player.skill.spear)
                        player.attr.expr -= 40
                    else
                        ImproveError "Spear requires 40 xp to upgrade."
                    End If
                ElseIf kn = 14 Then
                    If player.attr.expr >= 30 Then
                        player.skill.mace += ImproveSkill(player.skill.mace)
                        player.attr.expr -= 30
                    else
                        ImproveError "Mace requires 30 xp to upgrade."
                    End If
                ElseIf kn = 15 Then
                    If player.attr.expr >= 60 Then
                        player.skill.flail += ImproveSkill(player.skill.flail)
                        player.attr.expr -= 60
                    else
                        ImproveError "Flail requires 60 xp to upgrade."
                    End If
                ElseIf kn = 16 Then
                    If player.attr.expr >= 50 Then
                        player.skill.bow += ImproveSkill(player.skill.bow)
                        player.attr.expr -= 50
                    else
                        ImproveError "Bow requires 50 xp to upgrade."
                    End If
                ElseIf kn = 17 Then
                    If player.attr.expr >= 30 Then
                        player.skill.crossbow += ImproveSkill(player.skill.crossbow) 
                        player.attr.expr -= 30
                    else
                        ImproveError "Crossbow requires 30 xp to upgrade."
                    End If
                ElseIf kn = 18 Then
                    If player.attr.expr >= 40 Then
                        player.skill.shield += ImproveSkill(player.skill.shield)
                        player.attr.expr -= 40
                    else
                        ImproveError "Shield requires 40 xp to upgrade."
                    End If
                ElseIf kn = 19 Then
                    If player.attr.expr >= 30 Then
                        player.skill.caware += ImproveSkill(player.skill.caware)
                        player.attr.expr -= 30
                    else
                        ImproveError "Combat Awareness requires 30 xp to upgrade."
                    End If
                ElseIf kn = 20 Then
                    If player.attr.expr >= 50 Then
                        player.skill.stealth += ImproveSkill(player.skill.stealth)
                        player.attr.expr -= 50
                    else
                        ImproveError "Stealth requires 50 xp to upgrade."
                    End If
                ElseIf kn = 21 Then
                    If player.attr.expr >= 40 Then
                        player.skill.search += ImproveSkill(player.skill.search)
                        player.attr.expr -= 40
                    else
                        ImproveError "Search requires 40 xp to upgrade."
                    End If
                ElseIf kn = 22 Then
                    If player.attr.expr >= 50 Then
                        player.skill.disarmtrap += ImproveSkill(player.skill.disarmtrap)
                        player.attr.expr -= 50
                    else
                        ImproveError "Disarm trap requires 50 xp to upgrade."
                    End If
                ElseIf kn = 23 Then
                    If player.attr.expr >= 40 Then
                        player.skill.picklock += ImproveSkill(player.skill.picklock)
                        player.attr.expr -= 40
                    else
			ImproveError "Pick lock requires 40 xp to upgrade."
                    End If
                ElseIf kn = 24 Then
                    If player.attr.expr >= 40 Then
                        player.skill.readancient += ImproveSkill(player.skill.readancient)
                        player.attr.expr -= 40
                    else
			ImproveError "Read ancient requires 40 xp to upgrade."
                    End If
                ElseIf kn = 25 Then
                    If player.attr.expr >= 30 Then
                        player.skill.evalmagic += ImproveSkill(player.skill.evalmagic)
                        player.attr.expr -= 30
                    else
                        ImproveError "Evaluate item requires 30 xp to upgrade."
                    End If
                ElseIf kn = 26 Then
                    If player.attr.expr >= 60 Then
                        player.skill.usemagicitem += ImproveSkill(player.skill.usemagicitem)
                        player.attr.expr -= 60
                    else
                        ImproveError "Use magic item requires 60 xp to upgrade."
                    End If
                end if
            end if
        end if
        PrintStats
    Loop Until ky = "Q" Or ky = "q"
    Cls
end sub

Sub ExpandMiniMap
    Dim x As Integer = 280
    Dim y As Integer = 80
    Dim size As Integer = 2
    Dim offset As Integer = size * 2
    Dim As Integer i, j
    
    'Color fbYellow, fbUltramarine
    Cls
    Line (x - (offset * 2), y - (offset * 2)) - (x + (dunw * offset) + offset, y + (dunh * offset) + offset), fbMarsOrange, BF
    For i = 0 To dunw - 1
        For j = 0 To dunh - 1
            DrawMiniMapItem2 offset, i, j, x, y, size
        Next
    Next

	font_print_center( 4, "Current Map of Dungeon Level " & Str$(levels.currlevel), fbAlizarinCrimson, 48 )

	font_print( 64, 80, "Map Legend", &HFFFF00, 36 )

	font_print( 64, 116, "Floor", fbWarmGrey, 24 )
	font_print( 64, 140, "Water", fbBlue, 24 )
	font_print( 64, 164, "Wall", fbWhite, 24 )
	font_print( 64, 188, "Door", fbTan, 24 )
	font_print( 64, 212, "Stairs", fbOrange, 24 )
	font_print( 64, 236, "Items", fbYellow, 24 )
	font_print( 64, 260, "Player", fbGreen, 24 )

	font_print_center( 556, "Press any key to continue.", &HFFFF00, 36 )

    Sleep
    Do:Loop While Inkey$<>""
    Color fbYellow, fbBlack
    Cls
    DrawMap
End Sub

sub DisplayItemInfo(inv as invtype)
    Dim As String idesc = ""
    dim as integer y = 600
    dim as integer row, col
    Cls
	font_print_center( 556, "Press any key to continue.", &HFFFF00, 36 )
    With inv
        Select Case .typeid
            Case lights
                idesc = Trim$(inv.desc)
                If .light.id = torch Or .light.id = lantern Then
                    font_print_center( y, "Turns: " + Str$(.light.count), &HFFFFFF, 24 )
                End If
            Case ammos
                idesc = Trim$(inv.desc)
                font_print_center( y, "Count: " + Str$(.ammo.count), &HFFFFFF, 24 )
            Case supplies
                idesc = Trim$(inv.desc)
                If .supply.id = smeat Or .supply.id = sbread Or .supply.id = sbottle Then
                    font_print_center( y, "Health: " + Str$(.supply.modifier), &HFFFFFF, 24 )
                End If
            case necklaces
                idesc = Trim$(inv.desc)
                If .necklace.eval = True Then
                    font_print_center( y, "Evaluated", &HFFFFFF, 24 )
                    y += 24
                    if .necklace.cursed = true then
                        font_print_center( y, "Cursed", &HFFFFFF, 24 )
                    else
                        font_print_center( y, "Not cursed", &HFFFFFF, 24 )
                    End If
                    y += 24
                    if .necklace.magic = False then
                        font_print_center( y, "Not magic", &HFFFFFF, 24 )
                    else
                        font_print_center( y, GetRNEffectDesc(inv), &HFFFFFF, 24 )
                        y += 24
                        font_print_center( y, "Mod: " & str$(.necklace.modifier), &HFFFFFF, 24 )
                    end if
                Else
                    font_print_center( y, "Not evaluated", &HFFFFFF, 24 )
                end if
            case rings
                idesc = Trim$(inv.desc)
                If .ring.eval = True Then
                    font_print_center( y, "Evaluated", &HFFFFFF, 24 )
                    y += 24
                    if .ring.cursed = true then
                        font_print_center( y, "Cursed", &HFFFFFF, 24 )
                    else
                        font_print_center( y, "Not cursed", &HFFFFFF, 24 )
                    End If
                    y += 24
                    if .ring.magic = False then
                        font_print_center( y, "Not magic", &HFFFFFF, 24 )
                    else
                        font_print_center( y, GetRNEffectDesc(inv), &HFFFFFF, 24 )
                        y += 24
                        font_print_center( y, "Mod: " & str$(.ring.modifier), &HFFFFFF, 24 )
                    end if
                Else
                    font_print_center( y, "Not evaluated", &HFFFFFF, 24 )
                end if
            case potions
                idesc = Trim$(inv.desc)
                If .potion.eval = True Then
                    font_print_center( y, "Evaluated", &HFFFFFF, 24 )
                    y += 24
                    font_print_center( y, "Effect: " & GetPotionEffect(inv), &HFFFFFF, 24 )
                    y += 24
                    font_print_center( y, "Mod: " & Str$(.potion.modifier), &HFFFFFF, 24 )
                Else
                    font_print_center( y, "Not evaluated", &HFFFFFF, 24 )
                end if
            case wands
                idesc = Trim$(inv.desc)
                If .wand.eval = True Then
                    Locate row, col
                    Print "Evaluated"
                    row += 2
                    Locate row, col
                    Print "Dam: ";Str$(.wand.damage)
                    row += 2
                    Locate row, col
                    Print "Charges: ";Str$(.wand.count)
                Else
                    Locate row, col
                    print "Not evaluated"
                end if
            case weapons
                idesc = Trim$(inv.desc)
                If .weapon.eval = True Then
                    Locate row, col
                    Print "Evaluated"
                    row += 2
                    Locate row, col
                    if .weapon.cursed = true then
                        print "Cursed"
                    else
                        print "Not cursed"
                    End If
                    row += 2
                    Locate row, col
                    Print "Hands: ";Str$(.weapon.hands)
                    row += 2
                    Locate row, col
                    Print "Str req: ";Str$(.weapon.strg)
                    row += 2
                    Locate row, col
                    Print "Skill: ";GetWeaponSkillName(inv)
                    row += 2
                    Locate row, col
                    Print "Damage: ";Str$(.weapon.damage)
                    row += 2
                    Locate row, col
                    Print "To hit mod: ";Str$(.weapon.tohitmod)
                    row += 2
                    Locate row, col
                    Print "Damage mod: ";Str$(.weapon.dammod)
                else
                    Locate row, col
                    Print "Not evaluated"
                end if
            Case armors
                idesc = Trim$(inv.desc)
                If .armor.eval = True Then
                    Locate row, col
                    Print "Evaluated"
                    row += 2
                    Locate row, col
                    If .armor.cursed = true Then
                        print "Cursed"
                    else
                        print "Not cursed"
                    end if
                    row += 2
                    Locate row, col
                    Print "Str req: ";Str$(.armor.strg)
                    row += 2
                    Locate row, col
                    Print "AC: ";Str$(.armor.ac)
                    row += 2
                    Locate row, col
                    Print "Def Mod: ";Str$(.armor.defmod)
                    row += 2
                    Locate row, col
                    Print "Def magic: ";Str$(.armor.defmagic)
                    row += 2
                    Locate row, col
                    Print "Magic mod: ";Str$(.armor.defmagicmod)
                Else
                    Locate row, col
                    Print "Not evaluated"
                end if
            case shields
                idesc = Trim$(inv.desc)
                If .armor.eval = True Then
                    Locate row, col
                    Print "Evaluated"
                    row += 2
                    Locate row, col
                    If .shield.cursed = true Then
                        print "Cursed"
                    else
                        print "Not cursed"
                    end if
                    row += 2
                    Locate row, col
                    Print "Str req: ";Str$(.shield.strg)
                    row += 2
                    Locate row, col
                    Print "AC: ";Str$(.shield.ac)
                    row += 2
                    Locate row, col
                    Print "Def Mod: ";Str$(.shield.defmod)
                    row += 2
                    Locate row, col
                    Print "Def magic: ";Str$(.shield.defmagic)
                    row += 2
                    Locate row, col
                    Print "Magic mod: ";Str$(.shield.defmagicmod)
                Else
                    Locate row, col
                    Print "Not evaluated"
                end if
            case scrolls
                idesc = Trim$(inv.desc)
                If .scroll.eval = True Then
                    idesc = GetScrollName(inv)
                    Locate row, col
                    Print "Evaluated"
                    row += 2
                    Locate row, col
                    Print "Mod: ";Str$(.scroll.modifier)
                else
                    Locate row, col
                    Print "Not evaluated"
                end if
        end select
    End With
    font_print_center( 4, "Details for " + idesc, fbAlizarinCrimson, 48 )
    'CenterText 2, UCase$("  Details for " + idesc + "  ")
    Sleep
    Do:Loop While Inkey$<>""
end sub










