Reformatted inventory and stats screen.

This commit is contained in:
Martin Haye 2017-05-24 07:47:47 -07:00
parent 91fca1abac
commit 58d3386dff
3 changed files with 140 additions and 114 deletions

View File

@ -10,6 +10,9 @@
import gamelib
/////////// Shared numeric constants //////////////
const OVERSIZE_WINDOW_HEIGHT = 174
//////////// Shared library routines ////////////
// Let's try to keep these predef's in lexical order
predef addEncounterZone
@ -118,6 +121,9 @@ import gamelib
predef setWindow3
predef showMapName
predef showParty
predef sprintf1
predef sprintf2
predef sprintf3
predef streqi
predef strncpy
predef takeItemFromPlayer

View File

@ -377,6 +377,8 @@ export asm addToString
rts
end
// Complete string building (including plural processing), and return pointer
// to the string (in the input buffer)
export asm finishString
!zone {
+asmPlasm 1
@ -458,7 +460,7 @@ export asm finishString
.done
dey
sty inbuf ; save new length
lda #<inbuf
lda #<inbuf ; return pointer to string
ldy #>inbuf
rts
}
@ -942,18 +944,6 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
// General methods
export def strncpy(dst, src, maxlen)
byte i, l
l = ^src
if l > maxlen; l = maxlen; fin
^dst = l
for i = 1 to l
dst->[i] = src->[i]
next
return l
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Fatal error: print message and stop the system.
export def fatal(msg)
@ -990,6 +980,43 @@ def abs(n)
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Convert a lower-case character to upper-case (or return unchanged if it's not lower-case)
export def charToUpper(c)
if c >= 'a' and c <= 'z'
return c - $20
fin
return c
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Compare two strings for equality, ignoring case.
export def streqi(a, b)
word limit, leneq
leneq = ^a == ^b
limit = a + min(^a, ^b)
a++; b++
while a <= limit
if charToUpper(^a) <> charToUpper(^b); return FALSE; fin
a++; b++
loop
return leneq
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Copy part of a string
export def strncpy(dst, src, maxlen)
byte i, l
l = ^src
if l > maxlen; l = maxlen; fin
^dst = l
for i = 1 to l
dst->[i] = src->[i]
next
return l
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Read a string from the keyboard using the font manager, and intern it to the heap.
export def getStringResponse()
@ -1085,15 +1112,20 @@ end
export def displayf1(str, arg1); displayf3(str, arg1, 0, 0); end
export def displayf2(str, arg1, arg2); displayf3(str, arg1, arg2, 0); end
// Like printf, but displays text using font engine
export def rawDisplayf3(str, arg1, arg2, arg3)
// Like printf, but buffers string in $200
export def sprintf3(str, arg1, arg2, arg3)
buildString(@addToString)
printf3(str, arg1, arg2, arg3)
rawDisplayStr(finishString(isPlural))
return finishString(isPlural)
end
export def rawDisplayf1(str, arg1); rawDisplayf3(str, arg1, 0, 0); end
export def rawDisplayf2(str, arg1, arg2); rawDisplayf3(str, arg1, arg2, 0); end
export def sprintf1(str, arg1); return sprintf3(str, arg1, 0, 0); end
export def sprintf2(str, arg1, arg2); return sprintf3(str, arg1, arg2, 0); end
// Like printf, but displays text using font engine
export def rawDisplayf1(str, arg1); rawDisplayStr(sprintf3(str, arg1, 0, 0)); end
export def rawDisplayf2(str, arg1, arg2); rawDisplayStr(sprintf3(str, arg1, arg2, 0)); end
export def rawDisplayf3(str, arg1, arg2, arg3); rawDisplayStr(sprintf3(str, arg1, arg2, arg3)); end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def parseDec(str)
@ -1128,15 +1160,6 @@ export def parseDecWithDefault(str, default)
return parseDec(str)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Convert a lower-case character to upper-case (or return unchanged if it's not lower-case)
export def charToUpper(c)
if c >= 'a' and c <= 'z'
return c - $20
fin
return c
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Get a keystroke and convert it to upper case
export def getUpperKey()
@ -1338,23 +1361,32 @@ end
// Window that covers the entire inner area (destroys frame image, so be sure to loadMainFrame
// afterwards)
export def setOversizeWindow()
hline(getScreenLine(5)+1, 0, 0, 36, 0)
hline(getScreenLine(6)+1, $F8, $FF, 36, $8F)
hline(getScreenLine(7)+1, $FC, $FF, 36, $9F)
hline(getScreenLine(8)+1, $8C, 0, 36, $98)
vline(getScreenLine(9)+1, $8C, 174)
vline(getScreenLine(9)+38, $98, 174)
hline(getScreenLine(182)+1, $8C, 0, 36, $98)
hline(getScreenLine(183)+1, $FC, $FF, 36, $9F)
hline(getScreenLine(184)+1, $F8, $FF, 36, $8F)
hline(getScreenLine(185)+1, 0, 0, 36, 0)
// Draw border (if not already drawn)
if frameLoaded
hline(getScreenLine(5)+1, 0, 0, 36, 0)
hline(getScreenLine(6)+1, $F8, $FF, 36, $8F)
hline(getScreenLine(7)+1, $FC, $FF, 36, $9F)
hline(getScreenLine(8)+1, $8C, 0, 36, $98)
vline(getScreenLine(9)+1, $8C, 174)
vline(getScreenLine(9)+38, $98, 174)
hline(getScreenLine(182)+1, $8C, 0, 36, $98)
hline(getScreenLine(183)+1, $FC, $FF, 36, $9F)
hline(getScreenLine(184)+1, $F8, $FF, 36, $8F)
hline(getScreenLine(185)+1, 0, 0, 36, 0)
frameLoaded = 0 // since we just destroyed it
fin
setWindow(9, 183, 14, 267) // Top, Bottom, Left, Right
frameLoaded = 0 // since we destroyed it
end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def rightJustifyStr(str, rightX)
rawDisplayf2("^T%D%s", rightX - calcWidth(str), str)
word space
space = rightX - calcWidth(str)
if (space > 0)
rawDisplayStr("^T") // do not use printf variants, since it might overwrite str
rawDisplayStr(convert3Dec(space))
fin
rawDisplayStr(str)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -2187,20 +2219,6 @@ export def clearEncounterZones()
global=>p_encounterZones = NULL
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Compare two strings for equality, ignoring case.
export def streqi(a, b)
word limit, leneq
leneq = ^a == ^b
limit = a + min(^a, ^b)
a++; b++
while a <= limit
if charToUpper(^a) <> charToUpper(^b); return FALSE; fin
a++; b++
loop
return leneq
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Called by user-defined map scripts to initiate a combat encounter.
export def scriptCombat(mapCode)

View File

@ -31,9 +31,10 @@ const TYPE_USE = $0102
const TYPE_DROP = $0103
// Tab positions
const CHAR_WND_STAT_X = 30
const CHAR_WND_STATLBL_X = 38
const CHAR_WND_INV_X = 18
const CHAR_WND_INVLBL_X = 10
const CHAR_WND_INV_X = 25
const CHAR_WND_STAT_X = 174
const CHAR_WND_STATLBL_X = 182
const STATS_COL_1 = 45
const STATS_COL_2 = 140
@ -104,28 +105,29 @@ def unequip(player, type, kind)
loop
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Display title of a column at top but below character name. Optionally append a second string,
// then leave a little vertical space below before beginning the content of the column.
def showColumnTitle(x, title, page, nPages)
rawDisplayf2("^V000\n^J^J^L^J^T%D%s", x, title)
if nPages > 1
rawDisplayf2(" - p.%d/%d", page, nPages)
fin
rawDisplayStr("^N\n^J^J")
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Display inventory pane
def showInventory(player, page, rows, select)
word item
byte s_item, n_item, n_page, first
byte s_item, n_item, n_page, totalPages, first
s_item = 0
n_item = 0
n_page = page * rows
item = player=>p_items
setMapWindow()
clearWindow()
rawDisplayStr("^Y^LInventory^N")
if !select
if page
rawDisplayf1("^T008<%d", page)
fin
if countList(item) > n_page + rows
rawDisplayf1("^T108%d>", page+2)
fin
fin
rawDisplayStr("^V012") // leave half-a-line of space
totalPages = (countList(item)+rows-1) / rows
showColumnTitle(CHAR_WND_INV_X-10, "Inventory", page+1, totalPages)
if page
while item and n_item < n_page
item = item=>p_nextObj
@ -136,24 +138,21 @@ def showInventory(player, page, rows, select)
while item and n_item < (n_page + rows)
if !first; displayChar('\n'); fin
first = FALSE
if itemMatch(item, select)
displayf1("%c)", 'A' + s_item)
s_item++
fin
rawDisplayf1("^T%D", CHAR_WND_INV_X)
_displayItemName(item)
if item->t_type == TYPE_WEAPON or item->t_type == TYPE_ARMOR
if item->b_flags & ITEM_FLAG_EQUIP
displayStr(" *")
rawDisplayStr("*")
fin
fin
rawDisplayf2("^T%D%c.", CHAR_WND_INVLBL_X, 'A' + s_item)
s_item++
rawDisplayf1("^T%D", CHAR_WND_INV_X)
_displayItemName(item)
n_item++
item = item=>p_nextObj
loop
while n_item < (n_page + rows)
displayChar('\n')
n_item++
loop
return s_item
end
@ -183,21 +182,29 @@ def numToPlayer(num)
end
def displayDice(dice)
if (dice & $0F)
rawDisplayf3("%dd%d+%d", (dice >> 12) & $0F, (dice >> 8) & $0F, dice & $0F)
byte n, d, p
n = (dice >> 12) & $0F
d = (dice >> 8) & $0F
p = dice & $FF
if (p)
rightJustifyStr(sprintf3("%dd%d+%d", n, d, p), CHAR_WND_STAT_X)
else
rawDisplayf2("^T010%dd%d", (dice >> 12) & $0F, (dice >> 8) & $0F)
rightJustifyStr(sprintf2("%dd%d", n, d), CHAR_WND_STAT_X)
fin
end
def vspace()
rawDisplayStr("^J^J^J^J")
end
// Show stats in the right panel
def showStats(player)
word weapon, dmg
setWindow2()
clearWindow()
rawDisplayStr("^Y^LStats^N^V012")
showColumnTitle(CHAR_WND_STAT_X, "Stats", 0, 0)
rightJustifyNum(player=>w_health, CHAR_WND_STAT_X); rawDisplayf1("^T%DHealth\n", CHAR_WND_STATLBL_X)
rightJustifyNum(player=>w_maxHealth, CHAR_WND_STAT_X); rawDisplayf1("^T%DMax health\n", CHAR_WND_STATLBL_X)
vspace()
rightJustifyNum(player->b_intelligence, CHAR_WND_STAT_X); rawDisplayf1("^T%DIntelligence\n", CHAR_WND_STATLBL_X)
rightJustifyNum(player->b_strength, CHAR_WND_STAT_X); rawDisplayf1("^T%DStrength\n", CHAR_WND_STATLBL_X)
rightJustifyNum(player->b_agility, CHAR_WND_STAT_X); rawDisplayf1("^T%DAgility\n", CHAR_WND_STATLBL_X)
@ -205,6 +212,7 @@ def showStats(player)
rightJustifyNum(player->b_charisma, CHAR_WND_STAT_X); rawDisplayf1("^T%DCharisma\n", CHAR_WND_STATLBL_X)
rightJustifyNum(player->b_spirit, CHAR_WND_STAT_X); rawDisplayf1("^T%DSpirit\n", CHAR_WND_STATLBL_X)
rightJustifyNum(player->b_luck, CHAR_WND_STAT_X); rawDisplayf1("^T%DLuck\n", CHAR_WND_STATLBL_X)
vspace()
rightJustifyNum(player->b_armor, CHAR_WND_STAT_X); rawDisplayf1("^T%DArmor\n", CHAR_WND_STATLBL_X)
// Get weapon
weapon = player=>p_items
@ -212,24 +220,22 @@ def showStats(player)
if weapon->t_type == TYPE_WEAPON and weapon->b_flags & ITEM_FLAG_EQUIP; break; fin
weapon = weapon=>p_nextObj
loop
if weapon
dmg = weapon=>r_projectileDmg
else
dmg = 0
fin
if dmg > 0
displayDice(dmg)
if weapon and weapon=>r_projectileDmg
displayDice(weapon=>r_projectileDmg)
rawDisplayf1("^T%DProjectile\n", CHAR_WND_STATLBL_X)
else
if weapon
dmg = weapon=>r_meleeDmg
else
dmg = $01400
fin
displayDice(dmg)
rawDisplayf1("^T%DMelee\n", CHAR_WND_STATLBL_X)
fin
//rightJustifyNum(global=>w_gold, CHAR_WND_STAT_X); rawDisplayf1("^T%DGold (party)", CHAR_WND_STATLBL_X)
if weapon
dmg = weapon=>r_meleeDmg
else
dmg = $01400
fin
displayDice(dmg)
rawDisplayf1("^T%DMelee\n", CHAR_WND_STATLBL_X)
vspace()
rightJustifyNum(global=>w_gold, CHAR_WND_STAT_X); rawDisplayf1("^T%DGold (party)", CHAR_WND_STATLBL_X)
end
// Show aquired skills in lower right panel
@ -237,8 +243,6 @@ def showSkills(player)
word skill
byte col
setWindow3()
clearWindow()
rawDisplayStr("^T040^LSkills^L")
displaySkill("Aim", player->b_aiming, 0)
displaySkill("Fists", player->b_handToHand, 1)
@ -253,8 +257,8 @@ def showSkills(player)
end
// Show player data
def showMenu(vMap)
rawDisplayf1("^V%D^T012E)quip, U)se, D)rop", vMap - 9)
def showMenu()
rawDisplayf1("^V%D^T012E)quip, U)se, D)rop", OVERSIZE_WINDOW_HEIGHT - 9 - 1)
end
// Select an item and equip/unequip it. Returns TRUE if anything changed.
@ -283,8 +287,6 @@ def doUse(player, i_page, i_rows)
rawDisplayStr("\n^T032Which item?")
item = itemNum(player, i_rows * i_page, getUpperKey() - 'A', TYPE_USE)
if item
setWindow2()
clearWindow()
if item=>p_modifiers and streqi(item=>p_modifiers=>s_name, "health")
if player=>w_health < player=>w_maxHealth
player=>w_health = min(player=>w_health + item=>p_modifiers=>w_modValue, player=>w_maxHealth)
@ -343,28 +345,28 @@ end
// the item is returned; else NULL is returned.
def _doPlayerSheet(num)
word player, item
word hMap, vMap, i_rows
word i_rows
byte i_page, redisplay
setOversizeWindow()
clearWindow()
// Get size of inventory pane in chars
getMapWindow(@hMap, @vMap)
i_rows = (vMap / 9) - 3 // 9 rows per line; minus 3 lines for header/footer
i_rows = (OVERSIZE_WINDOW_HEIGHT / 9) - 4 // 9 rows per line; minus 4 lines for header/footer
i_page = 0
redisplay = TRUE
repeat
player = numToPlayer(num)
if !player; return; fin // Invalid player
if redisplay
// First, display the player's name in the title bar
showMapName(player=>s_name)
// First, display the player's name at the top
clearWindow()
rawDisplayf1("^Y^I %s ^N\n", player=>s_name)
showStats(player)
redisplay = FALSE
fin
showInventory(player, i_page, i_rows, 0)
showMenu(vMap)
showMenu()
// Get a key, do something
when getUpperKey()
// Select another player to show