added stackable functionality to items and improved inventory management

This commit is contained in:
2025-12-13 12:13:01 +01:00
parent b380e218f6
commit 97da3982d1
9 changed files with 99 additions and 26 deletions

View File

@@ -199,6 +199,24 @@ public class UI {
graphics2d.fillRoundRect(slotX, slotY, panel.tileSize, panel.tileSize, 10, 10); graphics2d.fillRoundRect(slotX, slotY, panel.tileSize, panel.tileSize, 10, 10);
} }
graphics2d.drawImage(entity.inventory.get(i).down1, slotX, slotY, null); 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; slotX += slotSize;
if (i == 4 || i == 9 || i == 14) { if (i == 4 || i == 9 || i == 14) {
slotX = slotXStart; slotX = slotXStart;
@@ -450,15 +468,14 @@ public class UI {
drawDialogueScreen(); drawDialogueScreen();
return; return;
} }
if(panel.player.inventory.size() == panel.player.maxInvSize) { if(panel.player.canObtainItem(tradingNPC.inventory.get(itemIndex))) {
panel.player.coins -= tradingNPC.inventory.get(itemIndex).price;
return;
}
tradeState = TradeState.SELECT; tradeState = TradeState.SELECT;
panel.gameState = GameState.DIALOGUE; panel.gameState = GameState.DIALOGUE;
currentDialogue = "Your inventory is full!"; currentDialogue = "Your inventory is full!";
drawDialogueScreen(); drawDialogueScreen();
return;
}
panel.player.coins -= tradingNPC.inventory.get(itemIndex).price;
panel.player.inventory.add(tradingNPC.inventory.get(itemIndex));
} }
} }
private void tradeSell() { private void tradeSell() {
@@ -499,7 +516,8 @@ public class UI {
currentDialogue = "You cannot sell an equipped item!"; currentDialogue = "You cannot sell an equipped item!";
return; 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); panel.player.coins += Integer.parseInt(price);
} }
} }

View File

@@ -39,6 +39,21 @@ public class AssetSetter {
panel.obj[Map.OVERWORLD.getIndex()][i].worldX = panel.tileSize*30; panel.obj[Map.OVERWORLD.getIndex()][i].worldX = panel.tileSize*30;
panel.obj[Map.OVERWORLD.getIndex()][i].worldY = panel.tileSize*28; panel.obj[Map.OVERWORLD.getIndex()][i].worldY = panel.tileSize*28;
i++; 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() { 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,32,12);i++;
panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,33,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,18,40);i++;
panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,17,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++; panel.iTile[Map.OVERWORLD.getIndex()][i] = new DryTreeTI(panel,16,40);i++;

View File

@@ -83,6 +83,8 @@ public class Entity {
public int value; public int value;
public int price; public int price;
public int knockbackVal; public int knockbackVal;
public boolean stackable;
public int amt = 1;
public Entity(GamePanel panel) { public Entity(GamePanel panel) {
this.panel = panel; this.panel = panel;
@@ -229,8 +231,8 @@ public class Entity {
alive = false; alive = false;
} }
} }
public void use(Entity entity) { public boolean use(Entity entity) {
return false;
} //If entity is consumable } //If entity is consumable
public void checkDrop() { public void checkDrop() {

View File

@@ -5,6 +5,7 @@ import de.miaurizius.jgame2d.core.enums.Direction;
import de.miaurizius.jgame2d.core.enums.EntityType; import de.miaurizius.jgame2d.core.enums.EntityType;
import de.miaurizius.jgame2d.core.enums.GameState; import de.miaurizius.jgame2d.core.enums.GameState;
import de.miaurizius.jgame2d.core.handlers.KeyHandler; 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.ShieldWoodObj;
import de.miaurizius.jgame2d.entity.item.SwordNormalObj; import de.miaurizius.jgame2d.entity.item.SwordNormalObj;
import de.miaurizius.jgame2d.entity.projectile.FireballObj; import de.miaurizius.jgame2d.entity.projectile.FireballObj;
@@ -150,11 +151,10 @@ public class Player extends Entity {
} }
// INVENTORY ITEMS // INVENTORY ITEMS
else { else {
if(inventory.size() == maxInvSize) { if(!canObtainItem(panel.obj[panel.currentMap.getIndex()][index])) {
panel.ui.addMessage("Your inventory is full!"); panel.ui.addMessage("Your inventory is full!");
return; return;
} }
inventory.add(panel.obj[panel.currentMap.getIndex()][index]);
panel.playSE(1); panel.playSE(1);
panel.ui.addMessage("Picked up " + panel.obj[panel.currentMap.getIndex()][index].name + "!"); panel.ui.addMessage("Picked up " + panel.obj[panel.currentMap.getIndex()][index].name + "!");
} }
@@ -289,9 +289,9 @@ public class Player extends Entity {
currentShield = selectedItem; currentShield = selectedItem;
getDefense(); getDefense();
} }
if(selectedItem.consumable) { if(selectedItem.consumable)
selectedItem.use(this); if(selectedItem.use(this))
} if(selectedItem.amt > 1) selectedItem.amt--; else inventory.remove(selectedItem);
} }
public void setDefaultPositions() { public void setDefaultPositions() {
worldX = panel.tileSize * 23; worldX = panel.tileSize * 23;
@@ -320,7 +320,7 @@ public class Player extends Entity {
dexterity = 1; dexterity = 1;
exp = 0; exp = 0;
nextLevelExp = 5; nextLevelExp = 5;
coins = 0; coins = 500;
currentWeapon = new SwordNormalObj(panel); currentWeapon = new SwordNormalObj(panel);
currentShield = new ShieldWoodObj(panel); currentShield = new ShieldWoodObj(panel);
projectile = new FireballObj(panel); projectile = new FireballObj(panel);
@@ -331,6 +331,7 @@ public class Player extends Entity {
inventory.clear(); inventory.clear();
inventory.add(currentWeapon); inventory.add(currentWeapon);
inventory.add(currentShield); inventory.add(currentShield);
inventory.add(new KeyObj(panel));
} }
public int getAttack() { public int getAttack() {
attackArea = currentWeapon.attackArea; attackArea = currentWeapon.attackArea;
@@ -373,5 +374,29 @@ public class Player extends Entity {
break; 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;
}
} }

View File

@@ -18,10 +18,10 @@ public class CoinObj extends Entity {
down1 = initEntitySprites("/objects/coin_bronze"); down1 = initEntitySprites("/objects/coin_bronze");
} }
public void use(Entity entity) { public boolean use(Entity entity) {
panel.playSE(1); panel.playSE(1);
panel.ui.addMessage("Coin +"+value); panel.ui.addMessage("Coin +"+value);
panel.player.coins += value; panel.player.coins += value;
panel.player.inventory.remove(this); return true;
} }
} }

