From 2c85b4e57945d886c32e34157ac2a6cbe3d07910 Mon Sep 17 00:00:00 2001 From: Trey Tomes Date: Tue, 26 Dec 2023 10:23:27 -0600 Subject: [PATCH] Select drop amount when stack size > 1. --- src/entity.ms | 2 +- src/factories/actions.ms | 26 ++++++++---- src/factories/behaviors.ms | 11 +++++- src/ui.ms | 6 +++ src/ui/IntegerSelectWindow.ms | 66 +++++++++++++++++++++++++++++++ src/ui/InventorySelectListItem.ms | 8 ++-- src/ui/SelectList.ms | 25 ++++++------ 7 files changed, 116 insertions(+), 28 deletions(-) create mode 100644 src/ui/IntegerSelectWindow.ms diff --git a/src/entity.ms b/src/entity.ms index 19e4480..2fc0d14 100644 --- a/src/entity.ms +++ b/src/entity.ms @@ -92,7 +92,7 @@ end function Entity.onDeath = function(killedByEntity, map) // Drop some loot. while self.inventory.len > 0 - actions.dropInventoryItem(0).apply(self, map) + actions.dropInventoryItem(0, 1).apply(self, map) end while end function diff --git a/src/factories/actions.ms b/src/factories/actions.ms index 415107a..cd2764c 100644 --- a/src/factories/actions.ms +++ b/src/factories/actions.ms @@ -65,20 +65,30 @@ useInventoryItem = function(inventoryIndex) return action end function -dropInventoryItem = function(inventoryIndex) +dropInventoryItem = function(inventoryIndex, count) action = new EntityAction action.inventoryIndex = inventoryIndex + action.count = count action.apply = function(entity, map) stack = entity.inventory.get(self.inventoryIndex) item = stack.item - entity.inventory.removeItem(self.inventoryIndex) - if stack.count == 0 then - entity.removeFromSlots(item) + count = self.count + while count > 0 + entity.inventory.removeItem(self.inventoryIndex) + if stack.count == 0 then + entity.removeFromSlots(item) + end if + + itemEntity = entities.makeItem(map, item, entity.position) + map.entities.push(itemEntity) + count -= 1 + end while + + if self.count == 1 then + Service.messages.report("{0} dropped {1}.".fill([entity.name, item.name])) + else + Service.messages.report("{0} dropped {1} x{2}.".fill([entity.name, item.name, self.count])) end if - - itemEntity = entities.makeItem(map, item, entity.position) - map.entities.push(itemEntity) - Service.messages.report("{0} dropped {1}.".fill([entity.name, item.name])) end function return action end function diff --git a/src/factories/behaviors.ms b/src/factories/behaviors.ms index 8500994..ef1c502 100644 --- a/src/factories/behaviors.ms +++ b/src/factories/behaviors.ms @@ -202,7 +202,16 @@ makeUserInput = function() if index == null then return null end if - return actions.dropInventoryItem(index) + + stack = entity.inventory.get(index) + if stack.count > 1 then + count = ui.selectInteger(1, stack.count, "How much?") + // Service.messages.report("You selected {0}.".fill([count])) + else + count = 1 + end if + + return actions.dropInventoryItem(index, count) end function b.useInventory = function(entity) diff --git a/src/ui.ms b/src/ui.ms index ff44ab2..6336da1 100644 --- a/src/ui.ms +++ b/src/ui.ms @@ -121,6 +121,7 @@ ExamineSelectListItem = require("ExamineSelectListItem") ExamineWindow = require("ExamineWindow") MessageWindow = require("MessageWindow") HeadsUpDisplay = require("HeadsUpDisplay") +IntegerSelectWindow = require("IntegerSelectWindow") selectItem = function(entity, title) return (new ui.InventorySelectWindow).selectItem(entity, title) @@ -133,3 +134,8 @@ end function showMessage = function(message, options, title="Message") return ui.MessageWindow.make(message, options, title).show() end function + +selectInteger = function(min, max, title="How many?") + wnd = ui.IntegerSelectWindow.make(min, max, title) + return wnd.select() +end function diff --git a/src/ui/IntegerSelectWindow.ms b/src/ui/IntegerSelectWindow.ms new file mode 100644 index 0000000..058e1e2 --- /dev/null +++ b/src/ui/IntegerSelectWindow.ms @@ -0,0 +1,66 @@ +IntegerSelectWindow = {} + +IntegerSelectWindow.make = function(min, max, title) + return (new IntegerSelectWindow).init(min, max, title) +end function + +IntegerSelectWindow.init = function(min, max, title) + self.min = min + self.max = max + self.title = title + self.result = min + self.fieldSize = math.max(str(self.min).len, str(self.max).len) + + margin = 10 + width = math.max(self.fieldSize + 4, title.len + 6) + height = 5 + x = (constants.UI_DISPLAY_WIDTH - width) / 2 + y = (constants.UI_DISPLAY_HEIGHT - height) / 2 + self.bounds = rect.make(x, y, width, 5) + return self +end function + +IntegerSelectWindow.drawLabel = function() + x = self.bounds.left + (self.bounds.width - (self.fieldSize + 4)) / 2 + y = self.bounds.bottom - 2 + text = str(self.result).pad(self.fieldSize) + Display.hud.setCell x, y, 17, Color.white, Color.black + Display.hud.print text, x + 2, y, Color.yellow, Color.black + Display.hud.setCell x + 2 + self.fieldSize + 1, y, 16, Color.white, Color.black +end function + +IntegerSelectWindow.draw = function() + ui.drawWindow(Display.hud, self.bounds, self.title) + self.drawLabel() +end function + +IntegerSelectWindow.select = function() + self.draw() + + while true + delta = 0 + k = key.get.code + if keybindings.up.contains(k) or keybindings.left.contains(k) then + delta = -1 + else if keybindings.down.contains(k) or keybindings.right.contains(k) then + delta = 1 + else if keybindings.exit.contains(k) then + self.result = null + break + else if keybindings.select.contains(k) then + break + end if + + if delta != 0 then + self.result = math.clamp(self.result + delta, self.min, self.max) + self.drawLabel() + end if + + end while + + ui.clearRect(Display.hud, self.bounds, null, Color.clear, Color.clear) + + return self.result +end function + +return IntegerSelectWindow diff --git a/src/ui/InventorySelectListItem.ms b/src/ui/InventorySelectListItem.ms index 8fb30a2..43dab23 100644 --- a/src/ui/InventorySelectListItem.ms +++ b/src/ui/InventorySelectListItem.ms @@ -14,11 +14,11 @@ InventorySelectListItem.draw = function(parent, isSelected) item = stack.item if isSelected then - bg = parent.ITEM_BACKGROUND_SELECTED.str() - fg = parent.ITEM_FOREGROUND_SELECTED.str() + bg = parent.ITEM_BACKGROUND_SELECTED + fg = parent.ITEM_FOREGROUND_SELECTED else - bg = parent.ITEM_BACKGROUND.str() - fg = parent.ITEM_FOREGROUND.str() + bg = parent.ITEM_BACKGROUND + fg = parent.ITEM_FOREGROUND end if x = parent.listBounds.left diff --git a/src/ui/SelectList.ms b/src/ui/SelectList.ms index 9378f86..2a6f9e3 100644 --- a/src/ui/SelectList.ms +++ b/src/ui/SelectList.ms @@ -91,25 +91,22 @@ end function SelectList.drawItems = function() ui.clearRect(self.display, self.listBounds, " ", Color.clear.str(), Color.black.str()) - self.display.color = color.gray n = 1 + x = self.windowBounds.left + 1 y = self.windowBounds.bottom - 1 + bg = Color.black if not self.isAtTop then - self.display.color = self.LIST_MORE_FOREGROUND.str() + fg = self.LIST_MORE_FOREGROUND + self.display.print("^" * (self.windowBounds.width / 2 - 1), x, y, fg, bg) else - self.display.color = self.LIST_NOMORE_FOREGROUND.str() + fg = self.LIST_NOMORE_FOREGROUND + self.display.print("^" * (self.windowBounds.width / 2 - 1), x, y, fg, bg) end if - self.display.row = y - self.display.column = self.windowBounds.left + 1 - self.display.backColor = color.black - self.display.print("^" * (self.windowBounds.width / 2 - 1)) y -= 1 if self.list.len == 0 then - self.display.row = y - self.display.column = self.windowBounds.left + 1 - self.display.print("You've got nothing.") + self.display.print("You've got nothing.", self.windowBounds.left + 1, y, fg, bg) else for n in range(self.firstDisplayIndex, self.lastDisplayIndex) if math.isInRange(n, 0, self.list.len - 1) then @@ -125,10 +122,10 @@ SelectList.drawItems = function() else self.display.color = self.LIST_NOMORE_FOREGROUND.str() end if - self.display.row = self.windowBounds.top + 1 - self.display.column = self.windowBounds.left + 1 - self.display.backColor = self.ITEM_BACKGROUND.str() - self.display.print("v" * (self.windowBounds.width / 2 - 1)) + x = self.windowBounds.left + 1 + y = self.windowBounds.top + 1 + bg = self.ITEM_BACKGROUND + self.display.print("v" * (self.windowBounds.width / 2 - 1), x, y, fg, bg) if self.selectedItem != null then self.selectedItem.describe(self) end function