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

View File

@ -377,6 +377,8 @@ export asm addToString
rts rts
end end
// Complete string building (including plural processing), and return pointer
// to the string (in the input buffer)
export asm finishString export asm finishString
!zone { !zone {
+asmPlasm 1 +asmPlasm 1
@ -458,7 +460,7 @@ export asm finishString
.done .done
dey dey
sty inbuf ; save new length sty inbuf ; save new length
lda #<inbuf lda #<inbuf ; return pointer to string
ldy #>inbuf ldy #>inbuf
rts rts
} }
@ -942,18 +944,6 @@ end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// General methods // 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. // Fatal error: print message and stop the system.
export def fatal(msg) export def fatal(msg)
@ -990,6 +980,43 @@ def abs(n)
fin fin
end 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. // Read a string from the keyboard using the font manager, and intern it to the heap.
export def getStringResponse() export def getStringResponse()
@ -1085,15 +1112,20 @@ end
export def displayf1(str, arg1); displayf3(str, arg1, 0, 0); end export def displayf1(str, arg1); displayf3(str, arg1, 0, 0); end
export def displayf2(str, arg1, arg2); displayf3(str, arg1, arg2, 0); end export def displayf2(str, arg1, arg2); displayf3(str, arg1, arg2, 0); end
// Like printf, but displays text using font engine // Like printf, but buffers string in $200
export def rawDisplayf3(str, arg1, arg2, arg3) export def sprintf3(str, arg1, arg2, arg3)
buildString(@addToString) buildString(@addToString)
printf3(str, arg1, arg2, arg3) printf3(str, arg1, arg2, arg3)
rawDisplayStr(finishString(isPlural)) return finishString(isPlural)
end end
export def rawDisplayf1(str, arg1); rawDisplayf3(str, arg1, 0, 0); end export def sprintf1(str, arg1); return sprintf3(str, arg1, 0, 0); end
export def rawDisplayf2(str, arg1, arg2); rawDisplayf3(str, arg1, arg2, 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) export def parseDec(str)
@ -1128,15 +1160,6 @@ export def parseDecWithDefault(str, default)
return parseDec(str) return parseDec(str)
end 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 // Get a keystroke and convert it to upper case
export def getUpperKey() export def getUpperKey()
@ -1338,6 +1361,8 @@ end
// Window that covers the entire inner area (destroys frame image, so be sure to loadMainFrame // Window that covers the entire inner area (destroys frame image, so be sure to loadMainFrame
// afterwards) // afterwards)
export def setOversizeWindow() export def setOversizeWindow()
// Draw border (if not already drawn)
if frameLoaded
hline(getScreenLine(5)+1, 0, 0, 36, 0) hline(getScreenLine(5)+1, 0, 0, 36, 0)
hline(getScreenLine(6)+1, $F8, $FF, 36, $8F) hline(getScreenLine(6)+1, $F8, $FF, 36, $8F)
hline(getScreenLine(7)+1, $FC, $FF, 36, $9F) hline(getScreenLine(7)+1, $FC, $FF, 36, $9F)
@ -1348,13 +1373,20 @@ export def setOversizeWindow()
hline(getScreenLine(183)+1, $FC, $FF, 36, $9F) hline(getScreenLine(183)+1, $FC, $FF, 36, $9F)
hline(getScreenLine(184)+1, $F8, $FF, 36, $8F) hline(getScreenLine(184)+1, $F8, $FF, 36, $8F)
hline(getScreenLine(185)+1, 0, 0, 36, 0) 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 setWindow(9, 183, 14, 267) // Top, Bottom, Left, Right
frameLoaded = 0 // since we destroyed it
end end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
export def rightJustifyStr(str, rightX) 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 end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
@ -2187,20 +2219,6 @@ export def clearEncounterZones()
global=>p_encounterZones = NULL global=>p_encounterZones = NULL
end 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. // Called by user-defined map scripts to initiate a combat encounter.
export def scriptCombat(mapCode) export def scriptCombat(mapCode)

View File

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