Files
BattleBane/src/engine/objects/Item.java
T

1141 lines
37 KiB
Java
Raw Normal View History

2022-04-30 09:41:17 -04:00
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.objects;
import engine.gameManager.ConfigManager;
import engine.gameManager.DbManager;
import engine.gameManager.DispatchManager;
2022-04-30 09:41:17 -04:00
import engine.gameManager.PowersManager;
import engine.mbEnums;
import engine.mbEnums.*;
2022-04-30 09:41:17 -04:00
import engine.net.ByteBufferReader;
import engine.net.ByteBufferWriter;
import engine.net.Dispatch;
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;
2024-03-22 13:03:47 -04:00
import java.util.EnumSet;
2022-04-30 09:41:17 -04:00
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
public class Item extends AbstractWorldObject {
2023-07-15 09:23:48 -04:00
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 mbEnums.ItemContainerType containerType;
2023-07-15 09:23:48 -04:00
public ReentrantLock lootLock = new ReentrantLock();
2024-03-01 21:32:51 -05:00
public int ownerID; //may be character, account, npc, mob
2024-03-18 09:18:51 -04:00
public float drop_chance;
public EnumSet<mbEnums.ItemFlags> flags = EnumSet.noneOf(ItemFlags.class);
2024-03-02 11:07:07 -05:00
public int numberOfItems;
2024-03-25 05:25:09 -04:00
public float combat_health_current;
2024-03-01 21:32:51 -05:00
public int chargesRemaining;
public mbEnums.EquipSlotType equipSlot;
2023-07-15 09:23:48 -04:00
private boolean canDestroy;
public int value;
2024-03-01 21:32:51 -05:00
public OwnerType ownerType;
2024-03-15 10:35:41 -04:00
public int templateID;
2023-07-15 09:23:48 -04:00
private long dateToUpgrade;
2024-03-25 00:52:47 -04:00
public int magicValue;
2024-03-01 16:28:28 -05:00
public ItemTemplate template;
2024-03-25 04:36:07 -04:00
public String name = "";
2024-04-14 13:51:37 -04:00
public int prefixToken; // Forge support
public int suffixToken; // Forge support
2023-07-15 09:23:48 -04:00
/**
2024-03-01 16:28:28 -05:00
* In Memory constructor
2024-03-02 11:11:24 -05:00
* Set values and call PERSIST();
2023-07-15 09:23:48 -04:00
*/
2024-03-01 16:28:28 -05:00
public Item(int templateID) {
2024-03-01 16:38:20 -05:00
super();
2024-03-15 10:35:41 -04:00
this.templateID = templateID;
2024-03-16 07:57:17 -04:00
this.template = ItemTemplate.templates.get(templateID);
2024-03-01 21:32:51 -05:00
this.chargesRemaining = this.template.item_initial_charges;
2024-03-25 05:25:09 -04:00
this.combat_health_current = this.template.combat_health_full;
2024-03-08 12:19:57 -05:00
this.equipSlot = EquipSlotType.NONE;
2024-03-02 11:07:07 -05:00
this.containerType = ItemContainerType.NONE;
this.numberOfItems = 1;
2024-03-22 13:14:45 -04:00
this.flags.addAll(this.template.item_flags);
2024-03-25 00:30:16 -04:00
this.value = this.template.item_value;
2024-03-25 00:52:47 -04:00
this.magicValue = this.value + calcMagicValue();
2024-03-24 09:39:38 -04:00
loadTemplateEnchantments();
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
/**
* ResultSet Constructor
*/
public Item(ResultSet rs) throws SQLException {
super(rs);
2024-03-28 04:24:36 -04:00
this.templateID = rs.getInt("templateID");
2024-03-16 07:57:17 -04:00
this.template = ItemTemplate.templates.get(this.templateID);
2023-07-15 09:23:48 -04:00
if (this.template == null)
2024-03-16 08:56:22 -04:00
Logger.error("Null template of " + this.templateID);
2024-03-16 09:01:56 -04:00
// Name override in db.
2024-03-28 04:24:36 -04:00
this.name = rs.getString("name");
2024-03-16 08:56:22 -04:00
if (this.name == null)
2024-03-16 09:01:56 -04:00
this.name = "";
2024-03-16 08:56:22 -04:00
2023-07-15 09:23:48 -04:00
// Set container enumeration
2024-03-28 04:24:36 -04:00
String container = rs.getString("container");
2023-07-15 09:23:48 -04:00
switch (container) {
case "inventory":
this.containerType = mbEnums.ItemContainerType.INVENTORY;
2023-07-15 09:23:48 -04:00
break;
case "bank":
this.containerType = mbEnums.ItemContainerType.BANK;
2023-07-15 09:23:48 -04:00
break;
case "vault":
this.containerType = mbEnums.ItemContainerType.VAULT;
2023-07-15 09:23:48 -04:00
break;
case "equip":
this.containerType = mbEnums.ItemContainerType.EQUIPPED;
2023-07-15 09:23:48 -04:00
break;
case "forge":
this.containerType = mbEnums.ItemContainerType.FORGE;
2023-07-15 09:23:48 -04:00
break;
case "warehouse":
2024-03-24 09:40:47 -04:00
this.containerType = ItemContainerType.WAREHOUSE;
2023-07-15 09:23:48 -04:00
break;
}
this.ownerID = rs.getInt("parent");
2024-03-28 04:24:36 -04:00
this.chargesRemaining = rs.getByte("chargesRemaining");
2023-07-15 09:23:48 -04:00
2024-03-28 04:24:36 -04:00
this.combat_health_current = rs.getShort("combat_health_current");
2023-07-15 09:23:48 -04:00
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;
2024-03-29 13:23:56 -04:00
String equipString = rs.getString("equipSlot");
if (equipString.isEmpty())
this.equipSlot = EquipSlotType.NONE;
else
this.equipSlot = EquipSlotType.valueOf(equipString);
2023-07-15 09:23:48 -04:00
2024-03-28 04:24:36 -04:00
this.numberOfItems = rs.getInt("numberOfItems");
2023-07-15 09:23:48 -04:00
2024-03-28 04:24:36 -04:00
String flagString = rs.getString("flags");
2024-03-22 13:03:47 -04:00
2024-03-22 13:19:56 -04:00
if (flagString.isEmpty() == false)
for (String itemFlag : flagString.split(";"))
this.flags.add(mbEnums.ItemFlags.valueOf(itemFlag));
2024-03-22 13:03:47 -04:00
2024-03-28 04:24:36 -04:00
this.dateToUpgrade = rs.getLong("dateToUpgrade");
this.value = rs.getInt("value");
2022-04-30 09:41:17 -04:00
2024-05-12 12:06:30 -04:00
if (this.value == 0) {
2024-03-25 04:26:55 -04:00
this.value = this.template.item_value;
2024-05-12 12:06:30 -04:00
this.magicValue = this.value + calcMagicValue();
} else
this.magicValue = this.value; // Value was overridden in vendor inventory
2023-07-15 09:23:48 -04:00
}
2024-05-12 13:36:47 -04:00
public static void _serializeForClientMsg(Item item, ByteBufferWriter writer) {
2023-07-15 09:23:48 -04:00
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);
2022-04-30 09:41:17 -04:00
int baseValue = item.magicValue;
2023-07-15 09:23:48 -04:00
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)
2024-03-08 12:19:57 -05:00
writer.putInt(item.equipSlot.ordinal());
2023-07-15 09:23:48 -04:00
writer.putInt(0); // Pad
2024-03-28 05:42:27 -04:00
writer.putInt(item.templateID);
2023-07-15 09:23:48 -04:00
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.
2024-03-08 12:19:57 -05:00
boolean isHair = (item.equipSlot.equals(EquipSlotType.HAIR));
boolean isBeard = (item.equipSlot.equals(EquipSlotType.BEARD));
2023-07-15 09:23:48 -04:00
int itemColor = 0;
2024-03-08 12:19:57 -05:00
2023-07-15 09:23:48 -04:00
if (isHair || isBeard) {
2022-04-30 09:41:17 -04:00
PlayerCharacter pc = PlayerCharacter.getFromCache(item.ownerID);
2023-07-15 09:23:48 -04:00
if (pc != null)
if (isHair)
itemColor = pc.getHairColor();
else if (isBeard)
itemColor = pc.getBeardColor();
}
writer.putInt(itemColor);
writer.put((byte) 1); // End Datablock byte
2024-03-16 08:56:22 -04:00
writer.putString(item.name); // Unknown. pad?
2023-07-15 09:23:48 -04:00
writer.put((byte) 1); // End Datablock byte
2024-03-25 05:29:15 -04:00
writer.putFloat(item.template.combat_health_full);
2024-03-25 05:25:09 -04:00
writer.putFloat((float) item.combat_health_current);
2023-07-15 09:23:48 -04:00
writer.put((byte) 1); // End Datablock byte
writer.putInt(0); // Pad
writer.putInt(0); // Pad
2024-03-15 10:35:41 -04:00
if (item.templateID == ResourceType.GOLD.templateID) {
2023-07-15 09:23:48 -04:00
if (item.getOwner() != null && item.getOwner().getObjectType() == GameObjectType.PlayerCharacter) {
PlayerCharacter player = (PlayerCharacter) item.getOwner();
2024-03-18 10:01:29 -04:00
int tradingAmount = player.charItemManager.getGoldTrading();
2023-07-15 09:23:48 -04:00
writer.putInt(item.numberOfItems - tradingAmount);
} else
writer.putInt(item.numberOfItems); // Amount of gold
} else
2024-03-28 19:34:27 -04:00
writer.putInt(item.template.item_value);
2023-07-15 09:23:48 -04:00
writer.putInt(item.getValue());
int effectsSize = item.effects.size();
ArrayList<Effect> effs = null;
Effect nextE = null;
2024-03-22 13:03:47 -04:00
if (effectsSize > 0 && item.flags.contains(ItemFlags.Identified)) {
2023-07-15 09:23:48 -04:00
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)
2024-03-22 13:03:47 -04:00
if (item.flags.contains(ItemFlags.Identified))
2023-07-15 09:23:48 -04:00
writer.putInt(36); //Magical, blue name
else
writer.putInt(40); //Magical, unidentified
2024-03-11 11:29:41 -04:00
else if (item.template.item_user_power_action.size() > 0)
2023-07-15 09:23:48 -04:00
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);
2024-03-10 13:34:24 -04:00
if (item.template.item_type.equals(ItemType.EMPLOYMENTCONTRACT) == false) {
2023-07-15 09:23:48 -04:00
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
2024-03-18 10:01:29 -04:00
writer.putInt(player.charItemManager.getGoldTrading()); // Amount of gold
2023-07-15 09:23:48 -04:00
writer.putInt(0);
writer.putInt(0);
writer.putInt(0x00000000);
writer.putInt(4); //Non-Magical, grey name
writer.putInt(1);
writer.putInt(0); // Pad
2024-03-18 10:01:29 -04:00
writer.putInt(player.charItemManager.getGoldTrading());
2023-07-15 09:23:48 -04:00
writer.put((byte) 0);
writer.putShort((short) 0);
}
public static Item deserializeFromClientMsg(ByteBufferReader reader,
boolean includeSlot) {
if (includeSlot)
reader.getInt();
reader.getInt();
2024-03-28 20:44:14 -04:00
int templateID = reader.getInt(); //itemBase
2023-07-15 09:23:48 -04:00
int objectType = reader.getInt(); //object type;
int UUID = reader.getInt();
2024-03-28 20:44:14 -04:00
for (int i = 0; i < 14; i++)
2023-07-15 09:23:48 -04:00
reader.getInt(); // Pads and statics
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
int unknown = reader.getInt();
byte readString = reader.get();
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
if (readString == 1)
reader.getString();
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
byte readDurability = reader.get();
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
if (readDurability == 1) {
reader.getInt();
reader.getInt();
}
byte readEnchants = reader.get();
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
if (readEnchants == 1) {
reader.getInt();
reader.getInt();
reader.getInt();
reader.getInt();
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
int enchantSize = reader.getInt();
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
for (int i = 0; i < enchantSize; i++) {
reader.getInt(); //effect token
reader.getInt(); //trains
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
int type = reader.getInt();
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
reader.get();
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
if (type == 1)
reader.getLong(); //item comp
else
reader.getInt(); //power token
reader.getString(); //name
reader.getFloat(); //duration
}
2024-03-28 20:44:14 -04:00
for (int i = 0; i < 5; i++)
2023-07-15 09:23:48 -04:00
reader.getInt();
}
reader.get();
byte isContract = reader.get();
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
if (isContract == 1) {
reader.getInt();
reader.getInt();
reader.getInt();
}
reader.get();
if (UUID == 0 || objectType == 0)
return null;
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
if (objectType == GameObjectType.MobLoot.ordinal())
return MobLoot.getFromCache(UUID);
2024-03-28 20:44:14 -04:00
2023-07-15 09:23:48 -04:00
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) {
2022-04-30 09:41:17 -04:00
2024-03-10 13:34:24 -04:00
if (item.template.item_type.equals(ItemType.GOLD))
2023-07-15 09:23:48 -04:00
if (item.numberOfItems == 0)
continue;
try {
if (includeSlot && !forVendor)
Item._serializeForClientMsg(item, writer);
else if (!includeSlot && !forVendor)
Item.serializeForClientMsgWithoutSlot(item, writer);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (!includeSlot && forVendor) //TODO separate for sell/buy percent
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Item.serializeForClientMsgForVendorWithoutSlot(item, writer, vendor.getSellPercent());
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (includeSlot && forVendor) //TODO separate for sell/buy percent
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Item.serializeForClientMsgForVendor(item, writer, vendor.getSellPercent());
2022-04-30 09:41:17 -04:00
2024-05-12 13:36:47 -04:00
} catch (Exception se) {
2023-07-15 09:23:48 -04:00
continue;
}
++serialized;
}
writer.putIntAt(serialized, indexPosition);
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
int serialized = 0;
for (Item item : list) {
2022-04-30 09:41:17 -04:00
2024-03-10 13:34:24 -04:00
if (item.template.item_type.equals(ItemType.GOLD))
2023-07-15 09:23:48 -04:00
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());
2024-05-12 13:36:47 -04:00
} catch (Exception se) {
2023-07-15 09:23:48 -04:00
continue;
}
++serialized;
}
2024-03-18 10:01:29 -04:00
if (player.charItemManager.getGoldTrading() > 0) {
2023-07-15 09:23:48 -04:00
Item.SerializeTradingGold(player, writer);
++serialized;
}
writer.putIntAt(serialized, indexPosition);
}
public static Item getFromCache(int id) {
return (Item) DbManager.getFromCache(GameObjectType.Item, id);
}
public static Item newGoldItem(AbstractWorldObject awo, mbEnums.ItemContainerType containerType) {
2024-03-28 05:34:50 -04:00
return newGoldItem(awo, containerType, true);
2023-07-15 09:23:48 -04:00
}
//used for vault!
public static Item newGoldItem(int accountID, mbEnums.ItemContainerType containerType) {
2024-03-28 05:34:50 -04:00
return newGoldItem(accountID, containerType, true);
2023-07-15 09:23:48 -04:00
}
private static Item newGoldItem(int accountID, mbEnums.ItemContainerType containerType, boolean persist) {
2023-07-15 09:23:48 -04:00
int ownerID;
OwnerType ownerType;
ownerID = accountID;
ownerType = OwnerType.Account;
2024-03-28 05:34:50 -04:00
Item newGold = new Item(ResourceType.GOLD.templateID);
2024-03-02 10:34:45 -05:00
newGold.ownerID = ownerID;
newGold.ownerType = ownerType;
newGold.containerType = containerType;
newGold.numberOfItems = 0;
2023-07-15 09:23:48 -04:00
if (persist) {
try {
2024-03-02 09:55:30 -05:00
newGold = DbManager.ItemQueries.PERSIST(newGold);
2024-03-02 10:52:20 -05:00
DbManager.ItemQueries.ZERO_ITEM_STACK(newGold);
2023-07-15 09:23:48 -04:00
} catch (Exception e) {
Logger.error(e);
}
}
return newGold;
}
private static Item newGoldItem(AbstractWorldObject awo, mbEnums.ItemContainerType containerType, boolean persist) {
2023-07-15 09:23:48 -04:00
int ownerID;
OwnerType ownerType;
if (awo.getObjectType().equals(GameObjectType.Mob))
return null;
if (containerType == mbEnums.ItemContainerType.VAULT) {
2023-07-15 09:23:48 -04:00
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;
}
}
2024-03-28 05:34:50 -04:00
Item newGold = new Item(ResourceType.GOLD.templateID);
2024-03-02 10:34:45 -05:00
newGold.ownerID = ownerID;
newGold.ownerType = ownerType;
newGold.containerType = containerType;
newGold.numberOfItems = 0;
2023-07-15 09:23:48 -04:00
if (persist) {
try {
2024-03-02 09:55:30 -05:00
newGold = DbManager.ItemQueries.PERSIST(newGold);
2023-07-15 09:23:48 -04:00
} catch (Exception e) {
Logger.error(e);
}
DbManager.ItemQueries.ZERO_ITEM_STACK(newGold);
}
return newGold;
}
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 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;
}
2024-03-25 05:25:09 -04:00
public void setCombat_health_current(float value) {
this.combat_health_current = value;
2023-07-15 09:23:48 -04:00
}
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 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 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 synchronized void decrementChargesRemaining() {
this.chargesRemaining -= 1;
if (this.chargesRemaining < 0)
this.chargesRemaining = 0;
DbManager.ItemQueries.UPDATE_REMAINING_CHARGES(this);
}
2024-03-09 09:30:58 -05:00
public void zeroItem() {
this.ownerID = 0;
this.ownerType = null;
this.containerType = mbEnums.ItemContainerType.NONE;
2024-03-09 09:30:58 -05:00
this.equipSlot = EquipSlotType.NONE;
}
2023-07-15 09:23:48 -04:00
protected void validateItemContainer() {
if (this.containerType == mbEnums.ItemContainerType.NONE)
2023-07-15 09:23:48 -04:00
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 = mbEnums.ItemContainerType.BANK;
2023-07-15 09:23:48 -04:00
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() {
2024-03-30 14:04:08 -04:00
DbManager.ItemQueries.UPDATE_OWNER(this, 0, ItemContainerType.NONE, EquipSlotType.NONE);
2023-07-15 09:23:48 -04:00
this.zeroItem();
//cleanup item from server.
2024-03-18 07:01:44 -04:00
2023-07-15 09:23:48 -04:00
this.removeFromCache();
}
protected synchronized boolean moveItemToInventory(PlayerCharacter pc) {
2024-03-09 09:30:58 -05:00
2023-07-15 09:23:48 -04:00
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
pc.getObjectUUID(), //tableID
2024-03-30 14:04:08 -04:00
//isNPC
//isPlayer
//isAccount
2023-07-15 09:23:48 -04:00
ItemContainerType.INVENTORY,
2024-03-30 14:04:08 -04:00
EquipSlotType.NONE)) //Slot
2023-07-15 09:23:48 -04:00
return false;
this.ownerID = pc.getObjectUUID();
this.ownerType = OwnerType.PlayerCharacter;
this.containerType = ItemContainerType.INVENTORY;
2024-03-09 09:30:58 -05:00
this.equipSlot = EquipSlotType.NONE;
2023-07-15 09:23:48 -04:00
return true;
}
protected synchronized boolean moveItemToInventory(NPC npc) {
if (npc.isStatic()) {
2024-03-30 14:04:08 -04:00
if (!DbManager.ItemQueries.UPDATE_OWNER(this, 0, ItemContainerType.INVENTORY, EquipSlotType.NONE))
2023-07-15 09:23:48 -04:00
return false;
} else if (!DbManager.ItemQueries.UPDATE_OWNER(this,
npc.getObjectUUID(), //UUID
2024-03-30 14:04:08 -04:00
//isNPC
//isPlayer
//isAccount
2023-07-15 09:23:48 -04:00
ItemContainerType.INVENTORY,
2024-03-30 14:04:08 -04:00
EquipSlotType.NONE)) //Slot
2023-07-15 09:23:48 -04:00
return false;
this.zeroItem();
this.ownerID = npc.getObjectUUID();
this.ownerType = OwnerType.Npc;
this.containerType = mbEnums.ItemContainerType.INVENTORY;
2024-03-23 09:25:49 -04:00
this.equipSlot = EquipSlotType.NONE;
2023-07-15 09:23:48 -04:00
return true;
}
protected synchronized boolean moveItemToInventory(Corpse corpse) {
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
0, //no ID for corpse
2024-03-30 14:04:08 -04:00
//isNPC
//isPlayer
//isAccount
2023-07-15 09:23:48 -04:00
ItemContainerType.INVENTORY,
2024-03-30 14:04:08 -04:00
EquipSlotType.NONE)) //Slot
2023-07-15 09:23:48 -04:00
return false;
this.zeroItem();
this.ownerID = 0;
this.ownerType = null;
this.containerType = mbEnums.ItemContainerType.INVENTORY;
2024-03-23 09:25:49 -04:00
this.equipSlot = EquipSlotType.NONE;
2023-07-15 09:23:48 -04:00
return true;
}
protected synchronized boolean moveItemToBank(PlayerCharacter pc) {
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
pc.getObjectUUID(), //UUID
2024-03-30 14:04:08 -04:00
//isNPC
//isPlayer
//isAccount
2023-07-15 09:23:48 -04:00
ItemContainerType.BANK,
2024-03-30 14:04:08 -04:00
EquipSlotType.NONE)) //Slot
2023-07-15 09:23:48 -04:00
return false;
this.zeroItem();
this.ownerID = pc.getObjectUUID();
this.ownerType = OwnerType.PlayerCharacter;
this.containerType = mbEnums.ItemContainerType.BANK;
2024-03-23 09:25:49 -04:00
this.equipSlot = EquipSlotType.NONE;
2023-07-15 09:23:48 -04:00
return true;
}
protected synchronized boolean moveItemToBank(NPC npc) {
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
npc.getObjectUUID(), //UUID
2024-03-30 14:04:08 -04:00
//isNPC
//isPlayer
//isAccount
2023-07-15 09:23:48 -04:00
ItemContainerType.BANK,
2024-03-30 14:04:08 -04:00
EquipSlotType.NONE)) //Slot
2023-07-15 09:23:48 -04:00
return false;
this.zeroItem();
this.ownerID = npc.getObjectUUID();
this.ownerType = OwnerType.Npc;
this.containerType = mbEnums.ItemContainerType.BANK;
2024-03-23 09:25:49 -04:00
this.equipSlot = EquipSlotType.NONE;
2023-07-15 09:23:48 -04:00
return true;
}
protected synchronized boolean moveItemToVault(Account a) {
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
a.getObjectUUID(), //UUID
2024-03-30 14:04:08 -04:00
//isNPC
//isPlayer
//isAccount
2023-07-15 09:23:48 -04:00
ItemContainerType.VAULT,
2024-03-30 14:04:08 -04:00
EquipSlotType.NONE)) //Slot
2023-07-15 09:23:48 -04:00
return false;
this.zeroItem();
this.ownerID = a.getObjectUUID();
this.ownerType = OwnerType.Account;
this.containerType = mbEnums.ItemContainerType.VAULT;
2024-03-23 09:25:49 -04:00
this.equipSlot = EquipSlotType.NONE;
2023-07-15 09:23:48 -04:00
return true;
}
protected synchronized boolean equipItem(PlayerCharacter pc, mbEnums.EquipSlotType slot) {
2023-07-15 09:23:48 -04:00
if (!DbManager.ItemQueries.UPDATE_OWNER(this,
pc.getObjectUUID(), //tableID
2024-03-30 14:04:08 -04:00
//isNPC
//isPlayer
//isAccount
2023-07-15 09:23:48 -04:00
ItemContainerType.EQUIPPED,
2024-03-30 14:04:08 -04:00
slot)) //Slot
2023-07-15 09:23:48 -04:00
return false;
this.zeroItem();
this.ownerID = pc.getObjectUUID();
this.ownerType = OwnerType.PlayerCharacter;
this.containerType = mbEnums.ItemContainerType.EQUIPPED;
2024-03-08 13:39:38 -05:00
this.equipSlot = slot;
2023-07-15 09:23:48 -04:00
return true;
}
protected synchronized boolean equipItem(NPC npc, mbEnums.EquipSlotType slot) {
2023-07-15 09:23:48 -04:00
this.zeroItem();
this.ownerID = npc.getObjectUUID();
this.ownerType = OwnerType.Npc;
this.containerType = mbEnums.ItemContainerType.EQUIPPED;
2024-03-08 13:39:38 -05:00
this.equipSlot = slot;
2023-07-15 09:23:48 -04:00
return true;
}
protected synchronized boolean equipItem(Mob mobile, mbEnums.EquipSlotType slot) {
2023-07-15 09:23:48 -04:00
this.zeroItem();
2024-03-30 14:16:20 -04:00
this.ownerID = mobile.getObjectUUID();
2023-07-15 09:23:48 -04:00
this.ownerType = OwnerType.Mob;
this.containerType = mbEnums.ItemContainerType.EQUIPPED;
2024-03-08 13:39:38 -05:00
this.equipSlot = slot;
2023-07-15 09:23:48 -04:00
return true;
}
2024-03-24 09:39:38 -04:00
private void loadTemplateEnchantments() {
2023-07-15 09:23:48 -04:00
EffectsBase effect;
if (ConfigManager.serverType.equals(mbEnums.ServerType.LOGINSERVER))
2023-07-15 09:23:48 -04:00
return;
2024-03-11 11:24:19 -04:00
for (String effectID : this.template.item_user_power_action.keySet()) {
2023-07-15 09:23:48 -04:00
2024-03-11 11:24:19 -04:00
effect = PowersManager.getEffectByIDString(effectID);
2023-07-15 09:23:48 -04:00
2024-03-11 11:24:19 -04:00
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]);
2024-03-24 09:42:27 -04:00
}
2023-07-15 09:23:48 -04:00
}
public final void loadEnchantments() {
// No enchantments for negative id items in the db. Early exit.
if (this.objectUUID < 0) {
2024-03-03 13:18:16 -05:00
this.magicValue = this.template.item_value + calcMagicValue();
2023-07-15 09:23:48 -04:00
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);
}
}
2024-05-12 12:54:11 -04:00
// Value is overridden the db
if (this.value == this.template.item_value)
this.magicValue = this.template.item_value + calcMagicValue();
2023-07-15 09:23:48 -04:00
}
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);
}
2024-05-12 11:18:22 -04:00
public int calcMagicValue() {
2023-07-15 09:23:48 -04:00
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();
2024-03-24 09:39:38 -04:00
loadTemplateEnchantments();
2023-07-15 09:23:48 -04:00
}
public ArrayList<String> getEffectNames() {
return effectNames;
}
public boolean validForInventory(ClientConnection origin, PlayerCharacter pc, CharacterItemManager charItemMan) {
if (origin == null || pc == null || charItemMan == null)
return false;
2022-04-30 09:41:17 -04:00
if (ownerID != pc.getObjectUUID()) {
2023-07-15 09:23:48 -04:00
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;
2022-04-30 09:41:17 -04:00
if (!charItemMan.bankContains(this))
2023-07-15 09:23:48 -04:00
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;
2022-04-30 09:41:17 -04:00
if (!charItemMan.equippedContains(this))
2023-07-15 09:23:48 -04:00
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);
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
2023-07-15 09:23:48 -04:00
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;
2022-04-30 09:41:17 -04:00
if (!pc.getAccount().getVault().contains(this))
2023-07-15 09:23:48 -04:00
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);
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
2023-07-15 09:23:48 -04:00
return false;
}
return true;
}
public long getDateToUpgrade() {
return dateToUpgrade;
}
public void setDateToUpgrade(long dateToUpgrade) {
this.dateToUpgrade = dateToUpgrade;
}
/**
* @return the value
*/
public int getValue() {
2024-03-27 13:09:35 -04:00
int modifiedValue;
2024-03-25 04:28:28 -04:00
if (this.flags.contains(ItemFlags.Identified))
2024-03-27 13:09:35 -04:00
modifiedValue = this.magicValue;
else
modifiedValue = this.value;
if (this.template.item_initial_charges > 0)
modifiedValue = modifiedValue * (this.chargesRemaining / this.template.item_initial_charges);
if (this.template.combat_health_full > 0)
modifiedValue = (int) (modifiedValue * (this.combat_health_current / this.template.combat_health_full));
2023-07-15 09:23:48 -04:00
2024-03-27 13:09:35 -04:00
return modifiedValue;
2023-07-15 09:23:48 -04:00
}
/**
* @param value the value to set
*/
public void setValue(int value) {
this.value = value;
}
public boolean isCustomValue() {
if (this.value == 0)
return false;
return true;
}
2022-04-30 09:41:17 -04:00
}