// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2022 // www.magicbane.com package engine.objects; import engine.gameManager.DbManager; import engine.gameManager.PowersManager; import engine.mbEnums; import engine.mbEnums.ItemType; import engine.mbEnums.OwnerType; import engine.powers.poweractions.AbstractPowerAction; import org.pmw.tinylog.Logger; import java.util.concurrent.atomic.AtomicInteger; /** * An immutable, non-persistant implementation of Item * * @author Burfo */ public final class MobLoot extends Item { public static final AtomicInteger lastNegativeID = new AtomicInteger(0); private boolean isDeleted = false; private boolean noSteal; private String prefix = ""; private String suffix = ""; public MobLoot(AbstractCharacter mob, ItemTemplate template, boolean noSteal) { this(mob, template, 0, noSteal); } public MobLoot(AbstractCharacter mob, int qtyOfGold) { this(mob, ItemTemplate.templates.get(mbEnums.ResourceType.GOLD.templateID), qtyOfGold, false); } public MobLoot(AbstractCharacter mob, ItemTemplate template, int quantity, boolean noSteal) { super(template.template_id); this.ownerType = OwnerType.Mob; this.ownerID = mob.getObjectUUID(); this.objectUUID = generateId(); if (quantity == 0 && template.item_type == ItemType.RESOURCE) quantity = 1; if (quantity > 0) this.setNumOfItems(quantity); this.noSteal = noSteal; // Class is 'final'; passing 'this' should be okay at the end of the constructor DbManager.addToCache(this); } /** * Get the MobLoot object from its Id number * * @param id Id Number * @return MobLoot object */ public static MobLoot getFromCache(int id) { return (MobLoot) DbManager.getFromCache(mbEnums.GameObjectType.MobLoot, id); } /** * Get the next available Id number. * * @return Id number */ private static int generateId() { int id = lastNegativeID.decrementAndGet(); //TODO Add a way to reclaim disposed IDs if this becomes a problem if (id == (-10000)) Logger.warn("Only 10,000 Id numbers remain useable. Server restart suggested."); else if (id < Integer.MIN_VALUE + 1000) Logger.warn("Only " + (Integer.MIN_VALUE + id) + " Id numbers remain useable! Server restart suggested."); else if (id == Integer.MIN_VALUE) throw new UnsupportedOperationException("MobLoot has no remaining Id numbers! Restart server immediately!"); else if ((id % 10000) == 0) Logger.info(id + " of " + Integer.MIN_VALUE + " Id numbers consumed."); return id; } /** * Converts this MotLoot to a persistable Item. Used when a MotLoot is * looted * from a Mob to a Player. Do not call for a Gold item. * * @return An orphaned Item, ready to be moved to the Player's inventory. */ public synchronized Item promoteToItem(PlayerCharacter looter) { if (looter == null) return null; if (isDeleted) return null; if (this.template.item_type.equals(ItemType.GOLD)) return null; Item item = this; item.setOwner(looter); item.containerType = mbEnums.ItemContainerType.INVENTORY; item.setValue(0); if (this.getNumOfItems() > 1) item.setNumOfItems(this.getNumOfItems()); try { item = DbManager.ItemQueries.PERSIST(item); } catch (Exception e) { Logger.error("e"); return null; } //transfer enchantments to item if (this.prefix.length() != 0) item.addPermanentEnchantment(this.prefix, 0); if (this.suffix.length() != 0) item.addPermanentEnchantment(this.suffix, 0); this.junk(); return item; } public synchronized void recycle(NPC vendor) { //remove from production list for npc in db DbManager.NPCQueries.REMOVE_FROM_PRODUCTION_LIST(this.getObjectUUID(), vendor.getObjectUUID()); this.removeFromCache(); isDeleted = true; } /** * Junks the item and marks it as deleted */ @Override protected synchronized void junk() { this.removeFromCache(); isDeleted = true; } /** * Determines if this object has been marked as deleted. * * @return True if deleted. */ public boolean isDeleted() { return this.isDeleted; } public boolean noSteal() { return this.noSteal; } public void addPermanentEnchantment(String enchantID, int rank, int value, boolean prefix) { AbstractPowerAction apa = PowersManager.getPowerActionByIDString(enchantID); if (apa == null) return; apa.applyEffectForItem(this, rank); //limit to 2 effects // if (this.effectNames.size() < 2) // this.effectNames.add(enchantID); if (prefix) this.prefix = enchantID; else this.suffix = enchantID; this.getEffectNames().add(enchantID); } /* ***** * All of the following methods are overridden from * the superclass and intentionally not implemented. * ***** */ /** * Not implemented */ @Override @Deprecated public void setOwnerID(int id) { } /** * Not implemented */ @Override @Deprecated public synchronized void decrementChargesRemaining() { } /** * Not implemented */ @Deprecated protected boolean equipItem(NPC npc, byte slot) { return false; } /** * Not implemented */ @Deprecated protected boolean equipItem(PlayerCharacter pc, byte slot) { return false; } /** * Not implemented */ @Override @Deprecated protected boolean moveItemToBank(NPC npc) { return false; } /** * Not implemented */ @Override @Deprecated protected boolean moveItemToBank(PlayerCharacter pc) { return false; } /** * Not implemented */ @Override @Deprecated protected boolean moveItemToInventory(Corpse corpse) { return false; } /** * Not implemented */ @Override @Deprecated protected boolean moveItemToInventory(NPC npc) { return false; } /** * Not implemented */ @Override @Deprecated protected boolean moveItemToInventory(PlayerCharacter pc) { return false; } /** * Not implemented */ @Override @Deprecated protected boolean moveItemToVault(Account a) { return false; } /** * Not implemented */ @Deprecated public void setLastOwner(AbstractWorldObject value) { } /** * Not implemented */ @Override @Deprecated public void updateDatabase() { } /** * Not implemented */ @Override @Deprecated protected void validateItemContainer() { } public String getPrefix() { return prefix; } public void setPrefix(String prefix) { this.prefix = prefix; } public String getSuffix() { return suffix; } public void setSuffix(String suffix) { this.suffix = suffix; } }