From 1215e12e075d10e59a091227c7d95a25fb27f20a Mon Sep 17 00:00:00 2001 From: Martin Haye Date: Mon, 3 Apr 2017 08:22:32 -0700 Subject: [PATCH] Lots of work on selling especially, but also plural item display on inventory screen. --- .../src/org/badvision/A2PackPartitions.groovy | 4 +- Platform/Apple/virtual/src/plasma/gamelib.plh | 3 +- .../Apple/virtual/src/plasma/gameloop.pla | 35 +++- Platform/Apple/virtual/src/plasma/party.pla | 7 +- Platform/Apple/virtual/src/plasma/store.pla | 187 +++++++++++++++--- 5 files changed, 195 insertions(+), 41 deletions(-) diff --git a/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy b/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy index 932a5295..c1c9eca6 100644 --- a/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy +++ b/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy @@ -3559,7 +3559,7 @@ end assert blk.value.size() == 2 assert blk.value[0].@name == 'CODE' assert blk.value[1].@name == 'PROFIT' - outIndented("buyFromStore(") + outIndented("buySell(") assert blk.value[0].block.size() == 1 packExpr(blk.value[0].block[0]) out << (", ") @@ -3572,7 +3572,7 @@ end { assert blk.value.size() == 1 assert blk.value[0].@name == 'PROFIT' - outIndented("sellToStore(") + outIndented("buySell(NULL, ") assert blk.value[0].block.size() == 1 packExpr(blk.value[0].block[0]) out << ")\n" diff --git a/Platform/Apple/virtual/src/plasma/gamelib.plh b/Platform/Apple/virtual/src/plasma/gamelib.plh index 5cd84576..d8c2a8b3 100644 --- a/Platform/Apple/virtual/src/plasma/gamelib.plh +++ b/Platform/Apple/virtual/src/plasma/gamelib.plh @@ -23,7 +23,7 @@ import gamelib predef benchPlayer predef brk predef buildString - predef buyFromStore + predef buySell predef calcPlayerArmor predef calcWidth predef callGlobalFunc @@ -100,7 +100,6 @@ import gamelib predef scriptEvent predef scriptSetAvatar predef scriptSwapTile - predef sellToStore predef setCmd predef setGameFlag predef setGround diff --git a/Platform/Apple/virtual/src/plasma/gameloop.pla b/Platform/Apple/virtual/src/plasma/gameloop.pla index 7894d7c0..2cecb91f 100644 --- a/Platform/Apple/virtual/src/plasma/gameloop.pla +++ b/Platform/Apple/virtual/src/plasma/gameloop.pla @@ -104,6 +104,7 @@ byte tabBuf[5] // Animation tracking word curPortrait = NULL +byte curPortraitNum = 0 word curFullscreenImg = NULL byte animDirCt byte anyAnims = TRUE @@ -1526,7 +1527,8 @@ def initMap(x, y, dir) needRender = FALSE textDrawn = FALSE curEngine = NULL - curPortrait = 0 + curPortrait = NULL + curPortraitNum = 0 curFullscreenImg = NULL if global->b_curAvatar <> 0 and !mapIs3D setAvatar(global->b_curAvatar) @@ -1566,6 +1568,7 @@ export def clearPortrait() if curPortrait auxMmgr(FREE_MEMORY, curPortrait) curPortrait = NULL + curPortraitNum = 0 fin if curFullscreenImg auxMmgr(FREE_MEMORY, curFullscreenImg) @@ -1976,6 +1979,7 @@ export def setPortrait(portraitNum) if part > 1; part = curMapPartition; fin // Look on disk 1 or current disk only mmgr(START_LOAD, part) curPortrait = auxMmgr(QUEUE_LOAD, portraitNum<<8 | RES_TYPE_PORTRAIT) + curPortraitNum = portraitNum mmgr(FINISH_LOAD, 0) anyAnims = TRUE // for now; might get cleared if we discover otherwise on advance animDirCt = 1 @@ -2707,15 +2711,28 @@ export def unbenchPlayer() end /////////////////////////////////////////////////////////////////////////////////////////////////// -export def buyFromStore(storeCode, profitRatio) - loadEngine(MOD_STORE)=>store_buyFromStore(storeCode, profitRatio) - returnFromEngine() -end +export def buySell(storeCode, profitRatio) + word pModule, portrait + portrait = curPortraitNum + unloadTextures() + clearPortrait() -/////////////////////////////////////////////////////////////////////////////////////////////////// -export def sellToStore(profitRatio) - loadEngine(MOD_STORE)=>store_sellToStore(profitRatio) - returnFromEngine() + mmgr(START_LOAD, 1) // code is in partition 1 + pModule = mmgr(QUEUE_LOAD, MOD_STORE<<8 | RES_TYPE_MODULE) + mmgr(FINISH_LOAD, 0) + + if storeCode + pModule()=>store_buyFromStore(storeCode, profitRatio) + else + pModule()=>store_sellToStore(profitRatio) + fin + + mmgr(FREE_MEMORY, pModule) + loadMainFrameImg() + if portrait; setPortrait(portrait); fin + mapNameHash = 0; showMapName(global=>s_mapName) + showParty() + setWindow2(); clearWindow() // in case we're mid-script end /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Platform/Apple/virtual/src/plasma/party.pla b/Platform/Apple/virtual/src/plasma/party.pla index e9886864..a6097767 100644 --- a/Platform/Apple/virtual/src/plasma/party.pla +++ b/Platform/Apple/virtual/src/plasma/party.pla @@ -133,7 +133,12 @@ def showInventory(player, page, rows, select) s_item++ fin rawDisplayStr("^T018") - displayStr(item=>s_name) + setPlural(FALSE) + if item->t_type == TYPE_STUFF + displayf1("%d ", item=>w_count) + if item=>w_count > 1; setPlural(TRUE); fin + fin + displayf1("%s", item=>s_name) // use displayf to get proper plural processing if item->t_type == TYPE_WEAPON or item->t_type == TYPE_ARMOR if item->b_flags & ITEM_FLAG_EQUIP displayStr(" *") diff --git a/Platform/Apple/virtual/src/plasma/store.pla b/Platform/Apple/virtual/src/plasma/store.pla index e0b106b0..fac723b4 100644 --- a/Platform/Apple/virtual/src/plasma/store.pla +++ b/Platform/Apple/virtual/src/plasma/store.pla @@ -28,6 +28,7 @@ word pItemsModule const MAX_PAGE_ITEMS = 20 // should be plenty word pageItems[MAX_PAGE_ITEMS] word pagePrices[MAX_PAGE_ITEMS] +word pagePlayers[MAX_PAGE_ITEMS] word pMatchPlayer /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -119,7 +120,7 @@ def displayBuyTitle(pageNum, nPages) clearWindow() // Can't use centering mode on oversize window - font engine can't handle width > 255 rawDisplayStr("^Y^I Buying") - if (nPages > 0) + if (nPages > 1) rawDisplayf2(" - p. %d/%d", pageNum+1, nPages) fin rawDisplayStr(" ^N\n^V014^LBrowse^T046Price^T085Item^L") @@ -128,12 +129,15 @@ end /////////////////////////////////////////////////////////////////////////////////////////////////// def displayItemName(pItem) setPlural(FALSE) - if pItem->t_type == TYPE_STUFF; setPlural(TRUE); fin + 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 displayBuyLine(num) +def displayItemLine(num) rawDisplayf2("\n %c.^T046%d^T085", num + 'A', pagePrices[num]) displayItemName(pageItems[num]) end @@ -143,8 +147,6 @@ def displayBuyPage(pItemTbl, markupRatio, pageNum, nPages) byte itemNum word pFunc, pItem - printf1("markupRatio=%d\n", markupRatio) // FIXME FOO - displayBuyTitle(pageNum, nPages) mmgr(HEAP_COLLECT, 0) @@ -154,12 +156,12 @@ def displayBuyPage(pItemTbl, markupRatio, pageNum, nPages) pItem = (*pFunc)() pageItems[itemNum] = pItem pagePrices[itemNum] = max(1, pItem=>w_price + calcMarkup(pItem=>w_price, markupRatio)) - displayBuyLine(itemNum) + displayItemLine(itemNum) pFunc = pFunc + 2 next rawDisplayf2("\n^V166Gold: %d. Browse [A-%c], ", global=>w_gold, itemNum-1+'A') - if nPages > 0 + if nPages > 1 rawDisplayf1("p. [1-%d], ", nPages) fin rawDisplayStr("or [Esc].") @@ -314,7 +316,7 @@ end def matchEquipped(pMatch, nSkip) word pPlayer, pItem pPlayer = global=>p_players - pMatchPlayer = NULL + pMatchPlayer = pPlayer while pPlayer pItem = pPlayer=>p_items while pItem @@ -350,13 +352,8 @@ def displayItemMenu(price, hasNextComp) end /////////////////////////////////////////////////////////////////////////////////////////////////// -def askQuantity(pItem, price) +def askQuantity(nMax) word num - word nMax - nMax = global=>w_gold / price - if pItem=>w_maxCount - nMax = min(nMax, pItem=>w_maxCount) - fin if nMax == 1; return 1; fin rawDisplayf1("How many (1-%d)? ", nMax) num = parseDec(getStringResponse()) @@ -378,23 +375,34 @@ def browseItem(num) rawDisplayf1(" %c\n", sel) quantity = 1 if sel == 'B' and pItem->t_type == TYPE_STUFF and price <= global=>w_gold - quantity = askQuantity(pItem, price) + quantity = global=>w_gold / price + if pItem=>w_maxCount + quantity = min(quantity, pItem=>w_maxCount) + fin + quantity = askQuantity(quantity) fin if sel == 'B' and quantity >= 1 and (price*quantity) <= global=>w_gold matchEquipped(pItem, compSkip) // to set pMatchPlayer - if !addUnique(@pMatchPlayer=>p_items, pItem) - rawDisplayStr("\nDuplicate item.") - beep() - pause(1000) - else - global=>w_gold = global=>w_gold - (price * quantity) + pComp = scanForNamedObj(pMatchPlayer=>p_items, pItem=>s_name) + if pComp if pItem->t_type == TYPE_STUFF - pItem=>w_count = quantity + pComp=>w_count = pComp=>w_count + quantity + else + rawDisplayStr("\nDuplicate item.") + beep() + pause(1000) + continue fin - rawDisplayStr("\nPurchase complete.") - pause(800) - break + else + addToList(@pMatchPlayer=>p_items, pItem) fin + global=>w_gold = global=>w_gold - (price * quantity) + if pItem->t_type == TYPE_STUFF + pItem=>w_count = quantity + fin + rawDisplayStr("\nPurchase complete.") + pause(800) + break elsif sel == 'N' and (compSkip or matchEquipped(pItem, 1+compSkip)) compSkip++ if !matchEquipped(pItem, compSkip); compSkip = 0; fin @@ -447,10 +455,135 @@ def _buyFromStore(storeCode, profitPercent) mmgr(HEAP_COLLECT, 0) end +/////////////////////////////////////////////////////////////////////////////////////////////////// +def displaySellTitle(pageNum, nPages) + clearWindow() + // Can't use centering mode on oversize window - font engine can't handle width > 255 + rawDisplayStr("^Y^I Selling") + if (nPages > 1) + rawDisplayf2(" - p. %d/%d", pageNum+1, nPages) + fin + rawDisplayStr(" ^N\n^V014^LSell^T046Amt.^T085Item^L") +end + +/////////////////////////////////////////////////////////////////////////////////////////////////// +def iterateSellables(skipItems, markdownRatio) + word pPlayer, pItem, itemsOnPage, totalItems + byte ok + itemsOnPage = 0 + totalItems = 0 + pPlayer = global=>p_players + while pPlayer + pItem = pPlayer=>p_items + while pItem + ok = pItem=>w_price > 0 + if pItem->t_type == TYPE_WEAPON or pItem->t_type == TYPE_ARMOR + if pItem->b_flags & ITEM_FLAG_EQUIP; ok = FALSE; fin + fin + if ok + if totalItems >= skipItems and itemsOnPage < PAGE_SIZE + pageItems[itemsOnPage] = pItem + pagePrices[itemsOnPage] = max(0, pItem=>w_price - calcMarkup(pItem=>w_price, markdownRatio)) + pagePlayers[itemsOnPage] = pPlayer + displayItemLine(itemsOnPage) + itemsOnPage++ + fin + totalItems++ + fin + pItem = pItem=>p_nextObj + loop + pPlayer = pPlayer=>p_nextObj + loop + if skipItems == 9999; return totalItems; fin + return itemsOnPage +end + +/////////////////////////////////////////////////////////////////////////////////////////////////// +def displaySellPage(markdownRatio, pageNum, nPages) + word nItems + displaySellTitle(pageNum, nPages) + nItems = iterateSellables(pageNum * PAGE_SIZE, markdownRatio) + rawDisplayf2("\n^V166Gold: %d. Sell [A-%c], ", global=>w_gold, nItems-1+'A') + if nPages > 1 + rawDisplayf1("p. [1-%d], ", nPages) + fin + rawDisplayStr("or [Esc].") + return nItems +end + +/////////////////////////////////////////////////////////////////////////////////////////////////// +def sellItem(num) + word pItem, price, quantity + + pItem = pageItems[num] + price = pagePrices[num] + + clearWindow() + + quantity = 1 + if pItem->t_type == TYPE_STUFF and pItem=>w_count >= 2 + rawDisplayStr("^T108^I Sell ^N\n\nSelling ") + displayItemName(pItem) + rawDisplayStr("\n\n") + quantity = askQuantity(pItem=>w_count) + if quantity == 0; return; fin + fin + + global=>w_gold = global=>w_gold + (price * quantity) + if pItem->t_type == TYPE_STUFF + pItem=>w_count = pItem=>w_count - quantity + if pItem=>w_count > 0 + quantity = 0 + fin + fin + + if quantity > 0 + removeFromList(@pagePlayers=>p_items, pItem) + fin + + rawDisplayStr("\nSale complete.") + pause(800) +end + /////////////////////////////////////////////////////////////////////////////////////////////////// def _sellToStore(profitPercent) - word markupRatio - markupRatio = percentToRatio(profitPercent) + word pItemTbl, choice + byte nItemsOnPage, pageNum, totalItems, nPages, redisplay + + totalItems = iterateSellables(9999, 0) + if totalItems == 0 + scriptDisplayStr("\nNothing to sell.\n") + pause(800) + return + fin + + setOversizeWindow() + + pageNum = 0 + + redisplay = TRUE + while totalItems > 0 + nPages = (totalItems + PAGE_SIZE - 1) / PAGE_SIZE // recalc each time since totalItems changes + pageNum = min(nPages-1, pageNum) + if redisplay + nItemsOnPage = displaySellPage(percentToRatio(profitPercent), pageNum, nPages) + fin + choice = getUpperKey() + redisplay = TRUE + if choice >= '1' and (choice-'1') < nPages + pageNum = choice - '1' + elsif choice >= 'A' and (choice-'A' < nItemsOnPage) + sellItem(choice-'A') + totalItems = iterateSellables(9999, 0) + elsif choice == $1B // Esc + break + else + beep() + redisplay = FALSE + fin + loop + + mmgr(HEAP_COLLECT, 0) end ///////////////////////////////////////////////////////////////////////////////////////////////////