diff --git a/README.md b/README.md index 7a1a2bd4..fff99ed8 100644 --- a/README.md +++ b/README.md @@ -83,8 +83,6 @@ graph TD; - [ ] implement bonus gained by class - [ ] implement magic, resist, ... stats -- [ ] armor sets - - [ ] crafting feature - [ ] credits @@ -94,6 +92,7 @@ graph TD; ------- ## Bugs +- Objects in inventory are stacking even if there are not the same - FadeIn effect not working when transition [menu → game] - Drag and drop selection issue on item's render (items are far from mouse when picking them) - Sometimes current hp/mp on status HUD add a blank space before the max player's hp/mp diff --git a/core/src/main/java/com/gdx/game/battle/BattleHUD.java b/core/src/main/java/com/gdx/game/battle/BattleHUD.java index 901a90cf..974b4f78 100644 --- a/core/src/main/java/com/gdx/game/battle/BattleHUD.java +++ b/core/src/main/java/com/gdx/game/battle/BattleHUD.java @@ -24,8 +24,8 @@ import com.gdx.game.entities.player.characterClass.ClassObserver; import com.gdx.game.entities.player.characterClass.tree.Node; import com.gdx.game.entities.player.characterClass.tree.Tree; -import com.gdx.game.inventory.InventoryItem; -import com.gdx.game.inventory.InventoryItemLocation; +import com.gdx.game.inventory.item.InventoryItem; +import com.gdx.game.inventory.item.InventoryItemLocation; import com.gdx.game.inventory.InventoryObserver; import com.gdx.game.manager.ResourceManager; import com.gdx.game.map.MapManager; diff --git a/core/src/main/java/com/gdx/game/battle/BattleInventoryUI.java b/core/src/main/java/com/gdx/game/battle/BattleInventoryUI.java index 8c531320..045ada38 100644 --- a/core/src/main/java/com/gdx/game/battle/BattleInventoryUI.java +++ b/core/src/main/java/com/gdx/game/battle/BattleInventoryUI.java @@ -8,10 +8,9 @@ import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop; import com.badlogic.gdx.utils.Array; -import com.gdx.game.entities.Entity; -import com.gdx.game.inventory.InventoryItem; -import com.gdx.game.inventory.InventoryItemFactory; -import com.gdx.game.inventory.InventoryItemLocation; +import com.gdx.game.inventory.item.InventoryItem; +import com.gdx.game.inventory.item.InventoryItemFactory; +import com.gdx.game.inventory.item.InventoryItemLocation; import com.gdx.game.inventory.InventoryObserver; import com.gdx.game.inventory.InventorySubject; import com.gdx.game.inventory.slot.InventorySlot; diff --git a/core/src/main/java/com/gdx/game/battle/BattleState.java b/core/src/main/java/com/gdx/game/battle/BattleState.java index c3145eb0..9233cb6b 100644 --- a/core/src/main/java/com/gdx/game/battle/BattleState.java +++ b/core/src/main/java/com/gdx/game/battle/BattleState.java @@ -10,6 +10,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +import static com.gdx.game.common.UtilityClass.calculateBonus; + public class BattleState extends BattleSubject { private static final Logger LOGGER = LoggerFactory.getLogger(BattleState.class); @@ -35,6 +41,8 @@ public BattleState() { currentPlayerAP = ProfileManager.getInstance().getProperty("currentPlayerAP", Integer.class); currentPlayerDP = ProfileManager.getInstance().getProperty("currentPlayerDP", Integer.class); + + updateStatWithBonus("bonusSet"); } public void resetDefaults() { @@ -82,6 +90,27 @@ public void determineTurn() { Timer.schedule(determineTurn, 1); } + private void updateStatWithBonus(String bonusAttribute) { + HashMap bonusMap = calculateBonus(bonusAttribute); + Map mapping = Map.of( + EntityConfig.EntityProperties.ENTITY_PHYSICAL_ATTACK_POINTS.name(), "currentPlayerAP", + EntityConfig.EntityProperties.ENTITY_PHYSICAL_DEFENSE_POINTS.name(), "currentPlayerDP" + ); + + mapping.forEach((key, value) -> { + if (bonusMap.get(key) != null) { + try { + Field valueField = this.getClass().getDeclaredField(value); + int currentPlayerValue = valueField.getInt(this); + int newPlayerValue = currentPlayerValue + bonusMap.get(key); + valueField.setInt(this, newPlayerValue); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("A value in the mapping map does not exist", e); + } + } + }); + } + public void playerAttacks() { if (currentOpponent == null) { return; diff --git a/core/src/main/java/com/gdx/game/common/UtilityClass.java b/core/src/main/java/com/gdx/game/common/UtilityClass.java index fc92c3eb..ef508bc6 100644 --- a/core/src/main/java/com/gdx/game/common/UtilityClass.java +++ b/core/src/main/java/com/gdx/game/common/UtilityClass.java @@ -1,8 +1,16 @@ package com.gdx.game.common; +import com.badlogic.gdx.utils.Array; +import com.gdx.game.entities.EntityBonus; +import com.gdx.game.entities.EntityConfig; +import com.gdx.game.profile.ProfileManager; + import java.util.HashMap; +import java.util.Hashtable; import java.util.Map; +import static java.lang.Float.parseFloat; + public class UtilityClass { public static HashMap mapInverter(HashMap hashMap){ @@ -27,4 +35,36 @@ public static Map mapInverter(Map hashMap){ return newMap; } + public static HashMap calculateBonus(String bonusProperty) { + final Hashtable attributeTable = new Hashtable<>() {{ + put(EntityConfig.EntityProperties.ENTITY_PHYSICAL_ATTACK_POINTS.name(), "currentPlayerAP"); + put(EntityConfig.EntityProperties.ENTITY_PHYSICAL_DEFENSE_POINTS.name(), "currentPlayerDP"); + }}; + + HashMap bonusStatMap = new HashMap<>(); + Array bonusArray = ProfileManager.getInstance().getProperty(bonusProperty, Array.class); + + if (bonusArray == null || bonusArray.isEmpty()) { + return bonusStatMap; + } + + HashMap bonusEntityValues = new HashMap<>(); + for (EntityBonus entityBonus : bonusArray) { + bonusEntityValues.put(entityBonus.getEntityProperty(), entityBonus.getValue()); + } + + for (String key : attributeTable.keySet()) { + float bonusValue = parseFloat(bonusEntityValues.get(key)); + if (bonusValue > 1) { + bonusStatMap.put(key, (int) bonusValue); + } else { + int playerStat = ProfileManager.getInstance().getProperty(attributeTable.get(key), Integer.class); + int bonusStat = (int) Math.floor(playerStat * bonusValue); + bonusStatMap.put(key, bonusStat); + } + } + + return bonusStatMap; + } + } diff --git a/core/src/main/java/com/gdx/game/entities/EntityBonus.java b/core/src/main/java/com/gdx/game/entities/EntityBonus.java new file mode 100644 index 00000000..3faaa0d1 --- /dev/null +++ b/core/src/main/java/com/gdx/game/entities/EntityBonus.java @@ -0,0 +1,31 @@ +package com.gdx.game.entities; + +public class EntityBonus { + + private String entityProperty; + private String value; + + public EntityBonus() { + } + + public EntityBonus(String entityProperty, String value) { + this.entityProperty = entityProperty; + this.value = value; + } + + public String getEntityProperty() { + return entityProperty; + } + + public void setEntityProperty(String entityProperty) { + this.entityProperty = entityProperty; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/core/src/main/java/com/gdx/game/entities/EntityConfig.java b/core/src/main/java/com/gdx/game/entities/EntityConfig.java index af9eaf6b..46120cd6 100644 --- a/core/src/main/java/com/gdx/game/entities/EntityConfig.java +++ b/core/src/main/java/com/gdx/game/entities/EntityConfig.java @@ -3,7 +3,7 @@ import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectMap; -import com.gdx.game.inventory.InventoryItem; +import com.gdx.game.inventory.item.InventoryItem; public class EntityConfig { private Array animationConfig; diff --git a/core/src/main/java/com/gdx/game/entities/player/PlayerHUD.java b/core/src/main/java/com/gdx/game/entities/player/PlayerHUD.java index ab72412c..261e1ef9 100644 --- a/core/src/main/java/com/gdx/game/entities/player/PlayerHUD.java +++ b/core/src/main/java/com/gdx/game/entities/player/PlayerHUD.java @@ -32,10 +32,11 @@ import com.gdx.game.entities.player.characterClass.ClassObserver; import com.gdx.game.entities.player.characterClass.tree.Node; import com.gdx.game.entities.player.characterClass.tree.Tree; -import com.gdx.game.inventory.InventoryItem; -import com.gdx.game.inventory.InventoryItemLocation; import com.gdx.game.inventory.InventoryObserver; import com.gdx.game.inventory.InventoryUI; +import com.gdx.game.inventory.item.InventoryItem; +import com.gdx.game.inventory.item.InventoryItemLocation; +import com.gdx.game.inventory.slot.InventorySlot; import com.gdx.game.inventory.store.StoreInventoryObserver; import com.gdx.game.inventory.store.StoreInventoryUI; import com.gdx.game.manager.ResourceManager; @@ -48,6 +49,9 @@ import com.gdx.game.status.StatusObserver; import com.gdx.game.status.StatusUI; +import static com.gdx.game.inventory.InventoryUI.getInventory; +import static com.gdx.game.inventory.InventoryUI.setBonusFromSet; + public class PlayerHUD implements Screen, AudioSubject, ProfileObserver, ClassObserver, ComponentObserver, ConversationGraphObserver, BattleObserver, StoreInventoryObserver, InventoryObserver, StatusObserver { private Stage stage; @@ -282,7 +286,7 @@ public void onNotify(ProfileManager profileManager, ProfileEvent event) { itemLocations.add(new InventoryItemLocation(i, items.get(i).toString(), 1, InventoryUI.PLAYER_INVENTORY)); } InventoryUI.populateInventory(inventoryUI.getInventorySlotTable(), itemLocations, inventoryUI.getDragAndDrop(), InventoryUI.PLAYER_INVENTORY, false); - profileManager.setProperty("playerInventory", InventoryUI.getInventory(inventoryUI.getInventorySlotTable())); + profileManager.setProperty("playerInventory", getInventory(inventoryUI.getInventorySlotTable())); //start the player with some money statusUI.setGoldValue(20); @@ -297,6 +301,9 @@ public void onNotify(ProfileManager profileManager, ProfileEvent event) { inventoryUI.resetEquipSlots(); if (equipInventory != null && equipInventory.size > 0) { InventoryUI.populateInventory(inventoryUI.getEquipSlotTable(), equipInventory, inventoryUI.getDragAndDrop(), InventoryUI.PLAYER_INVENTORY, false); + if (inventoryUI.isSetEquipped(equipInventory)) { + setBonusFromSet(((InventorySlot) inventoryUI.getEquipSlotTable().getCells().get(1).getActor()).getTopInventoryItem()); + } } Array quests = profileManager.getProperty("playerQuests", Array.class); @@ -329,8 +336,8 @@ public void onNotify(ProfileManager profileManager, ProfileEvent event) { } case SAVING_PROFILE -> { profileManager.setProperty("playerQuests", questUI.getQuests()); - profileManager.setProperty("playerInventory", InventoryUI.getInventory(inventoryUI.getInventorySlotTable())); - profileManager.setProperty("playerEquipInventory", InventoryUI.getInventory(inventoryUI.getEquipSlotTable())); + profileManager.setProperty("playerInventory", getInventory(inventoryUI.getInventorySlotTable())); + profileManager.setProperty("playerEquipInventory", getInventory(inventoryUI.getEquipSlotTable())); if (mapManager.getPlayer() != null) { profileManager.setProperty("playerCharacter", EntityFactory.EntityType.valueOf(mapManager.getPlayer().getEntityConfig().getEntityID())); } @@ -344,8 +351,6 @@ public void onNotify(ProfileManager profileManager, ProfileEvent event) { profileManager.setProperty("currentPlayerHPMax", statusUI.getHPValueMax()); profileManager.setProperty("currentPlayerMP", statusUI.getMPValue()); profileManager.setProperty("currentPlayerMPMax", statusUI.getMPValueMax()); - profileManager.setProperty("currentPlayerAP", inventoryUI.getAPVal()); - profileManager.setProperty("currentPlayerDP", inventoryUI.getDPVal()); profileManager.setProperty("currentPlayerSPDP", inventoryUI.getSPDPVal()); } case CLEAR_CURRENT_PROFILE -> { @@ -364,6 +369,7 @@ public void onNotify(ProfileManager profileManager, ProfileEvent event) { profileManager.setProperty("currentPlayerDP", 0); profileManager.setProperty("currentPlayerSPDP", 0); profileManager.setProperty("currentTime", 0); + profileManager.setProperty("bonusSet", null); } default -> { } @@ -421,7 +427,7 @@ public void onNotify(ConversationGraph graph, ConversationCommandEvent event) { break; } - Array inventory = InventoryUI.getInventory(inventoryUI.getInventorySlotTable()); + Array inventory = getInventory(inventoryUI.getInventorySlotTable()); storeInventoryUI.loadPlayerInventory(inventory); Array items = selectedEntity.getEntityConfig().getInventory(); diff --git a/core/src/main/java/com/gdx/game/entities/player/characterClass/tree/Tree.java b/core/src/main/java/com/gdx/game/entities/player/characterClass/tree/Tree.java index eae27891..c06f16be 100644 --- a/core/src/main/java/com/gdx/game/entities/player/characterClass/tree/Tree.java +++ b/core/src/main/java/com/gdx/game/entities/player/characterClass/tree/Tree.java @@ -2,6 +2,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.utils.Json; +import com.gdx.game.entities.EntityConfig; import com.gdx.game.profile.ProfileManager; import java.util.*; @@ -112,10 +113,10 @@ public Node checkForClassUpgrade(String currentClassId, int currentPlayerCharact List nodes = findToWhichClassesUpgrade(currentClassId); if (nodes != null && nodes.size() == 2) { - int AP0 = Integer.parseInt(nodes.get(0).getRequirements().get("ENTITY_PHYSICAL_ATTACK_POINTS")); - int DP0 = Integer.parseInt(nodes.get(0).getRequirements().get("ENTITY_PHYSICAL_DEFENSE_POINTS")); - int AP1 = Integer.parseInt(nodes.get(1).getRequirements().get("ENTITY_PHYSICAL_ATTACK_POINTS")); - int DP1 = Integer.parseInt(nodes.get(1).getRequirements().get("ENTITY_PHYSICAL_DEFENSE_POINTS")); + int AP0 = Integer.parseInt(nodes.get(0).getRequirements().get(EntityConfig.EntityProperties.ENTITY_PHYSICAL_ATTACK_POINTS.name())); + int DP0 = Integer.parseInt(nodes.get(0).getRequirements().get(EntityConfig.EntityProperties.ENTITY_PHYSICAL_DEFENSE_POINTS.name())); + int AP1 = Integer.parseInt(nodes.get(1).getRequirements().get(EntityConfig.EntityProperties.ENTITY_PHYSICAL_ATTACK_POINTS.name())); + int DP1 = Integer.parseInt(nodes.get(1).getRequirements().get(EntityConfig.EntityProperties.ENTITY_PHYSICAL_DEFENSE_POINTS.name())); if (currentPlayerCharacterAP >= AP0 && currentPlayerCharacterDP >= DP0) { return nodes.get(0); diff --git a/core/src/main/java/com/gdx/game/inventory/InventoryUI.java b/core/src/main/java/com/gdx/game/inventory/InventoryUI.java index fa48f3d9..92030d0b 100644 --- a/core/src/main/java/com/gdx/game/inventory/InventoryUI.java +++ b/core/src/main/java/com/gdx/game/inventory/InventoryUI.java @@ -12,7 +12,13 @@ import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Array; -import com.gdx.game.entities.Entity; +import com.gdx.game.entities.EntityBonus; +import com.gdx.game.entities.EntityConfig; +import com.gdx.game.inventory.item.InventoryItem; +import com.gdx.game.inventory.item.InventoryItemFactory; +import com.gdx.game.inventory.item.InventoryItemLocation; +import com.gdx.game.inventory.set.EquipmentSet; +import com.gdx.game.inventory.set.EquipmentSetFactory; import com.gdx.game.inventory.slot.InventorySlot; import com.gdx.game.inventory.slot.InventorySlotObserver; import com.gdx.game.inventory.slot.InventorySlotSource; @@ -22,6 +28,11 @@ import com.gdx.game.manager.ResourceManager; import com.gdx.game.profile.ProfileManager; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +import static com.gdx.game.common.UtilityClass.calculateBonus; import static com.gdx.game.component.Component.MESSAGE_TOKEN; import static com.gdx.game.manager.ResourceManager.ITEMS_TEXTURE_ATLAS; import static com.gdx.game.manager.ResourceManager.STATUS_UI_TEXTURE_ATLAS; @@ -39,6 +50,8 @@ public class InventoryUI extends Window implements InventorySubject, InventorySl private Label classValLabel; private String classVal; + private Label setValLabel; + private String setVal; private Label DPValLabel; private int DPVal; private Label APValLabel; @@ -80,6 +93,9 @@ public InventoryUI() { Label classLabel = new Label("Class: ", ResourceManager.skin); classValLabel = new Label(classVal, ResourceManager.skin); + Label setLabel = new Label("Set: ", ResourceManager.skin); + setValLabel = new Label(setVal, ResourceManager.skin); + Label DPLabel = new Label("Defense: ", ResourceManager.skin); DPValLabel = new Label(String.valueOf(DPVal), ResourceManager.skin); @@ -93,6 +109,10 @@ public InventoryUI() { labelTable.add(classLabel).align(Align.left); labelTable.add(classValLabel).align(Align.center); labelTable.row(); + labelTable.add(setLabel).align(Align.left); + labelTable.add(setValLabel).align(Align.center); + labelTable.row(); + labelTable.row(); labelTable.row(); labelTable.add(DPLabel).align(Align.left); labelTable.add(DPValLabel).align(Align.center); @@ -231,12 +251,14 @@ public void touchUp (InputEvent event, float x, float y, int pointer, int button } public void resetEquipSlots() { + ProfileManager.getInstance().setProperty("bonusSet", null); classVal = ProfileManager.getInstance().getProperty("characterClass", String.class); APVal = ProfileManager.getInstance().getProperty("currentPlayerCharacterAP", Integer.class); DPVal = ProfileManager.getInstance().getProperty("currentPlayerCharacterDP", Integer.class); SPDPVal = ProfileManager.getInstance().getProperty("currentPlayerCharacterSPDP", Integer.class); classValLabel.setText(String.valueOf(classVal)); + setValLabel.setText(""); DPValLabel.setText(String.valueOf(DPVal)); notify(String.valueOf(DPVal), InventoryObserver.InventoryEvent.UPDATED_DP); @@ -455,6 +477,65 @@ public Array getInventoryActors() { return inventoryActors; } + public boolean isSetEquipped(Array equipItems) { + if (equipItems.isEmpty() || equipItems.size != 5) { + return false; + } + + InventoryItem firstItem = InventoryItemFactory.getInstance().getInventoryItem(InventoryItem.ItemTypeID.valueOf(equipItems.get(0).getItemTypeAtLocation())); + String firstItemSetID = firstItem.getItemSetID().name(); + + for (int i = 1; i < equipItems.size - 1; i++) { + InventoryItem currentItem = InventoryItemFactory.getInstance().getInventoryItem(InventoryItem.ItemTypeID.valueOf(equipItems.get(i).getItemTypeAtLocation())); + String currentItemSetID = String.valueOf(currentItem.getItemSetID()); + if (!firstItemSetID.equals(currentItemSetID)) { + return false; + } + } + return true; + } + + public static void setBonusFromSet(InventoryItem item) { + EquipmentSet set = EquipmentSetFactory.getInstance().getEquipmentSet(item.getItemSetID()); + HashMap bonusMap = set.getBonus(); + Array bonusArray = new Array<>(); + + for (Map.Entry entry : bonusMap.entrySet()) { + EntityBonus entityBonus = new EntityBonus(entry.getKey(), entry.getValue()); + bonusArray.add(entityBonus); + } + + ProfileManager.getInstance().setProperty("bonusSet", bonusArray); + } + + private void updateValuesWithBonus(String bonusAttribute, boolean isAdd) { + HashMap bonusMap = calculateBonus(bonusAttribute); + + Map updates = Map.of( + EntityConfig.EntityProperties.ENTITY_PHYSICAL_ATTACK_POINTS.name(), new String[]{"APVal", "APValLabel"}, + EntityConfig.EntityProperties.ENTITY_PHYSICAL_DEFENSE_POINTS.name(), new String[]{"DPVal", "DPValLabel"} + ); + + updates.forEach((key, fields) -> { + Integer value = bonusMap.get(key); + if (value != null) { + try { + Field propertyField = this.getClass().getDeclaredField(fields[0]); + Field labelField = this.getClass().getDeclaredField(fields[1]); + + int currentValue = propertyField.getInt(this); + int newValue = isAdd ? currentValue + value : currentValue - value; + propertyField.setInt(this, newValue); + + Label label = (Label) labelField.get(this); + label.setText(String.valueOf(newValue)); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("A value in the update stat map does not exist", e); + } + } + }); + } + @Override public void onNotify(InventorySlot slot, SlotEvent event) { switch (event) { @@ -463,6 +544,13 @@ public void onNotify(InventorySlot slot, SlotEvent event) { if (addItem == null) { return; } + boolean isSetEquipped = isSetEquipped(getInventory(equipSlots)); + if (!isSetEquipped) { + setValLabel.setText(""); + updateValuesWithBonus("bonusSet", false); + ProfileManager.getInstance().setProperty("bonusSet", null); + } + if (addItem.isInventoryItemOffensive()) { APVal += addItem.getItemUseTypeValue(); APValLabel.setText(String.valueOf(APVal)); @@ -481,12 +569,21 @@ public void onNotify(InventorySlot slot, SlotEvent event) { ProfileManager.getInstance().setProperty("currentPlayerDP", DPVal); } + if (isSetEquipped) { + setVal = InventoryItemFactory.getInstance().getInventoryItem(InventoryItem.ItemTypeID.valueOf(getInventory(equipSlots).get(0).getItemTypeAtLocation())).getItemSetID().name(); + setValLabel.setText(setVal); + + setBonusFromSet(addItem); + updateValuesWithBonus("bonusSet", true); + } } case REMOVED_ITEM -> { InventoryItem removeItem = slot.getTopInventoryItem(); if (removeItem == null) { return; } + updateValuesWithBonus("bonusSet", false); + if (removeItem.isInventoryItemOffensive()) { APVal -= removeItem.getItemUseTypeValue(); APValLabel.setText(String.valueOf(APVal)); @@ -505,6 +602,8 @@ public void onNotify(InventorySlot slot, SlotEvent event) { ProfileManager.getInstance().setProperty("currentPlayerDP", DPVal); } + setValLabel.setText(""); + ProfileManager.getInstance().setProperty("bonusSet", null); } default -> { } diff --git a/core/src/main/java/com/gdx/game/inventory/InventoryItem.java b/core/src/main/java/com/gdx/game/inventory/item/InventoryItem.java similarity index 95% rename from core/src/main/java/com/gdx/game/inventory/InventoryItem.java rename to core/src/main/java/com/gdx/game/inventory/item/InventoryItem.java index abb061cb..f2208b4c 100644 --- a/core/src/main/java/com/gdx/game/inventory/InventoryItem.java +++ b/core/src/main/java/com/gdx/game/inventory/item/InventoryItem.java @@ -1,4 +1,4 @@ -package com.gdx.game.inventory; +package com.gdx.game.inventory.item; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.TextureRegion; @@ -87,11 +87,16 @@ public Color getColor() { } } + public enum ItemSetID { + PEASANT_SET + } + private int itemAttributes; private int itemUseType; private int itemUseTypeValue; private ItemTypeID itemTypeID; private ItemRarity itemRarity; + private ItemSetID itemSetID; private String itemShortDescription; private int itemValue; @@ -116,6 +121,7 @@ public InventoryItem(InventoryItem inventoryItem) { this.itemUseType = inventoryItem.getItemUseType(); this.itemUseTypeValue = inventoryItem.getItemUseTypeValue(); this.itemRarity = inventoryItem.getItemRarity(); + this.itemSetID = inventoryItem.getItemSetID(); this.itemShortDescription = inventoryItem.getItemShortDescription(); this.itemValue = inventoryItem.getItemValue(); } @@ -168,6 +174,14 @@ public void setItemRarity(ItemRarity itemRarity) { this.itemRarity = itemRarity; } + public ItemSetID getItemSetID() { + return itemSetID; + } + + public void setItemSetID(ItemSetID itemSetID) { + this.itemSetID = itemSetID; + } + public String getItemShortDescription() { return itemShortDescription; } diff --git a/core/src/main/java/com/gdx/game/inventory/InventoryItemFactory.java b/core/src/main/java/com/gdx/game/inventory/item/InventoryItemFactory.java similarity index 95% rename from core/src/main/java/com/gdx/game/inventory/InventoryItemFactory.java rename to core/src/main/java/com/gdx/game/inventory/item/InventoryItemFactory.java index 439c82e6..c13d23b7 100644 --- a/core/src/main/java/com/gdx/game/inventory/InventoryItemFactory.java +++ b/core/src/main/java/com/gdx/game/inventory/item/InventoryItemFactory.java @@ -1,4 +1,4 @@ -package com.gdx.game.inventory; +package com.gdx.game.inventory.item; import com.badlogic.gdx.Gdx; @@ -6,7 +6,7 @@ import com.badlogic.gdx.utils.Json; import com.badlogic.gdx.utils.JsonValue; import com.badlogic.gdx.utils.Scaling; -import com.gdx.game.inventory.InventoryItem.ItemTypeID; +import com.gdx.game.inventory.item.InventoryItem.ItemTypeID; import java.util.ArrayList; import java.util.Hashtable; diff --git a/core/src/main/java/com/gdx/game/inventory/InventoryItemLocation.java b/core/src/main/java/com/gdx/game/inventory/item/InventoryItemLocation.java similarity index 97% rename from core/src/main/java/com/gdx/game/inventory/InventoryItemLocation.java rename to core/src/main/java/com/gdx/game/inventory/item/InventoryItemLocation.java index d7573376..cf95af98 100644 --- a/core/src/main/java/com/gdx/game/inventory/InventoryItemLocation.java +++ b/core/src/main/java/com/gdx/game/inventory/item/InventoryItemLocation.java @@ -1,4 +1,4 @@ -package com.gdx.game.inventory; +package com.gdx.game.inventory.item; public class InventoryItemLocation { private int locationIndex; diff --git a/core/src/main/java/com/gdx/game/inventory/set/EquipmentSet.java b/core/src/main/java/com/gdx/game/inventory/set/EquipmentSet.java new file mode 100644 index 00000000..c4f07107 --- /dev/null +++ b/core/src/main/java/com/gdx/game/inventory/set/EquipmentSet.java @@ -0,0 +1,45 @@ +package com.gdx.game.inventory.set; + +import com.gdx.game.inventory.item.InventoryItem; + +import java.util.HashMap; + +public class EquipmentSet { + + private InventoryItem.ItemSetID itemSetID; + private String itemSetDescription; + private HashMap bonus = new HashMap<>(); + + public EquipmentSet() { + } + + public EquipmentSet(EquipmentSet equipmentSet) { + this.itemSetID = equipmentSet.getItemSetID(); + this.itemSetDescription = equipmentSet.getItemSetDescription(); + this.bonus = equipmentSet.getBonus(); + } + + public InventoryItem.ItemSetID getItemSetID() { + return itemSetID; + } + + public void setItemSetID(InventoryItem.ItemSetID itemSetID) { + this.itemSetID = itemSetID; + } + + public String getItemSetDescription() { + return itemSetDescription; + } + + public void setItemSetDescription(String itemSetDescription) { + this.itemSetDescription = itemSetDescription; + } + + public HashMap getBonus() { + return bonus; + } + + public void setBonus(HashMap bonus) { + this.bonus = bonus; + } +} diff --git a/core/src/main/java/com/gdx/game/inventory/set/EquipmentSetFactory.java b/core/src/main/java/com/gdx/game/inventory/set/EquipmentSetFactory.java new file mode 100644 index 00000000..168157ad --- /dev/null +++ b/core/src/main/java/com/gdx/game/inventory/set/EquipmentSetFactory.java @@ -0,0 +1,39 @@ +package com.gdx.game.inventory.set; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.utils.Json; +import com.badlogic.gdx.utils.JsonValue; +import com.gdx.game.inventory.item.InventoryItem; + +import java.util.ArrayList; +import java.util.Hashtable; + +public class EquipmentSetFactory { + + private Json json = new Json(); + private static final String ITEM_SET = "scripts/equipment_sets.json"; + private static EquipmentSetFactory instance = null; + private Hashtable equipSetList; + + public static EquipmentSetFactory getInstance() { + if (instance == null) { + instance = new EquipmentSetFactory(); + } + + return instance; + } + + private EquipmentSetFactory() { + ArrayList list = json.fromJson(ArrayList.class, Gdx.files.internal(ITEM_SET)); + equipSetList = new Hashtable<>(); + + for(JsonValue jsonVal : list) { + EquipmentSet equipSet = json.readValue(EquipmentSet.class, jsonVal); + equipSetList.put(equipSet.getItemSetID(), equipSet); + } + } + + public EquipmentSet getEquipmentSet(InventoryItem.ItemSetID equipmentType) { + return new EquipmentSet(equipSetList.get(equipmentType)); + } +} diff --git a/core/src/main/java/com/gdx/game/inventory/slot/InventorySlot.java b/core/src/main/java/com/gdx/game/inventory/slot/InventorySlot.java index c55c1650..6822fae6 100644 --- a/core/src/main/java/com/gdx/game/inventory/slot/InventorySlot.java +++ b/core/src/main/java/com/gdx/game/inventory/slot/InventorySlot.java @@ -8,7 +8,7 @@ import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.SnapshotArray; -import com.gdx.game.inventory.InventoryItem; +import com.gdx.game.inventory.item.InventoryItem; import static com.gdx.game.manager.ResourceManager.STATUS_UI_SKIN; import static com.gdx.game.manager.ResourceManager.STATUS_UI_TEXTURE_ATLAS; diff --git a/core/src/main/java/com/gdx/game/inventory/slot/InventorySlotSource.java b/core/src/main/java/com/gdx/game/inventory/slot/InventorySlotSource.java index 5497f019..870cbfe0 100644 --- a/core/src/main/java/com/gdx/game/inventory/slot/InventorySlotSource.java +++ b/core/src/main/java/com/gdx/game/inventory/slot/InventorySlotSource.java @@ -2,11 +2,14 @@ import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop; import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Payload; import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Source; import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Target; +import static com.gdx.game.inventory.InventoryUI.getInventory; + public class InventorySlotSource extends Source { private DragAndDrop dragAndDrop; @@ -34,13 +37,13 @@ public Payload dragStart(InputEvent event, float x, float y, int pointer) { sourceSlot = source; } - sourceSlot.decrementItemCount(true); + sourceSlot.decrementItemCount(true); - payload.setDragActor(getActor()); - dragAndDrop.setDragActorPosition(-x, -y + getActor().getHeight()); + payload.setDragActor(getActor()); + dragAndDrop.setDragActorPosition(-x, -y + getActor().getHeight()); - return payload; -} + return payload; + } @Override public void dragStop (InputEvent event, float x, float y, int pointer, Payload payload, Target target) { diff --git a/core/src/main/java/com/gdx/game/inventory/slot/InventorySlotTarget.java b/core/src/main/java/com/gdx/game/inventory/slot/InventorySlotTarget.java index da565b01..1a7d43e8 100644 --- a/core/src/main/java/com/gdx/game/inventory/slot/InventorySlotTarget.java +++ b/core/src/main/java/com/gdx/game/inventory/slot/InventorySlotTarget.java @@ -3,7 +3,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Payload; import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Source; import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Target; -import com.gdx.game.inventory.InventoryItem; +import com.gdx.game.inventory.item.InventoryItem; public class InventorySlotTarget extends Target { diff --git a/core/src/main/java/com/gdx/game/inventory/slot/InventorySlotTooltip.java b/core/src/main/java/com/gdx/game/inventory/slot/InventorySlotTooltip.java index 3b9b165b..81744938 100644 --- a/core/src/main/java/com/gdx/game/inventory/slot/InventorySlotTooltip.java +++ b/core/src/main/java/com/gdx/game/inventory/slot/InventorySlotTooltip.java @@ -3,7 +3,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.ui.Window; -import com.gdx.game.inventory.InventoryItem; +import com.gdx.game.inventory.item.InventoryItem; public class InventorySlotTooltip extends Window { diff --git a/core/src/main/java/com/gdx/game/inventory/store/StoreInventoryUI.java b/core/src/main/java/com/gdx/game/inventory/store/StoreInventoryUI.java index eb1d6ff7..1844ebf9 100644 --- a/core/src/main/java/com/gdx/game/inventory/store/StoreInventoryUI.java +++ b/core/src/main/java/com/gdx/game/inventory/store/StoreInventoryUI.java @@ -14,7 +14,7 @@ import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Json; -import com.gdx.game.inventory.InventoryItemLocation; +import com.gdx.game.inventory.item.InventoryItemLocation; import com.gdx.game.inventory.slot.InventorySlot; import com.gdx.game.inventory.slot.InventorySlotObserver; import com.gdx.game.inventory.slot.InventorySlotTarget; diff --git a/core/src/main/java/com/gdx/game/screen/BattleScreen.java b/core/src/main/java/com/gdx/game/screen/BattleScreen.java index 8f80d17c..963841c0 100644 --- a/core/src/main/java/com/gdx/game/screen/BattleScreen.java +++ b/core/src/main/java/com/gdx/game/screen/BattleScreen.java @@ -14,7 +14,7 @@ import com.gdx.game.battle.BattleState; import com.gdx.game.entities.Entity; import com.gdx.game.entities.player.PlayerHUD; -import com.gdx.game.inventory.InventoryItemLocation; +import com.gdx.game.inventory.item.InventoryItemLocation; import com.gdx.game.inventory.InventoryObserver; import com.gdx.game.inventory.InventoryUI; import com.gdx.game.manager.ResourceManager; diff --git a/core/src/main/resources/scripts/equipment_sets.json b/core/src/main/resources/scripts/equipment_sets.json new file mode 100644 index 00000000..9b492b7c --- /dev/null +++ b/core/src/main/resources/scripts/equipment_sets.json @@ -0,0 +1,16 @@ +[ + { + itemSetID: PEASANT_SET + itemSetDescription: Increase physical attack by 10% + bonus: { + ENTITY_PHYSICAL_ATTACK_POINTS: { + class: java.lang.String + value: 0.1 + } + ENTITY_PHYSICAL_DEFENSE_POINTS: { + class: java.lang.String + value: 0.1 + } + } + } +] \ No newline at end of file diff --git a/core/src/main/resources/scripts/inventory_items.json b/core/src/main/resources/scripts/inventory_items.json index fd9b9cd8..5937b238 100644 --- a/core/src/main/resources/scripts/inventory_items.json +++ b/core/src/main/resources/scripts/inventory_items.json @@ -14,6 +14,7 @@ itemUseTypeValue: 10 itemTypeID: SHIELD02 itemRarity: COMMON + itemSetID: PEASANT_SET itemShortDescription: A wooden shield fit for a peasant itemValue: 25 }, @@ -77,6 +78,7 @@ itemUseTypeValue: 10 itemTypeID: ARMOR04 itemRarity: COMMON + itemSetID: PEASANT_SET itemShortDescription: Broken mail armor fit for a peasant itemValue: 25 }, @@ -113,6 +115,7 @@ itemUseTypeValue: 10 itemTypeID: BOOTS03 itemRarity: COMMON + itemSetID: PEASANT_SET itemShortDescription: Leather boots fit for a peasant itemValue: 25 }, @@ -176,6 +179,7 @@ itemUseTypeValue: 10 itemTypeID: HELMET05 itemRarity: COMMON + itemSetID: PEASANT_SET itemShortDescription: A leather helmet fit for a peasant itemValue: 25 }, @@ -230,6 +234,7 @@ itemUseTypeValue: 10 itemTypeID: WEAPON01 itemRarity: COMMON + itemSetID: PEASANT_SET itemShortDescription: A copper sword of a peasant itemValue: 25 }, diff --git a/core/src/test/java/com/gdx/game/battle/BattleHUDTest.java b/core/src/test/java/com/gdx/game/battle/BattleHUDTest.java index ef8ea36c..f847fbb5 100644 --- a/core/src/test/java/com/gdx/game/battle/BattleHUDTest.java +++ b/core/src/test/java/com/gdx/game/battle/BattleHUDTest.java @@ -11,11 +11,12 @@ import com.gdx.game.GdxRunner; import com.gdx.game.animation.AnimatedImage; import com.gdx.game.entities.Entity; +import com.gdx.game.entities.EntityBonus; import com.gdx.game.entities.EntityConfig; import com.gdx.game.entities.EntityFactory; -import com.gdx.game.inventory.InventoryItem; -import com.gdx.game.inventory.InventoryItemFactory; -import com.gdx.game.inventory.InventoryItemLocation; +import com.gdx.game.inventory.item.InventoryItem; +import com.gdx.game.inventory.item.InventoryItemFactory; +import com.gdx.game.inventory.item.InventoryItemLocation; import com.gdx.game.inventory.InventoryObserver; import com.gdx.game.manager.ResourceManager; import com.gdx.game.map.MapManager; @@ -68,6 +69,9 @@ void init() { profileManager.setProperty("currentPlayerCharacterAP", 5); profileManager.setProperty("currentPlayerCharacterDP", 5); profileManager.setProperty("currentPlayerCharacterSPDP", 10); + EntityBonus entityBonusAtk = new EntityBonus(EntityConfig.EntityProperties.ENTITY_PHYSICAL_ATTACK_POINTS.name(), "0.3"); + EntityBonus entityBonusDef = new EntityBonus(EntityConfig.EntityProperties.ENTITY_PHYSICAL_DEFENSE_POINTS.name(), "0.1"); + profileManager.setProperty("bonusSet", new Array<>(new EntityBonus[]{entityBonusAtk, entityBonusDef})); new ResourceManager(); } diff --git a/core/src/test/java/com/gdx/game/battle/BattleStateTest.java b/core/src/test/java/com/gdx/game/battle/BattleStateTest.java index 0be97b4f..ad0f8a7e 100644 --- a/core/src/test/java/com/gdx/game/battle/BattleStateTest.java +++ b/core/src/test/java/com/gdx/game/battle/BattleStateTest.java @@ -2,8 +2,10 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.utils.Array; import com.gdx.game.GdxRunner; import com.gdx.game.entities.Entity; +import com.gdx.game.entities.EntityBonus; import com.gdx.game.entities.EntityConfig; import com.gdx.game.entities.EntityFactory; import com.gdx.game.entities.npc.NPCGraphicsComponent; @@ -47,6 +49,9 @@ void init() { profileManager.setProperty("currentPlayerDP", 5); profileManager.setProperty("currentPlayerMP", 5); profileManager.setProperty("currentPlayerHP", 20); + EntityBonus entityBonusAtk = new EntityBonus(EntityConfig.EntityProperties.ENTITY_PHYSICAL_ATTACK_POINTS.name(), "0.3"); + EntityBonus entityBonusDef = new EntityBonus(EntityConfig.EntityProperties.ENTITY_PHYSICAL_DEFENSE_POINTS.name(), "0.1"); + profileManager.setProperty("bonusSet", new Array<>(new EntityBonus[]{entityBonusAtk, entityBonusDef})); } @AfterEach @@ -67,7 +72,7 @@ void playerAttack_doNotKill() { battleState.getPlayerAttackCalculationTimer().run(); - assertThat(enemy.getEntityConfig().getPropertyValue(EntityConfig.EntityProperties.ENTITY_HEALTH_POINTS.toString())).isLessThanOrEqualTo("19"); + assertThat(enemy.getEntityConfig().getPropertyValue(EntityConfig.EntityProperties.ENTITY_HEALTH_POINTS.toString())).isLessThanOrEqualTo("18"); verify(battleState).notify(enemy, BattleObserver.BattleEvent.OPPONENT_HIT_DAMAGE); verify(battleState).notify(enemy, BattleObserver.BattleEvent.PLAYER_TURN_DONE); verify(battleState, never()).notify(enemy, BattleObserver.BattleEvent.OPPONENT_DEFEATED); @@ -108,7 +113,7 @@ void opponentAttack() { battleState.getOpponentAttackCalculationTimer().run(); - assertThat(player.getEntityConfig().getPropertyValue(EntityConfig.EntityProperties.ENTITY_HEALTH_POINTS.toString())).isLessThanOrEqualTo("19"); + assertThat(player.getEntityConfig().getPropertyValue(EntityConfig.EntityProperties.ENTITY_HEALTH_POINTS.toString())).isLessThanOrEqualTo("18"); verify(battleState).notify(player, BattleObserver.BattleEvent.PLAYER_HIT_DAMAGE); verify(battleState).notify(enemy, BattleObserver.BattleEvent.OPPONENT_TURN_DONE); } diff --git a/core/src/test/java/com/gdx/game/battle/BattleUITest.java b/core/src/test/java/com/gdx/game/battle/BattleUITest.java index a9aa8b18..f7cbcac4 100644 --- a/core/src/test/java/com/gdx/game/battle/BattleUITest.java +++ b/core/src/test/java/com/gdx/game/battle/BattleUITest.java @@ -2,7 +2,10 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.utils.Array; import com.gdx.game.GdxRunner; +import com.gdx.game.entities.EntityBonus; +import com.gdx.game.entities.EntityConfig; import com.gdx.game.manager.ResourceManager; import com.gdx.game.profile.ProfileManager; import org.junit.jupiter.api.BeforeEach; @@ -27,6 +30,9 @@ public void testBattleUI_ShouldSucceed() { ProfileManager profileManager = ProfileManager.getInstance(); profileManager.setProperty("currentPlayerAP", 5); profileManager.setProperty("currentPlayerDP", 5); + EntityBonus entityBonusAtk = new EntityBonus(EntityConfig.EntityProperties.ENTITY_PHYSICAL_ATTACK_POINTS.name(), "0.3"); + EntityBonus entityBonusDef = new EntityBonus(EntityConfig.EntityProperties.ENTITY_PHYSICAL_DEFENSE_POINTS.name(), "0.1"); + profileManager.setProperty("bonusSet", new Array<>(new EntityBonus[]{entityBonusAtk, entityBonusDef})); BattleState battleState = new BattleState(); BattleInventoryUI battleInventoryUI = new BattleInventoryUI(); diff --git a/core/src/test/java/com/gdx/game/entities/player/PlayerHUDTest.java b/core/src/test/java/com/gdx/game/entities/player/PlayerHUDTest.java index b83e5eba..0e6dc0e0 100644 --- a/core/src/test/java/com/gdx/game/entities/player/PlayerHUDTest.java +++ b/core/src/test/java/com/gdx/game/entities/player/PlayerHUDTest.java @@ -16,8 +16,8 @@ import com.gdx.game.entities.Entity; import com.gdx.game.entities.EntityFactory; import com.gdx.game.entities.player.characterClass.ClassObserver; -import com.gdx.game.inventory.InventoryItem; -import com.gdx.game.inventory.InventoryItemFactory; +import com.gdx.game.inventory.item.InventoryItem; +import com.gdx.game.inventory.item.InventoryItemFactory; import com.gdx.game.inventory.InventoryObserver; import com.gdx.game.inventory.store.StoreInventoryObserver; import com.gdx.game.manager.ResourceManager; diff --git a/core/src/test/java/com/gdx/game/inventory/InventoryItemFactoryTest.java b/core/src/test/java/com/gdx/game/inventory/InventoryItemFactoryTest.java index a7d5d449..da7502ef 100644 --- a/core/src/test/java/com/gdx/game/inventory/InventoryItemFactoryTest.java +++ b/core/src/test/java/com/gdx/game/inventory/InventoryItemFactoryTest.java @@ -3,8 +3,8 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; import com.gdx.game.GdxRunner; -import com.gdx.game.inventory.InventoryItem; -import com.gdx.game.inventory.InventoryItemFactory; +import com.gdx.game.inventory.item.InventoryItem; +import com.gdx.game.inventory.item.InventoryItemFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/core/src/test/java/com/gdx/game/inventory/InventoryItemLocationTest.java b/core/src/test/java/com/gdx/game/inventory/InventoryItemLocationTest.java index 4f39311d..6dd1b2e8 100644 --- a/core/src/test/java/com/gdx/game/inventory/InventoryItemLocationTest.java +++ b/core/src/test/java/com/gdx/game/inventory/InventoryItemLocationTest.java @@ -3,7 +3,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; import com.gdx.game.GdxRunner; -import com.gdx.game.inventory.InventoryItemLocation; +import com.gdx.game.inventory.item.InventoryItemLocation; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/core/src/test/java/com/gdx/game/inventory/InventoryItemTest.java b/core/src/test/java/com/gdx/game/inventory/InventoryItemTest.java index 99358d75..b4503093 100644 --- a/core/src/test/java/com/gdx/game/inventory/InventoryItemTest.java +++ b/core/src/test/java/com/gdx/game/inventory/InventoryItemTest.java @@ -3,8 +3,8 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; import com.gdx.game.GdxRunner; -import com.gdx.game.inventory.InventoryItem; -import com.gdx.game.inventory.InventoryItemFactory; +import com.gdx.game.inventory.item.InventoryItem; +import com.gdx.game.inventory.item.InventoryItemFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/core/src/test/java/com/gdx/game/inventory/InventoryUITest.java b/core/src/test/java/com/gdx/game/inventory/InventoryUITest.java index 98818eca..4782519e 100644 --- a/core/src/test/java/com/gdx/game/inventory/InventoryUITest.java +++ b/core/src/test/java/com/gdx/game/inventory/InventoryUITest.java @@ -2,36 +2,177 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.utils.Array; import com.gdx.game.GdxRunner; +import com.gdx.game.entities.EntityConfig; +import com.gdx.game.entities.EntityFactory; +import com.gdx.game.inventory.item.InventoryItem; +import com.gdx.game.inventory.item.InventoryItemLocation; +import com.gdx.game.inventory.slot.InventorySlot; +import com.gdx.game.inventory.slot.InventorySlotObserver; import com.gdx.game.manager.ResourceManager; import com.gdx.game.profile.ProfileManager; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.MockedConstruction; +import java.util.HashMap; +import java.util.stream.Stream; + +import static com.gdx.game.common.UtilityClass.calculateBonus; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; @ExtendWith(GdxRunner.class) public class InventoryUITest { + private MockedConstruction mockShapeRenderer; + private MockedConstruction mockSpriteBatch; + + private static final int PLAYER_AP = 15; + private static final int PLAYER_DP = 15; + @BeforeEach void init() { Gdx.gl = mock(GL20.class); Gdx.gl20 = mock(GL20.class); + mockShapeRenderer = mockConstruction(ShapeRenderer.class); + mockSpriteBatch = mockConstruction(SpriteBatch.class); new ResourceManager(); + ProfileManager profileManager = ProfileManager.getInstance(); + profileManager.setProperty("playerCharacter", EntityFactory.EntityType.WARRIOR); + profileManager.setProperty("currentPlayerCharacterAP", PLAYER_AP); + profileManager.setProperty("currentPlayerCharacterDP", PLAYER_DP); + profileManager.setProperty("currentPlayerCharacterSPDP", 10); + } + + @AfterEach + void end() { + mockShapeRenderer.close(); + mockSpriteBatch.close(); } @Test public void testInventoryUI_ShouldSucceed() { - ProfileManager profileManager = ProfileManager.getInstance(); - profileManager.setProperty("currentPlayerCharacterAP", 5); - profileManager.setProperty("currentPlayerCharacterDP", 5); - profileManager.setProperty("currentPlayerCharacterSPDP", 5); - InventoryUI inventoryUI = new InventoryUI(); assertThat(inventoryUI).isNotNull(); assertThat(inventoryUI.getDragAndDrop()).isNotNull(); } + + @ParameterizedTest + @MethodSource("itemEventData") + public void add_item_event(InventoryItem item, int playerStat, String profileSave, InventoryObserver.InventoryEvent inventoryEvent) { + InventorySlot inventorySlot = new InventorySlot(); + inventorySlot.add(item); + + InventoryUI inventoryUI = spy(new InventoryUI()); + Table equipSlotTable = inventoryUI.getEquipSlotTable(); + inventoryUI.onNotify(inventorySlot, InventorySlotObserver.SlotEvent.ADDED_ITEM); + + verify(inventoryUI, times(1)).notify(String.valueOf(playerStat + item.getItemUseTypeValue()), inventoryEvent); + assertEquals(playerStat + item.getItemUseTypeValue(), ProfileManager.getInstance().getProperty(profileSave, Integer.class)); + verify(inventoryUI, times(1)).isSetEquipped(InventoryUI.getInventory(equipSlotTable)); + } + + @ParameterizedTest + @MethodSource("itemEventData") + public void remove_item_event(InventoryItem item, int playerStat, String profileSave, InventoryObserver.InventoryEvent inventoryEvent) { + InventorySlot inventorySlot = new InventorySlot(); + inventorySlot.add(item); + + InventoryUI inventoryUI = spy(new InventoryUI()); + inventoryUI.onNotify(inventorySlot, InventorySlotObserver.SlotEvent.REMOVED_ITEM); + + verify(inventoryUI, times(1)).notify(String.valueOf(playerStat - item.getItemUseTypeValue()), inventoryEvent); + assertEquals(playerStat - item.getItemUseTypeValue(), ProfileManager.getInstance().getProperty(profileSave, Integer.class)); + } + + private static Stream itemEventData() { + return Stream.of( + Arguments.of(getInventoryItem(8), PLAYER_AP, "currentPlayerAP", InventoryObserver.InventoryEvent.UPDATED_AP), + Arguments.of(getInventoryItem(128), PLAYER_DP, "currentPlayerDP", InventoryObserver.InventoryEvent.UPDATED_DP) + ); + } + + private static InventoryItem getInventoryItem(int itemUseType) { + InventoryItem item = new InventoryItem(); + item.setItemAttributes(2); + item.setItemUseType(itemUseType); + item.setItemUseTypeValue(10); + item.setItemTypeID(InventoryItem.ItemTypeID.WEAPON01); + item.setItemSetID(InventoryItem.ItemSetID.PEASANT_SET); + return item; + } + + @ParameterizedTest + @MethodSource("itemSetData") + public void should_return_if_set_equipped(Array equipSlots, boolean expectedResult) { + InventoryUI inventoryUI = new InventoryUI(); + boolean result = inventoryUI.isSetEquipped(equipSlots); + + assertEquals(expectedResult, result); + } + + private static Stream itemSetData() { + return Stream.of( + Arguments.of(getInventoryItemLocations(), true), + Arguments.of(getInventoryItemLocationsWithoutHelmet(), false), + Arguments.of(getInventoryItemLocationsWithDifferentHelmet(), false) + ); + } + + private static Array getInventoryItemLocations() { + InventoryItemLocation itemHelmet = new InventoryItemLocation(1, "HELMET05", 1, "Player_Inventory"); + InventoryItemLocation itemWeapon = new InventoryItemLocation(2, "WEAPON01", 1, "Player_Inventory"); + InventoryItemLocation itemArmor = new InventoryItemLocation(3, "ARMOR04", 1, "Player_Inventory"); + InventoryItemLocation itemShield = new InventoryItemLocation(4, "SHIELD02", 1, "Player_Inventory"); + InventoryItemLocation itemBoots = new InventoryItemLocation(5, "BOOTS03", 1, "Player_Inventory"); + + Array equipSlots = new Array<>(); + equipSlots.add(itemHelmet); + equipSlots.add(itemWeapon); + equipSlots.add(itemArmor); + equipSlots.add(itemShield); + equipSlots.add(itemBoots); + return equipSlots; + } + + private static Array getInventoryItemLocationsWithoutHelmet() { + Array equipSlots = getInventoryItemLocations(); + equipSlots.removeIndex(0); + return equipSlots; + } + + private static Array getInventoryItemLocationsWithDifferentHelmet() { + Array equipSlots = getInventoryItemLocations(); + InventoryItemLocation itemHelmet = new InventoryItemLocation(1, "HELMET03", 1, "Player_Inventory"); + equipSlots.add(itemHelmet); + return equipSlots; + } + + @Test + public void should_calculate_bonus_from_set() { + ProfileManager.getInstance().setProperty("currentPlayerAP", 10); + ProfileManager.getInstance().setProperty("currentPlayerDP", 25); + InventoryUI.setBonusFromSet(getInventoryItem(8)); + + HashMap bonusMap = calculateBonus("bonusSet"); + + assertEquals(1, bonusMap.get(EntityConfig.EntityProperties.ENTITY_PHYSICAL_ATTACK_POINTS.name())); + assertEquals(2, bonusMap.get(EntityConfig.EntityProperties.ENTITY_PHYSICAL_DEFENSE_POINTS.name())); + } }