|
|
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
|
|
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
|
|
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
|
|
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
|
|
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|