View File

@@ -22,10 +22,12 @@ public class HeartObj extends Entity {
image3 = initEntitySprites("objects/heart_blank"); image3 = initEntitySprites("objects/heart_blank");
} }
public void use(Entity entity) { @Override
public boolean use(Entity entity) {
panel.playSE(2); panel.playSE(2);
panel.ui.addMessage("Life +"+value); panel.ui.addMessage("Life +"+value);
entity.life += value; entity.life += value;
return true;
} }
} }

View File

@@ -16,20 +16,21 @@ public class KeyObj extends Entity {
down1 = initEntitySprites("objects/key"); down1 = initEntitySprites("objects/key");
price = 50; price = 50;
stackable = true;
} }
@Override @Override
public void use(Entity entity) { public boolean use(Entity entity) {
panel.gameState = GameState.DIALOGUE; panel.gameState = GameState.DIALOGUE;
int objIndex = getDetected(entity, panel.obj, "door"); int objIndex = getDetected(entity, panel.obj, "door");
if(objIndex == 999) { if(objIndex == 999) {
panel.ui.currentDialogue = "What are you doing?\nThere is no door nearby."; 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.ui.currentDialogue = "You used a " + name + "!\nThe door is now open.";
panel.playSE(3); panel.playSE(3);
panel.obj[panel.currentMap.getIndex()][objIndex] = null; panel.obj[panel.currentMap.getIndex()][objIndex] = null;
entity.inventory.remove(this); return true;
} }
} }

View File

@@ -21,16 +21,17 @@ public class PotionObj extends Entity {
description = "[" + name + "]\nHeals your life by " + value + "."; description = "[" + name + "]\nHeals your life by " + value + ".";
price = 50; price = 50;
stackable = true;
} }
public void use(Entity entity) { public boolean use(Entity entity) {
panel.gameState = GameState.DIALOGUE; panel.gameState = GameState.DIALOGUE;
panel.ui.currentDialogue = "You drank a " + name + "!\n" + panel.ui.currentDialogue = "You drank a " + name + "!\n" +
"Your life has been recovered by " + value + "."; "Your life has been recovered by " + value + ".";
entity.life += value; entity.life += value;
if(panel.player.life > panel.player.maxLife) panel.player.life = panel.player.maxLife; if(panel.player.life > panel.player.maxLife) panel.player.life = panel.player.maxLife;
panel.playSE(2); panel.playSE(2);
panel.player.inventory.remove(this); return true;
} }
} }

View File

@@ -42,13 +42,12 @@ public class ChestObj extends Entity {
panel.playSE(3); panel.playSE(3);
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("You open the chest and find a ").append(loot.name).append("!"); 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..."); sb.append("\nBut your inventory is full...");
panel.ui.currentDialogue = sb.toString(); panel.ui.currentDialogue = sb.toString();
return; return;
} }
sb.append("\nYou obtain the ").append(loot.name).append("!"); sb.append("\nYou obtain the ").append(loot.name).append("!");
panel.player.inventory.add(loot);
down1 = image2; down1 = image2;
opened = true; opened = true;
panel.ui.currentDialogue = sb.toString(); panel.ui.currentDialogue = sb.toString();