Refactored item display so party and store can share it.

This commit is contained in:
Martin Haye 2017-04-20 09:36:08 -07:00
parent cc725f0657
commit cc8fa3bb7d
3 changed files with 165 additions and 152 deletions

View File

@ -35,10 +35,15 @@ const CHAR_WND_STAT_X = 30
const CHAR_WND_STATLBL_X = 38
const CHAR_WND_INV_X = 18
const STATS_COL_1 = 45
const STATS_COL_2 = 140
// Exported functions go here. First a predef for each one, then a table with function pointers
// in the same order as the constants are defined in the header.
predef _party_doPlayerSheet, _party_benchPlayer, _party_unbenchPlayer
predef _party_displayItemStats, _party_displayItemName
word[] funcTbl = @_party_doPlayerSheet, @_party_benchPlayer, @_party_unbenchPlayer
word = @_party_displayItemStats, @_party_displayItemName
// Other global variables here
@ -489,6 +494,151 @@ def _party_unbenchPlayer()
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def tabTo(cursorX)
rawDisplayf1("^T%D", cursorX)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def formatDice(encoded)
byte nDice, dieSize, add
nDice = encoded >> 12
dieSize = (encoded >> 8) & $F
add = encoded & $F
rawDisplayf2("%dd%d", nDice, dieSize)
if add; rawDisplayf1("+%d", add); fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def formatNum(num)
rawDisplayf1("%d", num)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def formatStr(str)
rawDisplayStr(str)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def formatAttack(code)
if !code; return; fin
if code == 1
rawDisplayStr("single")
elsif code == 2
rawDisplayStr("double")
else
rawDisplayf1("%d-shot", code)
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def byteField(pItem, field)
if pItem
return ^(pItem + field)
else
return 0
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def wordField(pItem, field)
if pItem
return *(pItem + field)
else
return 0
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayTwoCol(fieldName, pItem1, pItem2, field, fieldFunc, formatFunc)
word val1, val2
val1 = fieldFunc(pItem1, field)
val2 = fieldFunc(pItem2, field)
if val1 or val2
rawDisplayf1("\n%s", fieldName)
if val1; tabTo(STATS_COL_1); formatFunc(val1); fin
if val2; tabTo(STATS_COL_2); formatFunc(val2); fin
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayWeaponStats(pItem1, pItem2)
displayTwoCol("Uses", pItem1, pItem2, b_maxUses, @byteField, @formatNum)
displayTwoCol("Ammo", pItem1, pItem2, s_ammoKind, @wordField, @formatStr)
displayTwoCol("Clip", pItem1, pItem2, b_clipSize, @byteField, @formatNum)
displayTwoCol("Melee", pItem1, pItem2, r_meleeDmg, @wordField, @formatDice)
displayTwoCol("Proj", pItem1, pItem2, r_projectileDmg, @wordField, @formatDice)
displayTwoCol("Attack", pItem1, pItem2, ba_attacks+0, @byteField, @formatAttack)
displayTwoCol("Att 2", pItem1, pItem2, ba_attacks+1, @byteField, @formatAttack)
displayTwoCol("Att 3", pItem1, pItem2, ba_attacks+2, @byteField, @formatAttack)
displayTwoCol("Range", pItem1, pItem2, b_weaponRange, @byteField, @formatNum)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayArmorStats(pItem1, pItem2)
displayTwoCol("Uses", pItem1, pItem2, b_maxUses, @byteField, @formatNum)
displayTwoCol("Protec", pItem1, pItem2, b_armorValue, @byteField, @formatNum)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayStuffStats(pItem1, pItem2)
// Nothing special
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _party_displayItemStats(pItem1, pItem2)
word pMod1, pMod2
// First, show the item type and name
when pItem1->t_type
is TYPE_ITEM; rawDisplayStr("\nItem"); break
is TYPE_WEAPON; rawDisplayStr("\nWeapon"); break
is TYPE_ARMOR; rawDisplayStr("\nArmor"); break
is TYPE_STUFF; rawDisplayStr("\nSupply"); break
otherwise fatal("tItem")
wend
tabTo(STATS_COL_1); _party_displayItemName(pItem1)
if pItem2
if pItem1->t_type <> pItem2->t_type; fatal("tMatch"); fin
tabTo(STATS_COL_2); _party_displayItemName(pItem2)
fin
// Type-specific attributes
when pItem1->t_type
is TYPE_WEAPON; displayWeaponStats(pItem1, pItem2); break
is TYPE_ARMOR; displayArmorStats(pItem1, pItem2); break
is TYPE_STUFF; displayStuffStats(pItem1, pItem2); break
wend
// If either item has modifiers, show them
pMod1 = pItem1=>p_modifiers
pMod2 = NULL
if pItem2; pMod2 = pItem2=>p_modifiers; fin
if pMod1 or pMod2
rawDisplayStr("\nSpecial:")
while pMod1 or pMod2
if pMod1
rawDisplayf3("^T%D%d %s", STATS_COL_1, pMod1=>w_modValue, pMod1=>s_name)
pMod1 = pMod1=>p_nextObj
fin
if pMod2
rawDisplayf3("^T%D%d %s", STATS_COL_2, pMod2=>w_modValue, pMod2=>s_name)
pMod2 = pMod2=>p_nextObj
fin
loop
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def _party_displayItemName(pItem)
setPlural(FALSE)
if pItem->t_type == TYPE_STUFF; setPlural(pItem=>w_count <> 1); fin
if pItem=>w_count >= 1
rawDisplayf1("%d ", pItem=>w_count)
fin
rawDisplayf1("%s", pItem=>s_name) // use displayf to get proper plural processing
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Boilerplate module initialization code
return @funcTbl

