// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2022 // www.magicbane.com package engine.objects; import engine.Enum; import engine.Enum.GameObjectType; import engine.Enum.ItemType; import engine.gameManager.DbManager; import org.pmw.tinylog.Logger; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; public class ItemBase { public static ItemBase GOLD_ITEM_BASE = null; public static int GOLD_BASE_ID = 7; public static ArrayList AnniversaryGifts = new ArrayList<>(); public static HashMap _itemBaseByUUID = new HashMap<>(); // Internal cache private static final HashMap itemHashIDMap = new HashMap<>(); private static final HashMap _IDsByNames = new HashMap<>(); private static final ArrayList _resourceList = new ArrayList<>(); private final int uuid; //requirements/restrictions private final ItemType type; private int vendorType; private final int modTable; private final int useID; private int hashID; private final byte useAmount; // Armor and weapon related values private final String skillRequired; private final short percentRequired; private final float blockMod; private final short defense; private final float dexPenalty; private final float speed; private final float range; private final short minDamage; private final short maxDamage; private final String mastery; private final engine.Enum.SourceType damageType; private final boolean twoHanded; private boolean isConsumable; // Item stat modifiers private final HashMap bakedInStats = new HashMap<>(); private final HashMap usedStats = new HashMap<>(); private final float parryBonus; private final boolean isStrBased; private ArrayList animations = new ArrayList<>(); private ArrayList offHandAnimations = new ArrayList<>(); /** * ResultSet Constructor */ public ItemBase(ResultSet rs) throws SQLException { this.uuid = rs.getInt("ID"); this.type = ItemType.valueOf(rs.getString("Type")); this.useID = rs.getInt("useID"); this.vendorType = rs.getInt("vendorType"); this.useAmount = rs.getByte("useAmount"); this.modTable = rs.getInt("modTable"); this.hashID = rs.getInt("itemHashID"); this.isConsumable = false; this.skillRequired = rs.getString("skillRequired"); this.percentRequired = rs.getShort("percentRequired"); this.blockMod = rs.getFloat("blockMod"); this.defense = rs.getShort("defense"); this.dexPenalty = rs.getFloat("dexPenalty"); this.parryBonus = rs.getFloat("parryBonus"); this.isStrBased = (rs.getInt("isStrBased") == 1); this.speed = rs.getFloat("speed"); this.range = rs.getFloat("range"); this.minDamage = rs.getShort("minDamage"); this.maxDamage = rs.getShort("maxDamage"); this.mastery = rs.getString("mastery"); damageType = Enum.SourceType.valueOf(rs.getString("damageType").toUpperCase()); this.twoHanded = (rs.getInt("twoHanded") == 1); switch (this.type) { case RUNE: case SCROLL: case COMMANDROD: case POTION: case TEARS: case GUILDCHARTER: case DEED: case CONTRACT: case WATERBUCKET: case REALMCHARTER: case GIFT: this.isConsumable = true; break; case OFFERING: this.isConsumable = true; Boon.HandleBoonListsForItemBase(uuid); break; } try { DbManager.ItemBaseQueries.LOAD_ANIMATIONS(this); } catch (Exception e) { Logger.error(e.getMessage()); } initBakedInStats(); initializeHashes(); } public static void addToCache(ItemBase itemBase) { _itemBaseByUUID.put(itemBase.uuid, itemBase); if (itemBase.type.equals(ItemType.RESOURCE)) _resourceList.add(itemBase); ItemTemplate template = ItemTemplate.itemTemplates.get(itemBase.uuid); if (template == null) Logger.error("Null template for: " + itemBase.uuid); else _IDsByNames.put(template.item_base_name.toLowerCase().replace(" ", "_"), itemBase.uuid); } public static HashMap getItemHashIDMap() { return itemHashIDMap; } /* * Database */ public static ItemBase getItemBase(int uuid) { return _itemBaseByUUID.get(uuid); } /** * Get the ItemBase instance for Gold. * * @return ItemBase for Gold */ public static ItemBase getGoldItemBase() { if (ItemBase.GOLD_ITEM_BASE == null) ItemBase.GOLD_ITEM_BASE = getItemBase(7); return ItemBase.GOLD_ITEM_BASE; } public static int getIDByName(String name) { if (ItemBase._IDsByNames.containsKey(name)) return ItemBase._IDsByNames.get(name); return 0; } /** * @return the _itemBaseByUUID */ public static HashMap getUUIDCache() { return _itemBaseByUUID; } /** * @return the _resourceList */ public static ArrayList getResourceList() { return _resourceList; } public static void loadAllItemBases() { DbManager.ItemBaseQueries.LOAD_ALL_ITEMBASES(); AnniversaryGifts.add(971000); AnniversaryGifts.add(971001); AnniversaryGifts.add(971002); AnniversaryGifts.add(971003); AnniversaryGifts.add(971004); AnniversaryGifts.add(971005); AnniversaryGifts.add(971006); AnniversaryGifts.add(971007); AnniversaryGifts.add(971008); AnniversaryGifts.add(971009); AnniversaryGifts.add(971010); AnniversaryGifts.add(5101000); AnniversaryGifts.add(5101020); AnniversaryGifts.add(5101100); AnniversaryGifts.add(5101120); AnniversaryGifts.add(5101040); AnniversaryGifts.add(5101140); AnniversaryGifts.add(5101060); AnniversaryGifts.add(5101080); } private void initBakedInStats() { DbManager.ItemBaseQueries.LOAD_BAKEDINSTATS(this); } public boolean isConsumable() { return this.isConsumable; } public boolean isRune() { int ID = uuid; if (ID > 2499 && ID < 3050) //class, discipline runes return true; else return ID > 249999 && ID < 252137; } public boolean isDiscRune() { int ID = uuid; //class, discipline runes return ID > 2499 && ID < 3050; } public boolean isGlass() { int ID = uuid; return ID > 7000099 && ID < 7000281; } //returns powers tokens baked in to item public HashMap getBakedInStats() { return this.bakedInStats; } //returns power tokens granted when using item, such as scrolls and potions public HashMap getUsedStats() { return this.usedStats; } public final void initializeHashes() { itemHashIDMap.put(this.hashID, uuid); } public ItemType getType() { return this.type; } public int getUseID() { return this.useID; } public byte getUseAmount() { return this.useAmount; } public int getModTable() { return modTable; } public int getHashID() { return hashID; } public boolean canEquip(Enum.EquipSlotType slot, CharacterItemManager itemManager, AbstractCharacter abstractCharacter, Item item) { if (itemManager == null || abstractCharacter == null) return false; if (abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter)) { if (!validForSlot(slot, itemManager.getEquipped(), item)) return false; if (!ItemTemplate.validForSkills(item, abstractCharacter.getSkills())) return false; if (ItemTemplate.canCharacterEquip(item, abstractCharacter) == false) return false; return item.template.item_value != 0 || Kit.IsNoobGear(item.getItemBase().uuid); //players can't wear 0 value items. } return true; //Mobiles and NPC's don't need to check equip } public static boolean validForSlot(Enum.EquipSlotType slot, ConcurrentHashMap equipped, Item item) { boolean validSlot = false; if (equipped == null) 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 ((ItemTemplate.isTwoHanded(item)) && ((slot == Enum.EquipSlotType.LHELD && equipped.get(Enum.EquipSlotType.RHELD) != null) || (slot == Enum.EquipSlotType.RHELD && equipped.get(Enum.EquipSlotType.LHELD) != null))) return false; if (item.template.item_type.equals(ItemType.WEAPON)) if (equipped.get(slot) != null && equipped.get(slot).equals(item) == false) return false; return true; } /** * @return the uuid */ public final int getUUID() { return uuid; } public boolean isTwoHanded() { return this.twoHanded; } /** * @return the skillRequired */ public String getSkillRequired() { return skillRequired; } /** * @return the mastery */ public String getMastery() { return mastery; } /** * @return the defense */ public short getDefense() { return defense; } /** * @return the dexPenalty */ public float getDexPenalty() { return dexPenalty; } /** * @return the speed */ public float getSpeed() { return speed; } /** * @return the range */ public float getRange() { return range; } /** * @return the isStrBased */ public boolean isStrBased() { return isStrBased; } /** * @return the maxDamage */ public short getMaxDamage() { return maxDamage; } /** * @return the minDamage */ public short getMinDamage() { return minDamage; } /** * @return the damageType */ public Enum.SourceType getDamageType() { return damageType; } public short getPercentRequired() { return percentRequired; } public ArrayList getAnimations() { return animations; } public void setAnimations(ArrayList animations) { this.animations = animations; } public ArrayList getOffHandAnimations() { return offHandAnimations; } public void setOffHandAnimations(ArrayList offHandAnimations) { this.offHandAnimations = offHandAnimations; } }