From 97da3982d18c7b7a0da0e8723848602fe71d196e Mon Sep 17 00:00:00 2001 From: Maurice Date: Sat, 13 Dec 2025 12:13:01 +0100 Subject: [PATCH] added stackable functionality to items and improved inventory management --- src/de/miaurizius/jgame2d/core/UI.java | 34 +++++++++++++---- .../jgame2d/core/handlers/AssetSetter.java | 25 +++++++++++++ src/de/miaurizius/jgame2d/entity/Entity.java | 6 ++- src/de/miaurizius/jgame2d/entity/Player.java | 37 ++++++++++++++++--- .../jgame2d/entity/item/CoinObj.java | 4 +- .../jgame2d/entity/item/HeartObj.java | 4 +- .../jgame2d/entity/item/KeyObj.java | 7 ++-- .../jgame2d/entity/item/PotionObj.java | 5 ++- .../jgame2d/entity/obstacle/ChestObj.java | 3 +- 9 files changed, 99 insertions(+), 26 deletions(-) diff --git a/src/de/miaurizius/jgame2d/core/UI.java b/src/de/miaurizius/jgame2d/core/UI.java index 1d97ed6..40af2e0 100644 --- a/src/de/miaurizius/jgame2d/core/UI.java +++ b/src/de/miaurizius/jgame2d/core/UI.java @@ -199,6 +199,24 @@ public class UI { graphics2d.fillRoundRect(slotX, slotY, panel.tileSize, panel.tileSize, 10, 10); } graphics2d.drawImage(entity.inventory.get(i).down1, slotX, slotY, null); + + // AMOUNT + if(entity == panel.player && entity.inventory.get(i).amt > 1) { + graphics2d.setFont(graphics2d.getFont().deriveFont(32F)); + int amtX; + int amtY; + String amtS = String.valueOf(entity.inventory.get(i).amt); + amtX = getAlignedToRightX(amtS, slotX+44); + amtY = slotY + panel.tileSize; + + // SHADOW + graphics2d.setColor(new Color(60, 60, 60)); + graphics2d.drawString(amtS, amtX, amtY); + // NUMBER + graphics2d.setColor(Color.white); + graphics2d.drawString(amtS, amtX-3, amtY-3); + } + slotX += slotSize; if (i == 4 || i == 9 || i == 14) { slotX = slotXStart; @@ -450,15 +468,14 @@ public class UI { drawDialogueScreen(); return; } - if(panel.player.inventory.size() == panel.player.maxInvSize) { - tradeState = TradeState.SELECT; - panel.gameState = GameState.DIALOGUE; - currentDialogue = "Your inventory is full!"; - drawDialogueScreen(); + if(panel.player.canObtainItem(tradingNPC.inventory.get(itemIndex))) { + panel.player.coins -= tradingNPC.inventory.get(itemIndex).price; return; } - panel.player.coins -= tradingNPC.inventory.get(itemIndex).price; - panel.player.inventory.add(tradingNPC.inventory.get(itemIndex)); + tradeState = TradeState.SELECT; + panel.gameState = GameState.DIALOGUE; + currentDialogue = "Your inventory is full!"; + drawDialogueScreen(); } } private void tradeSell() { @@ -499,7 +516,8 @@ public class UI { currentDialogue = "You cannot sell an equipped item!"; return; } - panel.player.inventory.remove(itemIndex); + if(panel.player.inventory.get(itemIndex).amt <= 1) panel.player.inventory.remove(itemIndex); + else panel.player.inventory.get(itemIndex).amt--; panel.player.coins += Integer.parseInt(price); } } diff --git a/src/de/miaurizius/jgame2d/core/handlers/AssetSetter.java b/src/de/miaurizius/jgame2d/core/handlers/AssetSetter.java index 33ae5ab..1ab7a68 100644 --- a/src/de/miaurizius/jgame2d/core/handlers/AssetSetter.java +++ b/src/de/miaurizius/jgame2d/core/handlers/AssetSetter.java @@ -39,6 +39,21 @@ public class AssetSetter { panel.obj[Map.OVERWORLD.getIndex()][i].worldX = panel.tileSize*30; panel.obj[Map.OVERWORLD.getIndex()][i].worldY = panel.tileSize*28; i++; + + panel.obj[Map.OVERWORLD.getIndex()][i] = new PotionObj(panel); + panel.obj[Map.OVERWORLD.getIndex()][i].worldX = panel.tileSize*21; + panel.obj[Map.OVERWORLD.getIndex()][i].worldY = panel.tileSize*20; + i++; + + panel.obj[Map.OVERWORLD.getIndex()][i] = new PotionObj(panel); + panel.obj[Map.OVERWORLD.getIndex()][i].worldX = panel.tileSize*20; + panel.obj[Map.OVERWORLD.getIndex()][i].worldY = panel.tileSize*20; + i++; + + panel.obj[Map.OVERWORLD.getIndex()][i] = new PotionObj(panel); + panel.obj[Map.OVERWORLD.getIndex()][i].worldX = panel.tileSize*17; + panel.obj[Map.OVERWORLD.getIndex()][i].worldY = panel.tileSize*21; + i++; } public void setNPC() { @@ -88,6 +103,16 @@ public class AssetSetter { panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,32,12);i++; panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,33,12);i++; + panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,29,21);i++; + + panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,25,27);i++; + panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,26,27);i++; + panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,27,27);i++; + panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,27,28);i++; + panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,27,29);i++; + panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,28,29);i++; + panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,29,29);i++; + panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,18,40);i++; panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,17,40);i++; panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,16,40);i++; diff --git a/src/de/miaurizius/jgame2d/entity/Entity.java b/src/de/miaurizius/jgame2d/entity/Entity.java index 5638285..5445d06 100644 --- a/src/de/miaurizius/jgame2d/entity/Entity.java +++ b/src/de/miaurizius/jgame2d/entity/Entity.java @@ -83,6 +83,8 @@ public class Entity { public int value; public int price; public int knockbackVal; + public boolean stackable; + public int amt = 1; public Entity(GamePanel panel) { this.panel = panel; @@ -229,8 +231,8 @@ public class Entity { alive = false; } } - public void use(Entity entity) { - + public boolean use(Entity entity) { + return false; } //If entity is consumable public void checkDrop() { diff --git a/src/de/miaurizius/jgame2d/entity/Player.java b/src/de/miaurizius/jgame2d/entity/Player.java index 09d9315..0830912 100644 --- a/src/de/miaurizius/jgame2d/entity/Player.java +++ b/src/de/miaurizius/jgame2d/entity/Player.java @@ -5,6 +5,7 @@ import de.miaurizius.jgame2d.core.enums.Direction; import de.miaurizius.jgame2d.core.enums.EntityType; import de.miaurizius.jgame2d.core.enums.GameState; import de.miaurizius.jgame2d.core.handlers.KeyHandler; +import de.miaurizius.jgame2d.entity.item.KeyObj; import de.miaurizius.jgame2d.entity.item.ShieldWoodObj; import de.miaurizius.jgame2d.entity.item.SwordNormalObj; import de.miaurizius.jgame2d.entity.projectile.FireballObj; @@ -150,11 +151,10 @@ public class Player extends Entity { } // INVENTORY ITEMS else { - if(inventory.size() == maxInvSize) { + if(!canObtainItem(panel.obj[panel.currentMap.getIndex()][index])) { panel.ui.addMessage("Your inventory is full!"); return; } - inventory.add(panel.obj[panel.currentMap.getIndex()][index]); panel.playSE(1); panel.ui.addMessage("Picked up " + panel.obj[panel.currentMap.getIndex()][index].name + "!"); } @@ -289,9 +289,9 @@ public class Player extends Entity { currentShield = selectedItem; getDefense(); } - if(selectedItem.consumable) { - selectedItem.use(this); - } + if(selectedItem.consumable) + if(selectedItem.use(this)) + if(selectedItem.amt > 1) selectedItem.amt--; else inventory.remove(selectedItem); } public void setDefaultPositions() { worldX = panel.tileSize * 23; @@ -320,7 +320,7 @@ public class Player extends Entity { dexterity = 1; exp = 0; nextLevelExp = 5; - coins = 0; + coins = 500; currentWeapon = new SwordNormalObj(panel); currentShield = new ShieldWoodObj(panel); projectile = new FireballObj(panel); @@ -331,6 +331,7 @@ public class Player extends Entity { inventory.clear(); inventory.add(currentWeapon); inventory.add(currentShield); + inventory.add(new KeyObj(panel)); } public int getAttack() { attackArea = currentWeapon.attackArea; @@ -373,5 +374,29 @@ public class Player extends Entity { break; } } + public int searchItemInInventory(String itemName) { + for(int i = 0; i < inventory.size(); i++) { + if(inventory.get(i).name.equals(itemName)) { + return i; + } + } + return 999; + } + public boolean canObtainItem(Entity item) { + int i = searchItemInInventory(item.name); + if(item.stackable) { + if(i != 999) { + inventory.get(i).amt++; + return true; + } else if(inventory.size() != maxInvSize) { + inventory.add(item); + return true; + } + } else if(inventory.size() != maxInvSize) { + inventory.add(item); + return true; + } + return false; + } } diff --git a/src/de/miaurizius/jgame2d/entity/item/CoinObj.java b/src/de/miaurizius/jgame2d/entity/item/CoinObj.java index 1dada1a..b9854c9 100644 --- a/src/de/miaurizius/jgame2d/entity/item/CoinObj.java +++ b/src/de/miaurizius/jgame2d/entity/item/CoinObj.java @@ -18,10 +18,10 @@ public class CoinObj extends Entity { down1 = initEntitySprites("/objects/coin_bronze"); } - public void use(Entity entity) { + public boolean use(Entity entity) { panel.playSE(1); panel.ui.addMessage("Coin +"+value); panel.player.coins += value; - panel.player.inventory.remove(this); + return true; } } diff --git a/src/de/miaurizius/jgame2d/entity/item/HeartObj.java b/src/de/miaurizius/jgame2d/entity/item/HeartObj.java index fefdb78..319c665 100644 --- a/src/de/miaurizius/jgame2d/entity/item/HeartObj.java +++ b/src/de/miaurizius/jgame2d/entity/item/HeartObj.java @@ -22,10 +22,12 @@ public class HeartObj extends Entity { image3 = initEntitySprites("objects/heart_blank"); } - public void use(Entity entity) { + @Override + public boolean use(Entity entity) { panel.playSE(2); panel.ui.addMessage("Life +"+value); entity.life += value; + return true; } } diff --git a/src/de/miaurizius/jgame2d/entity/item/KeyObj.java b/src/de/miaurizius/jgame2d/entity/item/KeyObj.java index 2d3d5bf..6d6b2a3 100644 --- a/src/de/miaurizius/jgame2d/entity/item/KeyObj.java +++ b/src/de/miaurizius/jgame2d/entity/item/KeyObj.java @@ -16,20 +16,21 @@ public class KeyObj extends Entity { down1 = initEntitySprites("objects/key"); price = 50; + stackable = true; } @Override - public void use(Entity entity) { + public boolean use(Entity entity) { panel.gameState = GameState.DIALOGUE; int objIndex = getDetected(entity, panel.obj, "door"); if(objIndex == 999) { panel.ui.currentDialogue = "What are you doing?\nThere is no door nearby."; - return; + return false; } panel.ui.currentDialogue = "You used a " + name + "!\nThe door is now open."; panel.playSE(3); panel.obj[panel.currentMap.getIndex()][objIndex] = null; - entity.inventory.remove(this); + return true; } } diff --git a/src/de/miaurizius/jgame2d/entity/item/PotionObj.java b/src/de/miaurizius/jgame2d/entity/item/PotionObj.java index 5089c30..5f3284f 100644 --- a/src/de/miaurizius/jgame2d/entity/item/PotionObj.java +++ b/src/de/miaurizius/jgame2d/entity/item/PotionObj.java @@ -21,16 +21,17 @@ public class PotionObj extends Entity { description = "[" + name + "]\nHeals your life by " + value + "."; price = 50; + stackable = true; } - public void use(Entity entity) { + public boolean use(Entity entity) { panel.gameState = GameState.DIALOGUE; panel.ui.currentDialogue = "You drank a " + name + "!\n" + "Your life has been recovered by " + value + "."; entity.life += value; if(panel.player.life > panel.player.maxLife) panel.player.life = panel.player.maxLife; panel.playSE(2); - panel.player.inventory.remove(this); + return true; } } diff --git a/src/de/miaurizius/jgame2d/entity/obstacle/ChestObj.java b/src/de/miaurizius/jgame2d/entity/obstacle/ChestObj.java index 750e28b..d32d93d 100644 --- a/src/de/miaurizius/jgame2d/entity/obstacle/ChestObj.java +++ b/src/de/miaurizius/jgame2d/entity/obstacle/ChestObj.java @@ -42,13 +42,12 @@ public class ChestObj extends Entity { panel.playSE(3); StringBuilder sb = new StringBuilder(); sb.append("You open the chest and find a ").append(loot.name).append("!"); - if(panel.player.inventory.size() == panel.player.maxInvSize) { + if(!panel.player.canObtainItem(loot)) { sb.append("\nBut your inventory is full..."); panel.ui.currentDialogue = sb.toString(); return; } sb.append("\nYou obtain the ").append(loot.name).append("!"); - panel.player.inventory.add(loot); down1 = image2; opened = true; panel.ui.currentDialogue = sb.toString();