package engine.gameManager; import engine.loot.WorkOrder; import engine.mbEnums; import engine.objects.*; import engine.powers.EffectsBase; import org.pmw.tinylog.Logger; import java.util.EnumSet; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; // • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2022 // www.magicbane.com public enum ItemManager { ITEMMANAGER; public static final AtomicInteger lastNegativeID = new AtomicInteger(0); public static Boolean ValidRace(Item item, mbEnums.MonsterType race) { if (item.template.item_race_req.isEmpty() && item.template.item_race_res.isEmpty()) return true; if (item.template.item_race_req.isEmpty() == false) if (item.template.item_race_req.contains(race)) return true; if (item.template.item_race_res.isEmpty() == false) if (item.template.item_race_res.contains(race) == false) return true; return false; } public static Boolean ValidClass(Item item, mbEnums.ClassType base, mbEnums.ClassType profession) { // Early exit if no entry if (item.template.item_class_req.isEmpty() && item.template.item_class_res.isEmpty()) return true; if (item.template.item_class_req.isEmpty() == false) if (item.template.item_class_req.contains(base) || item.template.item_class_req.contains(profession)) return true; if (item.template.item_class_res.isEmpty() == false) if (item.template.item_class_res.contains(base) == false && item.template.item_class_res.contains(profession) == false) return true; return false; } public static Boolean ValidDiscipline(Item item, EnumSet discs) { // Early exit if no entry if (item.template.item_disc_req.isEmpty() && item.template.item_disc_res.isEmpty()) return true; EnumSet workSet = EnumSet.copyOf(discs); if (item.template.item_disc_req.isEmpty() == false) { workSet.retainAll(item.template.item_disc_req); if (workSet.isEmpty() == false) return true; } if (item.template.item_disc_res.isEmpty() == false) { workSet.retainAll(item.template.item_disc_res); if (workSet.isEmpty() == false) return true; } return false; } public static Boolean canCharacterEquip(Item item, AbstractCharacter character) { return ValidRace(item, character.absRace) && ValidClass(item, character.absBaseClass, character.absPromotionClass) && ValidDiscipline(item, character.absDisciplines); } public static boolean validForSkills(Item item, ConcurrentHashMap skills) { CharacterSkill characterSkill; if (item.template.item_skill_required.isEmpty()) return true; for (String skillRequired : item.template.item_skill_required.keySet()) { int required_value = item.template.item_skill_required.get(skillRequired); characterSkill = skills.get(skillRequired); if (characterSkill == null) return false; if (characterSkill.getModifiedAmountBeforeMods() > required_value) return true; } return false; } public static boolean isTwoHanded(Item item) { if (!item.template.item_type.equals(mbEnums.ItemType.WEAPON)) return false; return item.template.item_eq_slots_and.contains(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD)); } public static boolean isTwoHanded(ItemTemplate template) { if (!template.item_type.equals(mbEnums.ItemType.WEAPON)) return false; return template.item_eq_slots_and.contains(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD)); } public static boolean isShield(Item item) { if (item.template.item_skill_required.containsKey("Block")) return true; return false; } public static boolean isShield(ItemTemplate template) { if (template.item_skill_required.containsKey("Block")) return true; return false; } public static boolean validForSlot(mbEnums.EquipSlotType slot, ConcurrentHashMap equipped, Item item) { boolean validSlot = false; if (equipped == null) return false; //Item not valid for slot if (item.template.item_eq_slots_or.contains(slot) == false) return false; // Slot is taken if (equipped.get(slot) != null && equipped.get(slot).equals(item) == false) return false; // Two handed weapons take up two slots if ((isTwoHanded(item)) && ((slot == mbEnums.EquipSlotType.LHELD && equipped.get(mbEnums.EquipSlotType.RHELD) != null) || (slot == mbEnums.EquipSlotType.RHELD && equipped.get(mbEnums.EquipSlotType.LHELD) != null))) return false; if (item.template.item_type.equals(mbEnums.ItemType.WEAPON)) if (equipped.get(slot) != null && equipped.get(slot).equals(item) == false) return false; return true; } public static boolean canEquip(mbEnums.EquipSlotType slot, CharacterItemManager itemManager, AbstractCharacter abstractCharacter, Item item) { if (itemManager == null || abstractCharacter == null) return false; // Early exit for mobiles and NPCS. // Perhaps not needed now that mobs have skills. if (EnumSet.of(mbEnums.GameObjectType.NPC, mbEnums.GameObjectType.Mob).contains(abstractCharacter.getObjectType())) return false; if (!validForSlot(slot, itemManager.getEquipped(), item)) return false; if (!validForSkills(item, abstractCharacter.getSkills())) return false; if (!ValidRace(item, abstractCharacter.absRace)) return false; if (!ValidClass(item, abstractCharacter.absBaseClass,abstractCharacter.absPromotionClass)) return false; //players can't wear 0 value items. return item.template.item_value != 0 || Kit.IsNoobGear(item.templateID); } public static boolean MakeItemForPlayer(int templateID, PlayerCharacter reciever, int amount) { boolean itemWorked = false; Item item = new Item(templateID); item.ownerID = reciever.getObjectUUID(); item.ownerType = mbEnums.OwnerType.PlayerCharacter; item.containerType = mbEnums.ItemContainerType.INVENTORY; item.numberOfItems = amount; try { item = DbManager.ItemQueries.PERSIST(item); itemWorked = true; } catch (Exception e) { Logger.error(e); } if (!itemWorked) return false; reciever.charItemManager.addItemToInventory(item); reciever.charItemManager.updateInventory(); return true; } public static int validate(WorkOrder workOrder) { int validation_result = 0; ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID); if (workOrder.vendor.getBuilding() == null) return 58; //58: The formula is beyond the means of this facility if (workOrder.vendor.getBuilding().getCity() == null) return 58; //58: The formula is beyond the means of this facility if (!workOrder.vendor.charItemManager.hasRoomInventory(template.item_wt)) return 30; //30: That person cannot carry that item if (!workOrder.vendor.getItemModTable().contains((template.modTable))) return 59; //59: This hireling does not have this formula if (!Warehouse.calcCostOverrun(workOrder).isEmpty()) return 10; //18: You can't really afford that // Forge must be protected in order to access warehouse. if (ForgeManager.calcProductionCost(workOrder).size() > 1) if (!workOrder.vendor.building.protectionState.equals(mbEnums.ProtectionState.PROTECTED)) return 193; //193: Production denied: This building must be protected to gain access to warehouse return validation_result; } public static void applyItemEffects(Item forgedItem) { if (forgedItem.prefixToken != 0) { EffectsBase prefix = PowersManager.getEffectByToken(forgedItem.prefixToken); forgedItem.addPermanentEnchantment(prefix.getIDString(), 0); } if (forgedItem.suffixToken != 0) { EffectsBase suffix = PowersManager.getEffectByToken(forgedItem.suffixToken); forgedItem.addPermanentEnchantment(suffix.getIDString(), 0); } } }