Public Repository for the Magicbane Shadowbane Emulator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1224 lines
39 KiB

// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.objects;
import engine.Enum;
import engine.Enum.*;
import engine.exception.SerializationException;
import engine.gameManager.ConfigManager;
import engine.gameManager.DbManager;
import engine.gameManager.PowersManager;
import engine.net.ByteBufferReader;
import engine.net.ByteBufferWriter;
import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection;
import engine.net.client.msg.DeleteItemMsg;
import engine.powers.EffectsBase;
import engine.powers.effectmodifiers.AbstractEffectModifier;
import engine.powers.poweractions.AbstractPowerAction;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
public class Item extends AbstractWorldObject {
private static ConcurrentHashMap<String, Integer> enchantValues = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
private final ConcurrentHashMap<AbstractEffectModifier, Float> bonuses = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
private final ArrayList<String> effectNames = new ArrayList<>();
public Enum.ItemContainerType containerType;
public ReentrantLock lootLock = new ReentrantLock();
public int ownerID; //may be character, account, npc, mob
public float drop_chance;
private int flags; //1 = isIDed
public int numberOfItems;
public float durabilityCurrent;
public int chargesRemaining;
public Enum.EquipSlotType equipSlot;
private boolean canDestroy;
private boolean isRandom = false;
private int value;
public OwnerType ownerType;
public int templateID;
private long dateToUpgrade;
private int magicValue;
public ItemTemplate template;
public String name;
/**
* In Memory constructor
* Set values and call PERSIST();
*/
public Item(int templateID) {
super();
this.templateID = templateID;
this.template = ItemTemplate.templates.get(templateID);
this.chargesRemaining = this.template.item_initial_charges;
this.durabilityCurrent = this.template.combat_health_full;
this.equipSlot = EquipSlotType.NONE;
this.containerType = ItemContainerType.NONE;
this.numberOfItems = 1;
loadEnchantments();
applyBakedInStats();
}
/**
* ResultSet Constructor
*/
public Item(ResultSet rs) throws SQLException {
super(rs);
this.templateID = rs.getInt("item_itemBaseID");
this.template = ItemTemplate.templates.get(this.templateID);
if (this.template == null)
Logger.error("Null template of " + this.templateID);
// Name override in db.
this.name = rs.getString("item_name");
if (this.name == null)
this.name = "";
// Set container enumeration
String container = rs.getString("item_container");
switch (container) {
case "inventory":
this.containerType = Enum.ItemContainerType.INVENTORY;
break;
case "bank":
this.containerType = Enum.ItemContainerType.BANK;
break;
case "vault":
this.containerType = Enum.ItemContainerType.VAULT;
break;
case "equip":
this.containerType = Enum.ItemContainerType.EQUIPPED;
break;
case "forge":
this.containerType = Enum.ItemContainerType.FORGE;
break;
case "warehouse":
this.containerType = Enum.ItemContainerType.FORGE;
break;
}
this.ownerID = rs.getInt("parent");
this.chargesRemaining = rs.getByte("item_chargesRemaining");
this.durabilityCurrent = rs.getShort("item_durabilityCurrent");
DbObjectType ownerType;
ownerType = DbManager.BuildingQueries.GET_UID_ENUM(this.ownerID);
switch (ownerType) {
case CHARACTER:
this.ownerType = OwnerType.PlayerCharacter;
break;
case NPC:
this.ownerType = OwnerType.Npc;
break;
case ACCOUNT:
this.ownerType = OwnerType.Account;
break;
}
this.canDestroy = true;
this.equipSlot = EquipSlotType.values()[rs.getByte("item_equipSlot")];
this.numberOfItems = rs.getInt("item_numberOfItems");
this.flags = rs.getInt("item_flags");
this.dateToUpgrade = rs.getLong("item_dateToUpgrade");
this.value = rs.getInt("item_value");
}
public static void _serializeForClientMsg(Item item, ByteBufferWriter writer)
throws SerializationException {
Item._serializeForClientMsg(item, writer, true);
}
public static void serializeForClientMsgWithoutSlot(Item item, ByteBufferWriter writer) {
Item._serializeForClientMsg(item, writer, false);
}
public static void serializeForClientMsgForVendor(Item item, ByteBufferWriter writer, float percent) {
Item._serializeForClientMsg(item, writer, true);
int baseValue = item.magicValue;
writer.putInt(baseValue);
writer.putInt((int) (baseValue * percent));
}
public static void serializeForClientMsgForVendorWithoutSlot(Item item, ByteBufferWriter writer, float percent) {
Item._serializeForClientMsg(item, writer, false);
writer.putInt(item.getValue());
writer.putInt(item.getValue());
}
public static void _serializeForClientMsg(Item item, ByteBufferWriter writer,
boolean includeSlot) {
if (includeSlot)
writer.putInt(item.equipSlot.ordinal());
writer.putInt(0); // Pad
writer.putInt(item.getItemBase().getUUID());
writer.putInt(item.getObjectType().ordinal());
writer.putInt(item.getObjectUUID());
// Unknown statics
for (int i = 0; i < 3; i++) {
writer.putInt(0); // Pad
}
for (int i = 0; i < 4; i++) {
writer.putInt(0x3F800000); // Static
}
for (int i = 0; i < 5; i++) {
writer.putInt(0); // Pad
}
for (int i = 0; i < 2; i++) {
writer.putInt(0xFFFFFFFF); // Static
}
// Handle Hair / Beard / horns Color.
boolean isHair = (item.equipSlot.equals(EquipSlotType.HAIR));
boolean isBeard = (item.equipSlot.equals(EquipSlotType.BEARD));
int itemColor = 0;
if (isHair || isBeard) {
PlayerCharacter pc = PlayerCharacter.getFromCache(item.ownerID);
if (pc != null)
if (isHair)
itemColor = pc.getHairColor();
else if (isBeard)
itemColor = pc.getBeardColor();
}
writer.putInt(itemColor);
writer.put((byte) 1); // End Datablock byte
writer.putString(item.name); // Unknown. pad?
writer.put((byte) 1); // End Datablock byte
writer.putFloat(item.template.item_health_full);
writer.putFloat((float) item.durabilityCurrent);
writer.put((byte) 1); // End Datablock byte
writer.putInt(0); // Pad
writer.putInt(0); // Pad
if (item.templateID == ResourceType.GOLD.templateID) {
if (item.getOwner() != null && item.getOwner().getObjectType() == GameObjectType.PlayerCharacter) {
PlayerCharacter player = (PlayerCharacter) item.getOwner();
int tradingAmount = player.getCharItemManager().getGoldTrading();
writer.putInt(item.numberOfItems - tradingAmount);
} else
writer.putInt(item.numberOfItems); // Amount of gold
} else
writer.putInt(item.template.item_value);
writer.putInt(item.getValue());
int effectsSize = item.effects.size();
ArrayList<Effect> effs = null;
Effect nextE = null;
if (effectsSize > 0 && item.isID()) {
effs = new ArrayList<>(item.effects.values());
//Don't send effects that have a token of 1
Iterator<Effect> efi = effs.iterator();
while (efi.hasNext()) {
nextE = efi.next();
if (nextE.getEffectToken() == 1 || nextE.bakedInStat())
efi.remove();
}
} else
effs = new ArrayList<>();
int effectsToSendSize = effs.size();
writer.putInt(effectsToSendSize);
for (int i = 0; i < effectsToSendSize; i++) {
effs.get(i).serializeForItem(writer, item);
}
writer.putInt(0x00000000);
if (effectsSize > 0)
if (item.isID())
writer.putInt(36); //Magical, blue name
else
writer.putInt(40); //Magical, unidentified
else if (item.template.item_user_power_action.size() > 0)
writer.putInt(36); //Magical, blue name
else
writer.putInt(4); //Non-Magical, grey name
writer.putInt(item.chargesRemaining);
writer.putInt(0); // Pad
writer.putInt(item.numberOfItems);
writer.put((byte) 0);
if (item.template.item_type.equals(ItemType.EMPLOYMENTCONTRACT) == false) {
writer.putShort((short) 0);
return;
}
writer.put((byte) 1); //
writer.putInt(0);
writer.putInt(0);
if (item.chargesRemaining == 0)
writer.putInt(1);
else
writer.putInt(item.chargesRemaining);
writer.put((byte) 0);
}
public static void SerializeTradingGold(PlayerCharacter player, ByteBufferWriter writer) {
writer.putInt(0); // Pad
writer.putInt(7);
writer.putInt(GameObjectType.Item.ordinal());
writer.putInt(player.getObjectUUID());
// Unknown statics
for (int i = 0; i < 3; i++) {
writer.putInt(0); // Pad
}
for (int i = 0; i < 4; i++) {
writer.putInt(0x3F800000); // Static
}
for (int i = 0; i < 5; i++) {
writer.putInt(0); // Pad
}
for (int i = 0; i < 2; i++) {
writer.putInt(0xFFFFFFFF); // Static
}
// Handle Hair / Beard / horns Color.
int itemColor = 0;
writer.putInt(itemColor);
writer.put((byte) 1); // End Datablock byte
writer.putInt(0);
writer.put((byte) 1); // End Datablock byte
writer.putFloat((float) 1);
writer.putFloat((float) 1);
writer.put((byte) 1); // End Datablock byte
writer.putInt(0); // Pad
writer.putInt(0); // Pad
writer.putInt(player.getCharItemManager().getGoldTrading()); // Amount of gold
writer.putInt(0);
writer.putInt(0);
writer.putInt(0x00000000);
writer.putInt(4); //Non-Magical, grey name
writer.putInt(1);
writer.putInt(0); // Pad
writer.putInt(player.getCharItemManager().getGoldTrading());
writer.put((byte) 0);
writer.putShort((short) 0);
}
public static boolean MakeItemForPlayer(int templateID, PlayerCharacter reciever, int amount) {
boolean itemWorked = false;
Item item = new Item(templateID);
item.ownerID = reciever.getObjectUUID();
item.ownerType = OwnerType.PlayerCharacter;
item.containerType = Enum.ItemContainerType.INVENTORY;
item.numberOfItems = amount;
try {
item = DbManager.ItemQueries.PERSIST(item);
itemWorked = true;
} catch (Exception e) {
Logger.error(e);
}
if (!itemWorked)
return false;
reciever.getCharItemManager().addItemToInventory(item);
reciever.getCharItemManager().updateInventory();
return true;
}
public static Item deserializeFromClientMsg(ByteBufferReader reader,
boolean includeSlot) {
if (includeSlot)
reader.getInt();
reader.getInt();
int itemBase = reader.getInt(); //itemBase
int objectType = reader.getInt(); //object type;
int UUID = reader.getInt();
for (int i = 0; i < 14; i++) {
reader.getInt(); // Pads and statics
}
int unknown = reader.getInt();
byte readString = reader.get();
if (readString == 1)
reader.getString();
byte readDurability = reader.get();
if (readDurability == 1) {
reader.getInt();
reader.getInt();
}
byte readEnchants = reader.get();
if (readEnchants == 1) {
reader.getInt();
reader.getInt();
reader.getInt();
reader.getInt();
int enchantSize = reader.getInt();
for (int i = 0; i < enchantSize; i++) {
reader.getInt(); //effect token
reader.getInt(); //trains
int type = reader.getInt();
reader.get();
if (type == 1)
reader.getLong(); //item comp
else
reader.getInt(); //power token
reader.getString(); //name
reader.getFloat(); //duration
}
for (int i = 0; i < 5; i++) {
reader.getInt();
}
}
reader.get();
byte isContract = reader.get();
if (isContract == 1) {
reader.getInt();
reader.getInt();
reader.getInt();
}
reader.get();
if (UUID == 0 || objectType == 0)
return null;
if (objectType == GameObjectType.MobLoot.ordinal())
return MobLoot.getFromCache(UUID);
return Item.getFromCache(UUID);
}
public static void putListForVendor(ByteBufferWriter writer, ArrayList<Item> list, NPC vendor) {
putList(writer, list, false, vendor.getObjectUUID(), true, vendor);
}
public static void putList(ByteBufferWriter writer, ArrayList<Item> list, boolean includeSlot, int ownerID) {
putList(writer, list, includeSlot, ownerID, false, null);
}
private static void putList(ByteBufferWriter writer, ArrayList<Item> list, boolean includeSlot, int ownerID, boolean forVendor, NPC vendor) {
int indexPosition = writer.position();
//reserve 4 bytes for index.
writer.putInt(0);
int serialized = 0;
for (Item item : list) {
if (item.template.item_type.equals(ItemType.GOLD))
if (item.numberOfItems == 0)
continue;
try {
if (includeSlot && !forVendor)
Item._serializeForClientMsg(item, writer);
else if (!includeSlot && !forVendor)
Item.serializeForClientMsgWithoutSlot(item, writer);
if (!includeSlot && forVendor) //TODO separate for sell/buy percent
Item.serializeForClientMsgForVendorWithoutSlot(item, writer, vendor.getSellPercent());
if (includeSlot && forVendor) //TODO separate for sell/buy percent
Item.serializeForClientMsgForVendor(item, writer, vendor.getSellPercent());
} catch (SerializationException se) {
continue;
}
++serialized;
}
writer.putIntAt(serialized, indexPosition);
}
public static void putTradingList(PlayerCharacter player, ByteBufferWriter writer, ArrayList<Item> list, boolean includeSlot, int ownerID, boolean forVendor, NPC vendor) {
int indexPosition = writer.position();
//reserve 4 bytes for index.
writer.putInt(0);
int serialized = 0;
for (Item item : list) {
if (item.template.item_type.equals(ItemType.GOLD))
if (item.numberOfItems == 0)
continue;
try {
if (includeSlot && !forVendor)
Item._serializeForClientMsg(item, writer);
else if (!includeSlot && !forVendor)
Item.serializeForClientMsgWithoutSlot(item, writer);
if (!includeSlot && forVendor) //TODO separate for sell/buy percent
Item.serializeForClientMsgForVendorWithoutSlot(item, writer, vendor.getSellPercent());
if (includeSlot && forVendor) //TODO separate for sell/buy percent
Item.serializeForClientMsgForVendor(item, writer, vendor.getSellPercent());
} catch (SerializationException se) {
continue;
}
++serialized;
}
if (player.getCharItemManager().getGoldTrading() > 0) {
Item.SerializeTradingGold(player, writer);
++serialized;
}
writer.putIntAt(serialized, indexPosition);
}
public static Item createItemForPlayer(PlayerCharacter pc, int templateID) {
Item item = new Item(templateID);
item.ownerID = pc.getObjectUUID();
item.ownerType = OwnerType.PlayerCharacter;
try {
item = DbManager.ItemQueries.PERSIST(item);
} catch (Exception e) {
Logger.error(e);
}
return item;
}
public static Item getFromCache(int id) {
return (Item) DbManager.getFromCache(GameObjectType.Item, id);
}
public static Item newGoldItem(AbstractWorldObject awo, ItemBase ib, Enum.ItemContainerType containerType) {
return newGoldItem(awo, ib, containerType, true);
}
//used for vault!
public static Item newGoldItem(int accountID, ItemBase ib, Enum.ItemContainerType containerType) {
return newGoldItem(accountID, ib, containerType, true);
}
private static Item newGoldItem(int accountID, ItemBase ib, Enum.ItemContainerType containerType, boolean persist) {
int ownerID;
OwnerType ownerType;
ownerID = accountID;
ownerType = OwnerType.Account;
Item newGold = new Item(ib.getUUID());
newGold.ownerID = ownerID;
newGold.ownerType = ownerType;
newGold.containerType = containerType;
newGold.numberOfItems = 0;
if (persist) {
try {
newGold = DbManager.ItemQueries.PERSIST(newGold);
DbManager.ItemQueries.ZERO_ITEM_STACK(newGold);
} catch (Exception e) {
Logger.error(e);
}
}
return newGold;
}
private static Item newGoldItem(AbstractWorldObject awo, ItemBase ib, Enum.ItemContainerType containerType, boolean persist) {
int ownerID;
OwnerType ownerType;
if (awo.getObjectType().equals(GameObjectType.Mob))
return null;
if (containerType == Enum.ItemContainerType.VAULT) {
if (!(awo.getObjectType().equals(GameObjectType.PlayerCharacter))) {
Logger.error("AWO is not a PlayerCharacter");
return null;
}
ownerID = ((PlayerCharacter) awo).getAccount().getObjectUUID();
ownerType = OwnerType.Account;
} else {
ownerID = awo.getObjectUUID();
switch (awo.getObjectType()) {
case NPC:
ownerType = OwnerType.Npc;
break;
case PlayerCharacter:
ownerType = OwnerType.PlayerCharacter;
break;
case Mob:
ownerType = OwnerType.Mob;
break;
default:
Logger.error("Unsupported AWO object type.");
return null;
}
}
Item newGold = new Item(ib.getUUID());
newGold.ownerID = ownerID;
newGold.ownerType = ownerType;
newGold.containerType = containerType;
newGold.numberOfItems = 0;
if (persist) {
try {
newGold = DbManager.ItemQueries.PERSIST(newGold);
} catch (Exception e) {
Logger.error(e);
}
DbManager.ItemQueries.ZERO_ITEM_STACK(newGold);
}
return newGold;
}
// This is to be used for trades - the new item is not stored in the database
public static Item newGoldItemTemp(AbstractWorldObject awo, ItemBase ib) {
return Item.newGoldItem(awo, ib, Enum.ItemContainerType.NONE, false);
}
public static Item getItem(int UUID) {
if (UUID == 0)
return null;
Item item = (Item) DbManager.getFromCache(GameObjectType.Item, UUID);
if (item != null)
return item;
return DbManager.ItemQueries.GET_ITEM(UUID);
}
public static void addEnchantValue(String enchant, int value) {
Item.enchantValues.put(enchant, value);
}
public static int getEnchantValue(String enchant) {
if (Item.enchantValues.containsKey(enchant))
return Item.enchantValues.get(enchant);
return 0;
}
public ItemBase getItemBase() {
return ItemBase.getItemBase(templateID);
}
public int getTemplateID() {
return this.templateID;
}
public int getOwnerID() {
return ownerID;
}
//Only to be used for trading
public void setOwnerID(int ownerID) {
this.ownerID = ownerID;
}
public AbstractGameObject getOwner() {
if (this.ownerType == OwnerType.Npc)
return NPC.getFromCache(this.ownerID);
else if (this.ownerType == OwnerType.PlayerCharacter)
return PlayerCharacter.getFromCache(this.ownerID);
else if (this.ownerType == OwnerType.Mob)
return Mob.getFromCache(this.ownerID);
else if (this.ownerType == OwnerType.Account)
return DbManager.AccountQueries.GET_ACCOUNT(this.ownerID);
else
return null;
}
public boolean setOwner(AbstractGameObject owner) {
if (owner == null)
return false;
if (owner.getObjectType().equals(GameObjectType.NPC))
this.ownerType = OwnerType.Npc;
else if (owner.getObjectType().equals(GameObjectType.PlayerCharacter))
this.ownerType = OwnerType.PlayerCharacter;
else if (owner.getObjectType().equals(GameObjectType.Mob))
this.ownerType = OwnerType.Mob;
else if (owner.getObjectType().equals(GameObjectType.Account))
this.ownerType = OwnerType.Account;
else
return false;
this.ownerID = owner.getObjectUUID();
return true;
}
public void setDurabilityCurrent(float value) {
this.durabilityCurrent = value;
}
public boolean isCanDestroy() {
return canDestroy;
}
public int getNumOfItems() {
return this.numberOfItems;
}
public synchronized void setNumOfItems(int numberOfItems) {
this.numberOfItems = numberOfItems;
}
public ConcurrentHashMap<AbstractEffectModifier, Float> getBonuses() {
return this.bonuses;
}
public void clearBonuses() {
this.bonuses.clear();
}
public float getBonus(ModType modType, SourceType sourceType) {
int amount = 0;
for (AbstractEffectModifier modifier : this.getBonuses().keySet()) {
if (modifier.getPercentMod() != 0)
continue;
if (modifier.modType.equals(modType) == false || modifier.sourceType.equals(sourceType) == false)
continue;
amount += this.bonuses.get(modifier);
}
return amount;
}
public float getBonusPercent(ModType modType, SourceType sourceType) {
int amount = 0;
for (AbstractEffectModifier modifier : this.getBonuses().keySet()) {
if (modifier.getPercentMod() == 0)
continue;
if (modifier.modType.equals(modType) == false || modifier.sourceType.equals(sourceType) == false)
continue;
amount += this.bonuses.get(modifier);
}
return amount;
}
public boolean isID() {
return ((this.flags & 1) > 0);
}
public void setIsID(boolean value) {
if (value)
this.flags |= 1;
else
this.flags &= ~1;
}
public void setIsComplete(boolean value) {
if (value)
this.flags |= 2;
else
this.flags &= ~2;
}
public boolean isComplete() {
return this.dateToUpgrade < System.currentTimeMillis() + 1000;
}
public String getContainerInfo() {
String ret = "OwnerID: " + this.ownerID + ", container: ";
ret += this.containerType.toString();
ret += "Equip Slot: " + this.equipSlot;
return ret;
}
public int getFlags() {
return this.flags;
}
public void setFlags(int value) {
this.flags = value;
}
public void addBonus(AbstractEffectModifier key, float amount) {
if (this.bonuses.containsKey(key))
this.bonuses.put(key, (this.bonuses.get(key) + amount));
else
this.bonuses.put(key, amount);
}
public void multBonus(AbstractEffectModifier key, float amount) {
if (this.bonuses.containsKey(key))
this.bonuses.put(key, (this.bonuses.get(key) * amount));
else
this.bonuses.put(key, amount);
}
public synchronized void decrementChargesRemaining() {
this.chargesRemaining -= 1;
if (this.chargesRemaining < 0)
this.chargesRemaining = 0;
DbManager.ItemQueries.UPDATE_REMAINING_CHARGES(this);
}
8 months ago
public void zeroItem() {
this.ownerID = 0;
this.ownerType = null;
this.containerType = Enum.ItemContainerType.NONE;
this.equipSlot = EquipSlotType.NONE;
}
protected void validateItemContainer() {
if (this.containerType == Enum.ItemContainerType.NONE)
if (this.ownerID != 0)
// Item has an owner, just somehow the flags got messed up.
// Default to bank.
// TODO NEED LOG EVENT HERE.
this.containerType = Enum.ItemContainerType.BANK;
else
// This item is on the ground. Nothing to worry about.
this.zeroItem();
}
// Removes all ownership of item and 'orphans' it.
protected synchronized void junk() {
DbManager.ItemQueries.UPDATE_OWNER(this, 0, false, false, false, ItemContainerType.NONE, 0);
this.zeroItem();
//cleanup item from server.
this.removeFromCache();
}
protected synchronized boolean moveItemToInventory(PlayerCharacter pc) {
8 months ago
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
pc.getObjectUUID(), //tableID
false, //isNPC
true, //isPlayer
false, //isAccount
ItemContainerType.INVENTORY,
0)) //Slot
return false;
this.ownerID = pc.getObjectUUID();
this.ownerType = OwnerType.PlayerCharacter;
this.containerType = ItemContainerType.INVENTORY;
8 months ago
this.equipSlot = EquipSlotType.NONE;
return true;
}
protected synchronized boolean moveItemToInventory(NPC npc) {
if (npc.isStatic()) {
if (!DbManager.ItemQueries.UPDATE_OWNER(this, 0, false, false, false, ItemContainerType.INVENTORY, 0))
return false;
} else if (!DbManager.ItemQueries.UPDATE_OWNER(this,
npc.getObjectUUID(), //UUID
true, //isNPC
false, //isPlayer
false, //isAccount
ItemContainerType.INVENTORY,
0)) //Slot
return false;
this.zeroItem();
this.ownerID = npc.getObjectUUID();
this.ownerType = OwnerType.Npc;
this.containerType = Enum.ItemContainerType.INVENTORY;
return true;
}
protected synchronized boolean moveItemToInventory(Corpse corpse) {
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
0, //no ID for corpse
false, //isNPC
true, //isPlayer
false, //isAccount
ItemContainerType.INVENTORY,
0)) //Slot
return false;
this.zeroItem();
this.ownerID = 0;
this.ownerType = null;
this.containerType = Enum.ItemContainerType.INVENTORY;
return true;
}
protected synchronized boolean moveItemToBank(PlayerCharacter pc) {
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
pc.getObjectUUID(), //UUID
false, //isNPC
true, //isPlayer
false, //isAccount
ItemContainerType.BANK,
0)) //Slot
return false;
this.zeroItem();
this.ownerID = pc.getObjectUUID();
this.ownerType = OwnerType.PlayerCharacter;
this.containerType = Enum.ItemContainerType.BANK;
return true;
}
protected synchronized boolean moveItemToBank(NPC npc) {
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
npc.getObjectUUID(), //UUID
true, //isNPC
false, //isPlayer
false, //isAccount
ItemContainerType.BANK,
0)) //Slot
return false;
this.zeroItem();
this.ownerID = npc.getObjectUUID();
this.ownerType = OwnerType.Npc;
this.containerType = Enum.ItemContainerType.BANK;
return true;
}
protected synchronized boolean moveItemToVault(Account a) {
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
a.getObjectUUID(), //UUID
false, //isNPC
false, //isPlayer
true, //isAccount
ItemContainerType.VAULT,
0)) //Slot
return false;
this.zeroItem();
this.ownerID = a.getObjectUUID();
this.ownerType = OwnerType.Account;
this.containerType = Enum.ItemContainerType.VAULT;
return true;
}
protected synchronized boolean equipItem(PlayerCharacter pc, Enum.EquipSlotType slot) {
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
pc.getObjectUUID(), //tableID
false, //isNPC
true, //isPlayer
false, //isAccount
ItemContainerType.EQUIPPED,
slot.ordinal())) //Slot
return false;
this.zeroItem();
this.ownerID = pc.getObjectUUID();
this.ownerType = OwnerType.PlayerCharacter;
this.containerType = Enum.ItemContainerType.EQUIPPED;
this.equipSlot = slot;
return true;
}
protected synchronized boolean equipItem(NPC npc, Enum.EquipSlotType slot) {
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
npc.getObjectUUID(), //UUID
true, //isNPC
false, //isPlayer
false, //isAccount
ItemContainerType.EQUIPPED,
slot.ordinal())) //Slot
return false;
this.zeroItem();
this.ownerID = npc.getObjectUUID();
this.ownerType = OwnerType.Npc;
this.containerType = Enum.ItemContainerType.EQUIPPED;
this.equipSlot = slot;
return true;
}
protected synchronized boolean equipItem(Mob npc, Enum.EquipSlotType slot) {
this.zeroItem();
this.ownerID = npc.getObjectUUID();
this.ownerType = OwnerType.Mob;
this.containerType = Enum.ItemContainerType.EQUIPPED;
this.equipSlot = slot;
return true;
}
public final int getMagicValue() {
return this.magicValue;
}
private void applyBakedInStats() {
EffectsBase effect;
if (ConfigManager.serverType.equals(Enum.ServerType.LOGINSERVER))
return;
for (String effectID : this.template.item_user_power_action.keySet()) {
effect = PowersManager.getEffectByIDString(effectID);
if (effect == null) {
Logger.error("missing effect of type: " + effectID);
continue;
}
AbstractPowerAction apa = PowersManager.getPowerActionByIDString(effect.getIDString());
apa.applyBakedInStatsForItem(this, this.template.item_user_power_action.get(effectID)[0]);
}
}
public final void loadEnchantments() {
//dont load mobloot enchantments, they arent in db.
if (this.getObjectType().equals(GameObjectType.MobLoot)) {
this.magicValue = this.template.item_value + calcMagicValue();
return;
}
ConcurrentHashMap<String, Integer> enchantList = DbManager.EnchantmentQueries.GET_ENCHANTMENTS_FOR_ITEM(this.getObjectUUID());
for (String enchant : enchantList.keySet()) {
AbstractPowerAction apa = PowersManager.getPowerActionByIDString(enchant);
if (apa != null) {
apa.applyEffectForItem(this, enchantList.get(enchant));
this.effectNames.add(enchant);
}
}
this.magicValue = this.template.item_value + calcMagicValue();
}
public void clearEnchantments() {
//Clear permanent enchantment out of database
DbManager.EnchantmentQueries.CLEAR_ENCHANTMENTS((long) this.getObjectUUID());
for (String name : this.getEffects().keySet()) {
Effect eff = this.getEffects().get(name);
if (!eff.bakedInStat())
this.endEffect(name);
}
this.effectNames.clear();
}
public void addPermanentEnchantment(String enchantID, int rank) {
AbstractPowerAction apa = PowersManager.getPowerActionByIDString(enchantID);
if (apa == null)
return;
DbManager.EnchantmentQueries.CREATE_ENCHANTMENT_FOR_ITEM((long) this.getObjectUUID(), enchantID, rank);
apa.applyEffectForItem(this, rank);
this.effectNames.add(enchantID);
}
public void addPermanentEnchantmentForDev(String enchantID, int rank) {
AbstractPowerAction apa = PowersManager.getPowerActionByIDString(enchantID);
if (apa == null)
return;
DbManager.EnchantmentQueries.CREATE_ENCHANTMENT_FOR_ITEM((long) this.getObjectUUID(), enchantID, rank);
apa.applyEffectForItem(this, rank);
this.effectNames.add(enchantID);
}
protected int calcMagicValue() {
int ret = 0;
for (String enchant : this.effectNames) {
ret += Item.getEnchantValue(enchant + 'A');
}
return ret;
}
public void addToCache() {
DbManager.addToCache(this);
}
@Override
public void updateDatabase() {
//DbManager.ItemQueries.updateDatabase(this);
}
@Override
public void runAfterLoad() {
loadEnchantments();
applyBakedInStats();
}
public ArrayList<String> getEffectNames() {
return effectNames;
}
public boolean validForInventory(ClientConnection origin, PlayerCharacter pc, CharacterItemManager charItemMan) {
if (origin == null || pc == null || charItemMan == null)
return false;
if (ownerID != pc.getObjectUUID()) {
Logger.warn("Inventory Item " + this.getObjectUUID() + " not owned by Character " + charItemMan.getOwner().getObjectUUID());
charItemMan.updateInventory();
return false;
}
if (!charItemMan.inventoryContains(this)) {
charItemMan.updateInventory();
return false;
}
return true;
}
public boolean validForBank(ClientConnection origin, PlayerCharacter pc, CharacterItemManager charItemMan) {
if (origin == null || pc == null || charItemMan == null)
return false;
if (!charItemMan.bankContains(this))
return false;
else if (ownerID != pc.getObjectUUID()) {
Logger.warn("Bank Item " + this.getObjectUUID() + " not owned by Character " + charItemMan.getOwner().getObjectUUID());
return false;
}
return true;
}
public boolean validForEquip(ClientConnection origin, PlayerCharacter pc, CharacterItemManager charItemMan) {
if (origin == null || pc == null || charItemMan == null)
return false;
if (!charItemMan.equippedContains(this))
return false;
else if (ownerID != pc.getObjectUUID()) {
//duped item, cleanup
Logger.warn("Duped item id "
+ this.getObjectUUID() + " removed from PC " + pc.getObjectUUID() + '.');
DeleteItemMsg deleteItemMsg = new DeleteItemMsg(this.getObjectType().ordinal(), this.getObjectUUID());
charItemMan.cleanupDupe(this);
Dispatch dispatch = Dispatch.borrow(pc, deleteItemMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
return false;
}
return true;
}
public boolean validForVault(ClientConnection origin, PlayerCharacter pc, CharacterItemManager charItemMan) {
if (origin == null || pc == null || charItemMan == null)
return false;
if (pc.getAccount() == null)
return false;
if (!pc.getAccount().getVault().contains(this))
return false;
else if (ownerID != pc.getAccount().getObjectUUID()) {
//duped item, cleanup
Logger.warn("Duped item id "
+ this.getObjectUUID() + " removed from PC " + pc.getObjectUUID() + '.');
DeleteItemMsg deleteItemMsg = new DeleteItemMsg(this.getObjectType().ordinal(), this.getObjectUUID());
charItemMan.cleanupDupe(this);
Dispatch dispatch = Dispatch.borrow(pc, deleteItemMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
return false;
}
return true;
}
public long getDateToUpgrade() {
return dateToUpgrade;
}
public void setDateToUpgrade(long dateToUpgrade) {
this.dateToUpgrade = dateToUpgrade;
}
/**
* @return the value
*/
public int getValue() {
if (this.value == 0)
if (this.isID()) {
return this.getMagicValue();
} else
return this.template.item_value;
return this.value;
}
/**
* @param value the value to set
*/
public void setValue(int value) {
this.value = value;
}
public boolean isRandom() {
return isRandom;
}
public void setRandom(boolean isRandom) {
this.isRandom = isRandom;
}
public boolean isCustomValue() {
if (this.value == 0)
return false;
return true;
}
}