View File

@ -12,3 +12,5 @@
const party_showPlayerSheet = 0
const party_benchPlayer = 2
const party_unbenchPlayer = 4
const party_displayItemStats = 6
const party_displayItemName = 8

View File

@ -11,6 +11,7 @@
include "gamelib.plh"
include "playtype.plh"
include "globalDefs.plh"
include "party.plh"
include "gen_modules.plh"
include "gen_items.plh"
@ -24,7 +25,7 @@ const STATS_COL_2 = 140
predef _buyFromStore, _sellToStore
word[] funcTbl = @_buyFromStore, @_sellToStore
word pItemsModule
word pItemsModule, pPartyModule
const MAX_PAGE_ITEMS = 20 // should be plenty
word pageItems[MAX_PAGE_ITEMS]
word pagePrices[MAX_PAGE_ITEMS]
@ -104,15 +105,17 @@ def calcMarkup(price, ratio)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def loadItems()
def loadExtraModules()
mmgr(START_LOAD, 1) // code is in partition 1
pItemsModule = mmgr(QUEUE_LOAD, MOD_GEN_ITEMS<<8 | RES_TYPE_MODULE)
pPartyModule = mmgr(QUEUE_LOAD, MOD_PARTY<<8 | RES_TYPE_MODULE)
mmgr(FINISH_LOAD, 0)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def unloadItems()
def unloadExtraModules()
mmgr(FREE_MEMORY, pItemsModule)
mmgr(FREE_MEMORY, pPartyModule)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -126,20 +129,10 @@ def displayBuyTitle(pageNum, nPages)
rawDisplayStr(" ^N\n^V014^LBrowse^T046Price^T085Item^L")
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayItemName(pItem)
setPlural(FALSE)
if pItem->t_type == TYPE_STUFF; setPlural(pItem=>w_count <> 1); fin
if pItem=>w_count >= 1
rawDisplayf1("%d ", pItem=>w_count)
fin
rawDisplayf1("%s", pItem=>s_name) // use displayf to get proper plural processing
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayItemLine(num)
rawDisplayf2("\n %c.^T046%d^T085", num + 'A', pagePrices[num])
displayItemName(pageItems[num])
pPartyModule()=>party_displayItemName(pageItems[num])
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -169,145 +162,13 @@ def displayBuyPage(pItemTbl, markupRatio, pageNum, nPages)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def tabTo(cursorX)
rawDisplayf1("^T%D", cursorX)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def formatDice(encoded)
byte nDice, dieSize, add
nDice = encoded >> 12
dieSize = (encoded >> 8) & $F
add = encoded & $F
rawDisplayf2("%dd%d", nDice, dieSize)
if add; rawDisplayf1("+%d", add); fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def formatNum(num)
rawDisplayf1("%d", num)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def formatStr(str)
rawDisplayStr(str)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def formatAttack(code)
if !code; return; fin
if code == 1
rawDisplayStr("single")
elsif code == 2
rawDisplayStr("double")
else
rawDisplayf1("%d-shot", code)
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def byteField(pItem, field)
if pItem
return ^(pItem + field)
else
return 0
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def wordField(pItem, field)
if pItem
return *(pItem + field)
else
return 0
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayTwoCol(fieldName, pItem1, pItem2, field, fieldFunc, formatFunc)
word val1, val2
val1 = fieldFunc(pItem1, field)
val2 = fieldFunc(pItem2, field)
if val1 or val2
rawDisplayf1("\n%s", fieldName)
if val1; tabTo(STATS_COL_1); formatFunc(val1); fin
if val2; tabTo(STATS_COL_2); formatFunc(val2); fin
fin
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayWeaponStats(pItem1, pItem2)
displayTwoCol("Uses", pItem1, pItem2, b_maxUses, @byteField, @formatNum)
displayTwoCol("Ammo", pItem1, pItem2, s_ammoKind, @wordField, @formatStr)
displayTwoCol("Clip", pItem1, pItem2, b_clipSize, @byteField, @formatNum)
displayTwoCol("Melee", pItem1, pItem2, r_meleeDmg, @wordField, @formatDice)
displayTwoCol("Proj", pItem1, pItem2, r_projectileDmg, @wordField, @formatDice)
displayTwoCol("Attack", pItem1, pItem2, ba_attacks+0, @byteField, @formatAttack)
displayTwoCol("Att 2", pItem1, pItem2, ba_attacks+1, @byteField, @formatAttack)
displayTwoCol("Att 3", pItem1, pItem2, ba_attacks+2, @byteField, @formatAttack)
displayTwoCol("Range", pItem1, pItem2, b_weaponRange, @byteField, @formatNum)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayArmorStats(pItem1, pItem2)
displayTwoCol("Uses", pItem1, pItem2, b_maxUses, @byteField, @formatNum)
displayTwoCol("Protec", pItem1, pItem2, b_armorValue, @byteField, @formatNum)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayStuffStats(pItem1, pItem2)
// Nothing special
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayItemStats(pItem1, price, pItem2)
word pMod1, pMod2
def displayItemBrowse(pItem1, price, pItem2)
clearWindow()
rawDisplayf1("^T108^I Browse ^N\n\n^T%D^LMerchandise^L", STATS_COL_1)
if pItem2
rawDisplayf2("^T%D^L%s^L", STATS_COL_2, pMatchPlayer=>s_name)
fin
// First, show the item type and name
when pItem1->t_type
is TYPE_ITEM; rawDisplayStr("\nItem"); break
is TYPE_WEAPON; rawDisplayStr("\nWeapon"); break
is TYPE_ARMOR; rawDisplayStr("\nArmor"); break
is TYPE_STUFF; rawDisplayStr("\nSupply"); break
otherwise fatal("tItem")
wend
tabTo(STATS_COL_1); displayItemName(pItem1)
if pItem2
if pItem1->t_type <> pItem2->t_type; fatal("tMatch"); fin
tabTo(STATS_COL_2); displayItemName(pItem2)
fin
// Type-specific attributes
when pItem1->t_type
is TYPE_WEAPON; displayWeaponStats(pItem1, pItem2); break
is TYPE_ARMOR; displayArmorStats(pItem1, pItem2); break
is TYPE_STUFF; displayStuffStats(pItem1, pItem2); break
wend
// If either item has modifiers, show them
pMod1 = pItem1=>p_modifiers
pMod2 = NULL
if pItem2; pItem2=>p_modifiers; fin
if pMod1 or pMod2
rawDisplayStr("\nSpecial:")
while pMod1 or pMod2
if pMod1
rawDisplayf3("^T%D%d %s", STATS_COL_1, pMod1=>w_modValue, pMod1=>s_name)
pMod1 = pMod1=>p_nextObj
fin
if pMod2
rawDisplayf3("^T%D%d %s", STATS_COL_2, pMod2=>w_modValue, pMod2=>s_name)
pMod2 = pMod2=>p_nextObj
fin
loop
fin
pPartyModule()=>party_displayItemStats(pItem1, pItem2)
rawDisplayf2("\n\nPrice^T%D%d", STATS_COL_1, price)
rawDisplayf2("\nAvail^T%D%d", STATS_COL_1, global=>w_gold)
end
@ -369,7 +230,7 @@ def browseItem(num)
price = pagePrices[num]
compSkip = 0
while TRUE
displayItemStats(pItem, price, matchEquipped(pItem, compSkip))
displayItemBrowse(pItem, price, matchEquipped(pItem, compSkip))
displayItemMenu(price, compSkip or matchEquipped(pItem, 1+compSkip))
sel = getUpperKey()
rawDisplayf1(" %c\n", sel)
@ -424,7 +285,7 @@ def _buyFromStore(storeCode, profitPercent)
word pItemTbl, choice
byte nItemsOnPage, pageNum, nPages, redisplay
loadItems()
loadExtraModules()
pItemTbl = pItemsModule()=>items_forStoreCode(storeCode)
setOversizeWindow()
@ -451,7 +312,7 @@ def _buyFromStore(storeCode, profitPercent)
fin
loop
unloadItems()
unloadExtraModules()
mmgr(HEAP_COLLECT, 0)
end
@ -523,7 +384,7 @@ def sellItem(num)
quantity = 1
if pItem->t_type == TYPE_STUFF and pItem=>w_count >= 2
rawDisplayStr("^T108^I Sell ^N\n\nSelling ")
displayItemName(pItem)
pPartyModule()=>party_displayItemName(pItem)
rawDisplayStr("\n\n")
quantity = askQuantity(pItem=>w_count)
if quantity == 0; return; fin