Files
prestonbane/src/engine/objects/NPC.java
T

1347 lines
38 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.Enum;
import engine.Enum.*;
import engine.InterestManagement.WorldGrid;
import engine.exception.SerializationException;
import engine.gameManager.*;
import engine.job.JobContainer;
import engine.job.JobScheduler;
import engine.jobs.UpgradeNPCJob;
import engine.math.Bounds;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable;
import engine.net.ByteBufferWriter;
import engine.net.Dispatch;
import engine.net.DispatchMessage;
2023-08-21 13:26:13 -04:00
import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.ItemProductionMsg;
import engine.net.client.msg.PetMsg;
import engine.net.client.msg.PlaceAssetMsg;
2022-04-30 09:41:17 -04:00
import engine.server.MBServerStatics;
import org.joda.time.DateTime;
import org.pmw.tinylog.Logger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import static engine.net.client.msg.ErrorPopupMsg.sendErrorPopup;
import static engine.objects.MobBase.loadEquipmentSet;
2023-05-11 09:07:35 -04:00
import static engine.util.StringUtils.wordCount;
2022-04-30 09:41:17 -04:00
public class NPC extends AbstractCharacter {
2023-07-15 09:23:48 -04:00
public static int SVR_CLOSE_WINDOW = 4;
public static HashMap<Integer, ArrayList<String>> _pirateNames = new HashMap<>();
// Used for thread safety
public final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final ArrayList<MobLoot> rolling = new ArrayList<>();
public ReentrantReadWriteLock minionLock = new ReentrantReadWriteLock();
public ArrayList<ProducedItem> forgedItems = new ArrayList<>();
public HashMap<Integer, MobEquipment> equip = null;
public int runeSetID = 0;
public int extraRune2 = 0;
protected int loadID;
protected MobBase mobBase;
protected String name;
protected int dbID;
protected int currentID;
//used by static npcs
protected Zone parentZone;
protected float statLat;
protected float statLon;
protected float statAlt;
2023-08-21 13:47:47 -04:00
public float sellPercent; //also train percent
public float buyPercent;
2023-07-15 09:23:48 -04:00
protected int vendorID;
protected ArrayList<Integer> modTypeTable;
protected ArrayList<Integer> modSuffixTable;
protected ArrayList<Byte> itemModTable;
protected int symbol;
// Variables NOT to be stored in db
protected boolean isStatic = false;
private DateTime upgradeDateTime = null;
private HashSet<Integer> canRoll = null;
2023-08-21 13:47:47 -04:00
public int parentZoneUUID;
public int equipmentSetID = 0;
2023-07-15 09:23:48 -04:00
private int repairCost = 5;
2023-08-21 13:26:13 -04:00
// New NPC constructor. Fill in the blanks and then call
// PERSIST.
2023-07-15 09:23:48 -04:00
2023-08-21 13:26:13 -04:00
public NPC() {
2023-07-15 09:23:48 -04:00
2023-08-25 11:37:56 -04:00
super();
2023-07-15 09:23:48 -04:00
this.dbID = MBServerStatics.NO_DB_ROW_ASSIGNED_YET;
this.currentID = MBServerStatics.NO_DB_ROW_ASSIGNED_YET;
}
/**
* ResultSet Constructor
*/
public NPC(ResultSet rs) throws SQLException {
super(rs);
java.util.Date sqlDateTime;
try {
this.dbID = rs.getInt(1);
this.currentID = this.dbID;
this.setObjectTypeMask(MBServerStatics.MASK_NPC);
this.contractUUID = rs.getInt("npc_contractID");
2023-08-21 13:47:47 -04:00
this.parentZoneUUID = rs.getInt("parent");
2023-07-15 09:23:48 -04:00
this.gridObjectType = GridObjectType.STATIC;
this.equipmentSetID = rs.getInt("equipmentSet");
this.runeSetID = rs.getInt("runeSet");
this.loadID = rs.getInt("npc_raceID");
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
this.level = rs.getByte("npc_level");
2022-04-30 09:41:17 -04:00
buildingUUID = rs.getInt("npc_buildingID");
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Most objects from the cache have a default buy
// percentage of 100% which was a dupe source due
// to the way MB calculated item values.
2023-07-15 09:23:48 -04:00
// this.buyPercent = rs.getFloat("npc_buyPercent");
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
this.buyPercent = .33f;
this.sellPercent = 1;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
this.setRot(new Vector3f(0, rs.getFloat("npc_rotation"), 0));
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
this.statLat = rs.getFloat("npc_spawnX");
this.statAlt = rs.getFloat("npc_spawnY");
this.statLon = rs.getFloat("npc_spawnZ");
2022-04-30 09:41:17 -04:00
this.guildUUID = rs.getInt("npc_guildID");
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Set upgrade date JodaTime DateTime object
// if one exists in the database.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
sqlDateTime = rs.getTimestamp("upgradeDate");
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (sqlDateTime != null)
upgradeDateTime = new DateTime(sqlDateTime);
else
upgradeDateTime = null;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Submit upgrade job if NPC is currently set to rank.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (this.upgradeDateTime != null)
submitUpgradeJob();
2023-04-29 08:24:28 -04:00
2023-07-15 09:23:48 -04:00
this.name = rs.getString("npc_name");
2023-05-01 14:10:09 -04:00
2023-07-15 09:23:48 -04:00
} catch (Exception e) {
Logger.error("NPC: " + this.dbID + " :" + e);
e.printStackTrace();
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static boolean ISWallArcher(Contract contract) {
2023-04-24 09:22:01 -04:00
2023-07-15 09:23:48 -04:00
if (contract == null)
return false;
2023-04-24 09:22:01 -04:00
2023-07-15 09:23:48 -04:00
//838, 950, 1051, 1181, 1251, 1351, 1451, 1501, 1526, 1551, 980101,
2023-04-24 09:22:01 -04:00
2023-07-15 09:23:48 -04:00
return contract.getAllowedBuildings().contains(BuildingGroup.WALLCORNER) ||
contract.getAllowedBuildings().contains(BuildingGroup.WALLSTRAIGHTTOWER);
}
2023-04-18 20:47:49 -05:00
2023-07-15 09:23:48 -04:00
//This method restarts an upgrade timer when a building is loaded from the database.
// Submit upgrade job for this building based upon it's current upgradeDateTime
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static NPC getFromCache(int id) {
return (NPC) DbManager.getFromCache(GameObjectType.NPC, id);
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static boolean UpdateName(NPC npc, String value) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (!DbManager.NPCQueries.UPDATE_NAME(npc, value))
return false;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
npc.name = value;
return true;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static void serializeNpcForClientMsgOtherPlayer(NPC npc, ByteBufferWriter writer, boolean hideAsciiLastName)
throws SerializationException {
serializeForClientMsgOtherPlayer(npc, writer);
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static void serializeForClientMsgOtherPlayer(NPC npc, ByteBufferWriter writer)
throws SerializationException {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
writer.putInt(0);
writer.putInt(0);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
//num Runes
int cnt = 3;
boolean isVamp = false, isHealer = false, isArcher = false, isTrainer = false;
int contractID = 0, classID = 0;
int extraRune = 0;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (npc.contract != null) {
contractID = npc.contract.getContractID();
classID = npc.contract.getClassID();
extraRune = npc.contract.getExtraRune();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (extraRune == contractID)
extraRune = 0;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ((contractID > 252642 && contractID < 252647) || contractID == 252652) {
isVamp = true;
cnt++;
}
2023-04-29 13:57:09 -04:00
2023-07-15 09:23:48 -04:00
if (contractID == 252582 || contractID == 252579 || contractID == 252581
|| contractID == 252584 || contractID == 252597 || contractID == 252598
|| contractID == 252628 || extraRune == 252582 || extraRune == 252579
|| extraRune == 252581 || extraRune == 252584 || extraRune == 252597
|| extraRune == 252598 || extraRune == 252628) {
isHealer = true;
cnt++;
}
if (contractID == 252570) {
isArcher = true;
cnt++;
}
if (classID != 0)
cnt++;
if (extraRune != 0 && extraRune != contractID)
cnt++;
writer.putInt(cnt);
//Race
writer.putInt(1);
writer.putInt(0);
if (npc.mobBase != null)
writer.putInt(npc.mobBase.getLoadID());
else
writer.putInt(2011);
writer.putInt(GameObjectType.NPCRaceRune.ordinal());
writer.putInt(npc.currentID);
//Class/Trainer/Whatever
writer.putInt(5);
writer.putInt(0);
2023-04-29 08:47:35 -04:00
2023-07-15 09:23:48 -04:00
if (npc.contract != null)
writer.putInt(contractID);
else
writer.putInt(2500);
writer.putInt(GameObjectType.NPCClassRune.ordinal());
writer.putInt(npc.currentID);
//vampire trainer
cnt = 0;
if (extraRune != 0)
cnt = serializeExtraRune(npc, extraRune, cnt, writer);
if (isVamp)
cnt = serializeExtraRune(npc, 252647, cnt, writer);
//Healer trainer
2023-08-21 13:26:13 -04:00
if (isHealer)
2023-07-15 09:23:48 -04:00
cnt = serializeExtraRune(npc, 252592, cnt, writer);
if (classID != 0) {
writer.putInt(4);
writer.putInt(0);
writer.putInt(classID);
writer.putInt(GameObjectType.NPCExtraRune.ordinal());
writer.putInt(npc.currentID);
}
//Scout trainer
2023-08-21 13:26:13 -04:00
if (isArcher)
2023-07-15 09:23:48 -04:00
cnt = serializeExtraRune(npc, 252654, cnt, writer);
//Shopkeeper
writer.putInt(5);
writer.putInt(0);
writer.putInt(0x3DACC);
writer.putInt(GameObjectType.NPCShopkeeperRune.ordinal());
writer.putInt(npc.currentID);
//Send Stats
writer.putInt(5);
writer.putInt(0x8AC3C0E6); //Str
writer.putInt(0);
writer.putInt(0xACB82E33); //Dex
writer.putInt(0);
writer.putInt(0xB15DC77E); //Con
writer.putInt(0);
writer.putInt(0xE07B3336); //Int
writer.putInt(0);
writer.putInt(0xFF665EC3); //Spi
writer.putInt(0);
writer.putString(npc.name);
writer.putString("");
writer.putInt(0);
writer.putInt(0);
writer.putInt(0);
writer.putInt(0);
writer.put((byte) 0);
writer.putInt(npc.getObjectType().ordinal());
writer.putInt(npc.currentID);
writer.putFloat(1.0f);
writer.putFloat(1.0f);
writer.putFloat(1.0f);
if (npc.region != null)
writer.putVector3f(ZoneManager.convertWorldToLocal(npc.building, npc.getLoc()));
else
writer.putVector3f(npc.getLoc());
//Rotation
float radians = (float) Math.acos(npc.getRot().y) * 2;
if (npc.building != null)
if (npc.building.getBounds() != null && npc.building.getBounds().getQuaternion() != null)
radians += (npc.building.getBounds().getQuaternion()).angleY;
writer.putFloat(radians);
//Running Speed
writer.putInt(0);
// get a copy of the equipped items.
if (npc.equip != null) {
writer.putInt(npc.equip.size());
for (MobEquipment me : npc.equip.values())
MobEquipment.serializeForClientMsg(me, writer);
} else
writer.putInt(0);
writer.putInt((npc.level / 10));
writer.putInt(npc.level);
writer.putInt(npc.getIsSittingAsInt()); //Standing
writer.putInt(npc.getIsWalkingAsInt()); //Walking
writer.putInt(npc.getIsCombatAsInt()); //Combat
writer.putInt(2); //Unknown
writer.putInt(1); //Unknown - Headlights?
writer.putInt(0);
if (npc.building != null && npc.region != null) {
writer.putInt(npc.building.getObjectType().ordinal());
writer.putInt(npc.building.getObjectUUID());
} else {
writer.putInt(0); //<-Building Object Type
writer.putInt(0); //<-Building Object ID
}
writer.put((byte) 0);
writer.put((byte) 0);
writer.put((byte) 0);
//npc dialog menus from contracts
if (npc.contract != null) {
ArrayList<Integer> npcMenuOptions = npc.contract.getNPCMenuOptions();
writer.putInt(npcMenuOptions.size());
for (Integer val : npcMenuOptions) {
writer.putInt(val);
}
} else
writer.putInt(0);
writer.put((byte) 1);
if (npc.building != null) {
writer.putInt(GameObjectType.StrongBox.ordinal());
writer.putInt(npc.currentID);
writer.putInt(GameObjectType.StrongBox.ordinal());
writer.putInt(npc.building.getObjectUUID());
} else {
writer.putLong(0);
writer.putLong(0);
}
if (npc.contract != null)
writer.putInt(npc.contract.getIconID());
else
writer.putInt(0); //npc icon ID
writer.putInt(0);
writer.putShort((short) 0);
if (npc.contract != null && npc.contract.isTrainer()) {
writer.putInt(classID);
} else {
writer.putInt(0);
}
if (npc.contract != null && npc.contract.isTrainer())
writer.putInt(classID);
else
writer.putInt(0);
writer.putInt(0);
writer.putInt(0);
writer.putFloat(4);
writer.putInt(0);
writer.putInt(0);
writer.putInt(0);
writer.put((byte) 0);
//Pull guild info from building if linked to one
Guild.serializeForClientMsg(npc.guild, writer, null, true);
writer.putInt(1);
writer.putInt(0x8A2E);
writer.putInt(0);
writer.putInt(0);
//TODO Guard
writer.put((byte) 0); //Is guard..
writer.putFloat(1500f); //npc.healthMax
writer.putFloat(1500f); //npc.health
//TODO Peace Zone
writer.put((byte) 1); //0=show tags, 1=don't
writer.putInt(0);
writer.put((byte) 0);
}
private static int serializeExtraRune(NPC npc, int runeID, int cnt, ByteBufferWriter writer) {
2023-08-21 14:11:22 -04:00
2023-07-15 09:23:48 -04:00
writer.putInt(5);
writer.putInt(0);
writer.putInt(runeID);
2023-08-21 13:26:13 -04:00
2023-07-15 09:23:48 -04:00
if (cnt == 0)
writer.putInt(GameObjectType.NPCClassRuneTwo.ordinal());
else
writer.putInt(GameObjectType.NPCClassRuneThree.ordinal());
writer.putInt(npc.currentID);
return cnt + 1;
}
2022-04-30 09:41:17 -04:00
2023-08-21 14:11:22 -04:00
public static NPC createNPC(String name, int contractID, Vector3fImmutable spawn, Guild guild, Zone parent, short level, Building building) {
2023-06-26 19:19:59 -04:00
2023-08-21 13:26:13 -04:00
NPC newNPC = new NPC();
2023-07-21 12:50:52 -04:00
2023-08-21 13:26:13 -04:00
newNPC.name = name;
newNPC.contractUUID = contractID;
2023-07-21 12:50:52 -04:00
2023-08-21 13:26:13 -04:00
if (building == null)
newNPC.bindLoc = spawn;
else
newNPC.bindLoc = Vector3fImmutable.ZERO;
2023-07-21 12:50:52 -04:00
2023-08-21 13:47:47 -04:00
newNPC.parentZoneUUID = parent.getObjectUUID();
2023-08-21 13:26:13 -04:00
newNPC.guildUUID = guild.getObjectUUID();
2023-08-21 13:34:42 -04:00
if (building == null)
newNPC.buildingUUID = 0;
else
newNPC.buildingUUID = building.getObjectUUID();
2023-08-21 13:26:13 -04:00
newNPC.level = level;
2023-07-21 12:50:52 -04:00
2023-08-21 13:26:13 -04:00
newNPC.buyPercent = .33f;
newNPC.sellPercent = 1;
2023-07-21 12:50:52 -04:00
2023-07-15 09:23:48 -04:00
NPC npc;
2023-07-21 12:50:52 -04:00
2023-07-15 09:23:48 -04:00
try {
2023-08-21 13:26:13 -04:00
npc = DbManager.NPCQueries.PERSIST(newNPC);
2023-07-15 09:23:48 -04:00
npc.setObjectTypeMask(MBServerStatics.MASK_NPC);
} catch (Exception e) {
Logger.error(e);
npc = null;
}
2023-06-26 19:19:59 -04:00
2023-07-15 09:23:48 -04:00
return npc;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static NPC getNPC(int id) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (id == 0)
return null;
2023-08-20 16:18:51 -04:00
2023-07-15 09:23:48 -04:00
NPC npc = (NPC) DbManager.getFromCache(GameObjectType.NPC, id);
2023-08-20 16:18:51 -04:00
2023-07-15 09:23:48 -04:00
if (npc != null)
return npc;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return DbManager.NPCQueries.GET_NPC(id);
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
/*
* Getters
*/
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static boolean ISGuardCaptain(int contractID) {
return MinionType.ContractToMinionMap.containsKey(contractID);
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static boolean UpdateEquipSetID(NPC npc, int equipSetID) {
2022-04-30 09:41:17 -04:00
2023-08-08 18:30:21 -04:00
if (!LootManager._bootySetMap.containsKey(equipSetID))
2023-07-15 09:23:48 -04:00
return false;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (!DbManager.NPCQueries.UPDATE_EQUIPSET(npc, equipSetID))
return false;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
npc.equipmentSetID = equipSetID;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return true;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static boolean UpdateRaceID(NPC npc, int raceID) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (!DbManager.NPCQueries.UPDATE_MOBBASE(npc, raceID))
return false;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
npc.loadID = raceID;
npc.mobBase = MobBase.getMobBase(npc.loadID);
return true;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static NPCProfits GetNPCProfits(NPC npc) {
return NPCProfits.ProfitCache.get(npc.currentID);
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public final void submitUpgradeJob() {
2023-06-26 19:19:59 -04:00
2023-07-15 09:23:48 -04:00
JobContainer jc;
2023-06-26 19:19:59 -04:00
2023-07-15 09:23:48 -04:00
if (this.getUpgradeDateTime() == null) {
Logger.error("Attempt to submit upgrade job for non-ranking NPC");
return;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Submit upgrade job for future date or current instant
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (this.getUpgradeDateTime().isAfter(DateTime.now()))
jc = JobScheduler.getInstance().scheduleJob(new UpgradeNPCJob(this),
this.getUpgradeDateTime().getMillis());
else
JobScheduler.getInstance().scheduleJob(new UpgradeNPCJob(this), 0);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public void setRank(int newRank) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
DbManager.NPCQueries.SET_PROPERTY(this, "npc_level", newRank);
this.level = (short) newRank;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public int getDBID() {
return this.dbID;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
@Override
public int getObjectUUID() {
return currentID;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public MobBase getMobBase() {
return this.mobBase;
}
2023-06-26 19:19:59 -04:00
2023-07-15 09:23:48 -04:00
public Contract getContract() {
return this.contract;
}
2023-06-26 19:19:59 -04:00
2023-07-15 09:23:48 -04:00
public int getContractID() {
2023-04-24 09:42:01 -04:00
2023-07-15 09:23:48 -04:00
if (this.contract != null)
return this.contract.getObjectUUID();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return 0;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public boolean isStatic() {
return this.isStatic;
}
2023-04-24 09:42:01 -04:00
2023-07-15 09:23:48 -04:00
public Building getBuilding() {
return this.building;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public void setBuilding(Building value) {
this.building = value;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
@Override
public String getFirstName() {
return this.name;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
@Override
public String getName() {
return this.name;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public void setName(String value) {
this.name = value;
}
@Override
public String getLastName() {
return "";
}
@Override
public Vector3fImmutable getBindLoc() {
return this.bindLoc;
}
@Override
public int getGuildUUID() {
if (this.guild == null)
return 0;
return this.guild.getObjectUUID();
}
public void removeMinions() {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
for (Mob toRemove : this.siegeMinionMap.keySet()) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
try {
toRemove.clearEffects();
} catch (Exception e) {
Logger.error(e.getMessage());
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (toRemove.getParentZone() != null)
toRemove.getParentZone().zoneMobSet.remove(toRemove);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
WorldGrid.RemoveWorldObject(toRemove);
DbManager.removeFromCache(toRemove);
2022-04-30 09:41:17 -04:00
2023-08-27 21:04:34 -05:00
PlayerCharacter petOwner = (PlayerCharacter) toRemove.guardCaptain;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (petOwner != null) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
petOwner.setPet(null);
2023-08-27 21:04:34 -05:00
toRemove.guardCaptain = null;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
}
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
@Override
public float getSpeed() {
2023-04-24 09:42:01 -04:00
2023-07-15 09:23:48 -04:00
if (this.isWalk())
return MBServerStatics.WALKSPEED;
else
return MBServerStatics.RUNSPEED;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
@Override
public float getPassiveChance(String type, int AttackerLevel, boolean fromCombat) {
//TODO add this later for dodge
return 0f;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
/**
* @ Kill this Character
*/
@Override
public void killCharacter(AbstractCharacter attacker) {
//TODO Handle Death
killCleanup();
//TODO Send death message if needed
}
@Override
public void killCharacter(String reason) {
//TODO Handle Death
killCleanup();
//Orphan inventory so it can be looted
//if (!this.inSafeZone)
if (this.charItemManager != null)
this.charItemManager.orphanInventory();
//TODO Send death message if needed
//Question? How would a mob die to water?
}
private void killCleanup() {
//TODO handle cleanup from death here
//set so character won't load
this.load = false;
//Create Corpse and add to world
//Corpse.makeCorpse(this);
//TODO damage equipped items
//TODO cleanup any timers
}
public Zone getParentZone() {
return this.parentZone;
}
2023-08-21 13:47:47 -04:00
public int getParentZoneUUID() {
2023-07-15 09:23:48 -04:00
if (this.parentZone != null)
return this.parentZone.getObjectUUID();
return 0;
}
@Override
public Vector3fImmutable getLoc() {
return super.getLoc();
}
public float getSellPercent() {
return this.sellPercent;
}
public float getBuyPercent() {
return this.buyPercent;
}
2023-06-26 19:19:59 -04:00
2023-07-15 09:23:48 -04:00
public float getBuyPercent(PlayerCharacter player) {
if (NPC.GetNPCProfits(this) == null || this.guild == null)
return this.buyPercent;
NPCProfits profits = NPC.GetNPCProfits(this);
if (player.getGuild().equals(this.guild))
return profits.buyGuild;
if (player.getGuild().getNation().equals(this.guild.getNation()))
return profits.buyNation;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return profits.buyNormal;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public float getSellPercent(PlayerCharacter player) {
if (NPC.GetNPCProfits(this) == null || this.guild == null)
return 1 + this.sellPercent;
NPCProfits profits = NPC.GetNPCProfits(this);
if (player.getGuild().equals(this.guild))
return 1 + profits.sellGuild;
if (player.getGuild().getNation().equals(this.guild.getNation()))
return 1 + profits.sellNation;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return 1 + profits.sellNormal;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
@Override
public boolean canBeLooted() {
return !this.isAlive();
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public ArrayList<Integer> getModTypeTable() {
return this.modTypeTable;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
@Override
public void updateDatabase() {
DbManager.NPCQueries.updateDatabase(this);
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public int getSymbol() {
return symbol;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public ArrayList<Integer> getModSuffixTable() {
return modSuffixTable;
}
public ArrayList<Byte> getItemModTable() {
return itemModTable;
}
public boolean isRanking() {
return this.upgradeDateTime != null;
}
@Override
public void runAfterLoad() {
2023-08-25 12:54:03 -04:00
this.charItemManager = new CharacterItemManager(this);
2023-07-15 09:23:48 -04:00
if (ConfigManager.serverType.equals(ServerType.LOGINSERVER))
return;
this.contract = DbManager.ContractQueries.GET_CONTRACT(this.contractUUID);
if (this.equipmentSetID == 0 && this.contract != null)
this.equipmentSetID = this.contract.equipmentSet;
// Default to contract load ID
if (loadID == 0) {
if (this.contract != null)
loadID = this.contract.getMobbaseID();
else {
Logger.error("Invalid contract for NPC: " + this.getObjectUUID());
loadID = 2100; // Default human male
}
}
this.mobBase = MobBase.getMobBase(this.loadID);
this.building = BuildingManager.getBuilding(this.buildingUUID);
if (this.building != null)
this.guild = this.building.getGuild();
else
this.guild = Guild.getGuild(this.guildUUID);
if (this.guild == null)
this.guild = Guild.getErrantGuild();
2023-08-19 16:07:11 -04:00
if (this.contract == null)
return; // Early exit for npc guild owners
2023-08-20 15:37:11 -04:00
// Name override for this npc
if (wordCount(this.name) < 2 && this.contract != null)
this.name += " the " + this.contract.getName();
2023-08-19 15:30:35 -04:00
// Configure parent zone adding this NPC to the
// zone collection
2023-08-21 13:47:47 -04:00
this.parentZone = ZoneManager.getZoneByUUID(this.parentZoneUUID);
2023-08-19 15:30:35 -04:00
this.parentZone.zoneNPCSet.remove(this);
this.parentZone.zoneNPCSet.add(this);
2023-07-15 09:23:48 -04:00
2023-08-19 15:30:35 -04:00
// Setup location for this NPC
2023-07-15 09:23:48 -04:00
2023-08-19 15:30:35 -04:00
this.bindLoc = new Vector3fImmutable(this.statLat, this.statAlt, this.statLon);
this.bindLoc = this.parentZone.getLoc().add(this.bindLoc);
this.loc = new Vector3fImmutable(bindLoc);
// Handle NPCs within buildings
if (this.building != null)
NPCManager.slotCharacterInBuilding(this);
if (this.contract != null) {
this.symbol = this.contract.getIconID();
this.modTypeTable = this.contract.getNPCModTypeTable();
this.modSuffixTable = this.contract.getNpcModSuffixTable();
this.itemModTable = this.contract.getItemModTable();
int VID = this.contract.getVendorID();
if (VID != 0)
this.vendorID = VID;
else
this.vendorID = 1; //no vendor items
2023-07-15 09:23:48 -04:00
}
2023-08-19 15:30:35 -04:00
if (this.mobBase != null) {
this.healthMax = this.mobBase.getHealthMax();
this.manaMax = 0;
this.staminaMax = 0;
this.setHealth(this.healthMax);
this.mana.set(this.manaMax);
this.stamina.set(this.staminaMax);
}
if (this.parentZone.isPlayerCity())
if (NPC.GetNPCProfits(this) == null)
NPCProfits.CreateProfits(this);
//TODO set these correctly later
this.rangeHandOne = 8;
this.rangeHandTwo = -1;
this.minDamageHandOne = 1;
this.maxDamageHandOne = 4;
this.minDamageHandTwo = 1;
this.maxDamageHandTwo = 4;
this.atrHandOne = 300;
this.defenseRating = 200;
this.isActive = true;
this.charItemManager.load();
this.equip = loadEquipmentSet(this.equipmentSetID);
2023-07-15 09:23:48 -04:00
if (this.equip == null)
this.equip = new HashMap<>();
try {
DbManager.NPCQueries.LOAD_ALL_ITEMS_TO_PRODUCE(this);
for (ProducedItem producedItem : this.forgedItems) {
MobLoot ml = new MobLoot(this, ItemBase.getItemBase(producedItem.getItemBaseID()), false);
DbManager.NPCQueries.UPDATE_ITEM_ID(producedItem.getID(), currentID, ml.getObjectUUID());
if (producedItem.isInForge()) {
if (producedItem.getPrefix() != null && !producedItem.getPrefix().isEmpty()) {
ml.addPermanentEnchantment(producedItem.getPrefix(), 0, 0, true);
ml.setPrefix(producedItem.getPrefix());
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (producedItem.getSuffix() != null && !producedItem.getSuffix().isEmpty()) {
ml.addPermanentEnchantment(producedItem.getSuffix(), 0, 0, false);
ml.setSuffix(producedItem.getSuffix());
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (!producedItem.isRandom())
ml.setIsID(true);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
ml.loadEnchantments();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
ml.setValue(producedItem.getValue());
ml.setDateToUpgrade(producedItem.getDateToUpgrade().getMillis());
ml.containerType = Enum.ItemContainerType.FORGE;
this.addItemToForge(ml);
2023-06-26 19:19:59 -04:00
2023-07-15 09:23:48 -04:00
} else {
2023-06-26 19:19:59 -04:00
2023-07-15 09:23:48 -04:00
if (producedItem.getPrefix() != null && !producedItem.getPrefix().isEmpty()) {
ml.addPermanentEnchantment(producedItem.getPrefix(), 0, 0, true);
ml.setPrefix(producedItem.getPrefix());
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (producedItem.getSuffix() != null && !producedItem.getSuffix().isEmpty()) {
ml.addPermanentEnchantment(producedItem.getSuffix(), 0, 0, false);
ml.setSuffix(producedItem.getSuffix());
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
ml.setDateToUpgrade(producedItem.getDateToUpgrade().getMillis());
ml.containerType = Enum.ItemContainerType.INVENTORY;
ml.setIsID(true);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
this.charItemManager.addItemToInventory(ml);
}
ml.setValue(producedItem.getValue());
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Create NPC bounds object
Bounds npcBounds = Bounds.borrow();
npcBounds.setBounds(this.getLoc());
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
} catch (Exception e) {
Logger.error(e.getMessage());
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public void removeFromZone() {
this.parentZone.zoneNPCSet.remove(this);
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
@Override
protected ConcurrentHashMap<Integer, CharacterPower> initializePowers() {
return new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public DateTime getUpgradeDateTime() {
lock.readLock().lock();
try {
return upgradeDateTime;
} finally {
lock.readLock().unlock();
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public void setUpgradeDateTime(DateTime upgradeDateTime) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (!DbManager.NPCQueries.updateUpgradeTime(this, upgradeDateTime)) {
Logger.error("Failed to set upgradeTime for building " + currentID);
return;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
this.upgradeDateTime = upgradeDateTime;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public ArrayList<MobLoot> getRolling() {
synchronized (rolling) {
return rolling;
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public int getRollingCount() {
synchronized (this.rolling) {
return rolling.size();
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public void addItemToForge(MobLoot item) {
synchronized (this.rolling) {
this.rolling.add(item);
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public void removeItemFromForge(Item item) {
synchronized (this.rolling) {
this.rolling.remove(item);
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
@Override
public Guild getGuild() {
if (this.building != null)
return building.getGuild();
return this.guild;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public HashSet<Integer> getCanRoll() {
2022-04-30 09:41:17 -04:00
2023-08-15 08:52:49 -04:00
if (this.canRoll == null)
2023-07-15 09:23:48 -04:00
this.canRoll = DbManager.ItemQueries.GET_ITEMS_FOR_VENDOR(this.vendorID);
2023-08-15 08:52:49 -04:00
HashSet<Integer> fullItemList = this.canRoll;
HashSet<Integer> filteredItemList = new HashSet<>();
short maxSkill = 25;
switch (this.getRank()) {
case 1:
maxSkill = 25;
break;
case 2:
maxSkill = 50;
break;
case 3:
case 4:
maxSkill = 75;
break;
case 5:
case 6:
maxSkill = 100;
break;
case 7:
maxSkill = 110;
break;
}
2023-08-19 11:39:01 -05:00
ItemBase itemBase;
for (Integer itemID : fullItemList) {
itemBase = ItemBase.getItemBase(itemID);
boolean exclude = itemBase.getPercentRequired() == 0 && itemBase.getType() == ItemType.WEAPON;
if (itemBase.getPercentRequired() <= maxSkill && !exclude)
2023-08-15 08:52:49 -04:00
filteredItemList.add(itemID);
2023-08-19 11:39:01 -05:00
}
2023-08-15 08:52:49 -04:00
if (this.contract.getVendorID() == 102) {
2022-04-30 09:41:17 -04:00
2023-08-15 08:52:49 -04:00
for (int i = 0; i < this.getRank(); i++) {
int subID = i + 1;
filteredItemList.add(910010 + subID);
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-08-15 08:52:49 -04:00
if (this.getRank() == 7)
filteredItemList.add(910018);
}
return filteredItemList;
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public int getRollingTimeInSeconds(int itemID) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
ItemBase ib = ItemBase.getItemBase(itemID);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (ib == null)
return 0;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (ib.getType() == ItemType.SCROLL)
return this.getRank() * 60 * 60 * 3;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
float time;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (this.building == null)
return 600;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
float rank = this.building.getRank() - 1;
float rate = (float) (2.5 * rank);
time = (20 - rate);
time *= 60;
return (int) time;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public boolean remove() {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Building building;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Remove npc from it's building
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
building = this.building;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (building != null) {
building.getHirelings().remove(this);
this.removeMinions();
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Delete npc from database
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (DbManager.NPCQueries.DELETE_NPC(this) == 0) {
return false;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Remove npc from the simulation
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
this.removeFromCache();
WorldGrid.RemoveWorldObject(this);
WorldGrid.removeObject(this);
return true;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public int getUpgradeCost() {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
int upgradeCost;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
upgradeCost = Integer.MAX_VALUE;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (this.getRank() < 7)
return (this.getRank() * 100650) + 21450;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return upgradeCost;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public int getUpgradeTime() {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
int upgradeTime; // expressed in hours
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
upgradeTime = Integer.MAX_VALUE;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (this.getRank() < 7)
return (this.getRank() * 8);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return 0;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public synchronized Item produceItem(int playerID, int amount, boolean isRandom, int pToken, int sToken, String customName, int itemID) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Zone serverZone;
City city;
Item item = null;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
PlayerCharacter player = null;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (playerID != 0)
player = SessionManager.getPlayerCharacterByID(playerID);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
try {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (this.getRollingCount() >= this.getRank()) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (player != null)
ChatManager.chatSystemInfo(player, this.getName() + " " + this.getContract().getName() + " slots are full");
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return null;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Cannot roll items without a warehouse.
// Due to the fact fillForge references the
// warehouse and early exits. *** Refactor???
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
serverZone = this.building.getParentZone();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (serverZone == null)
return null;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
city = City.GetCityFromCache(serverZone.getPlayerCityUUID());
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (city == null) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (player != null)
ErrorPopupMsg.sendErrorMsg(player, "Could not find city."); // Production denied: This building must be protected to gain access to warehouse resources.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return null;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (this.building == null) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (player != null)
ErrorPopupMsg.sendErrorMsg(player, "Could not find building."); // Production denied: This building must be protected to gain ac
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return null;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
//TODO create Normal Items.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (amount == 0)
amount = 1;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (isRandom)
item = ItemFactory.randomRoll(this, player, amount, itemID);
else
item = ItemFactory.fillForge(this, player, amount, itemID, pToken, sToken, customName);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (item == null)
return null;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
ItemProductionMsg outMsg = new ItemProductionMsg(this.building, this, item, 8, true);
DispatchMessage.dispatchMsgToInterestArea(this, outMsg, DispatchChannel.SECONDARY, 700, false, false);
2023-06-26 19:19:59 -04:00
2023-07-15 09:23:48 -04:00
} catch (Exception e) {
Logger.error(e);
}
return item;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public synchronized boolean completeItem(int itemUUID) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
MobLoot targetItem;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
try {
targetItem = MobLoot.getFromCache(itemUUID);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (targetItem == null)
return false;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (!this.getCharItemManager().forgeContains(targetItem, this))
return false;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (!DbManager.NPCQueries.UPDATE_ITEM_TO_INVENTORY(targetItem.getObjectUUID(), currentID))
return false;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
targetItem.setIsID(true);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
this.rolling.remove(targetItem);
this.getCharItemManager().addItemToInventory(targetItem);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
//remove from client forge window
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
ItemProductionMsg outMsg1 = new ItemProductionMsg(this.building, this, targetItem, 9, true);
DispatchMessage.dispatchMsgToInterestArea(this, outMsg1, DispatchChannel.SECONDARY, MBServerStatics.STRUCTURE_LOAD_RANGE, false, false);
ItemProductionMsg outMsg = new ItemProductionMsg(this.building, this, targetItem, 10, true);
DispatchMessage.dispatchMsgToInterestArea(this, outMsg, DispatchChannel.SECONDARY, MBServerStatics.STRUCTURE_LOAD_RANGE, false, false);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
} catch (Exception e) {
Logger.error(e.getMessage());
}
return true;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public HashMap<Integer, MobEquipment> getEquip() {
return equip;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public int getEquipmentSetID() {
return equipmentSetID;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public String getNameOverride() {
return name;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public int getRepairCost() {
return repairCost;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public void setRepairCost(int repairCost) {
this.repairCost = repairCost;
}
2023-06-26 19:19:59 -04:00
2023-07-15 09:23:48 -04:00
public void processUpgradeNPC(PlayerCharacter player) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
int rankCost;
Building building;
DateTime dateToUpgrade;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
this.lock.writeLock().lock();
try {
2023-06-26 19:19:59 -04:00
2023-07-15 09:23:48 -04:00
building = this.getBuilding();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Cannot upgrade an npc not within a building
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (building == null)
return;
2023-06-26 19:19:59 -04:00
2023-07-15 09:23:48 -04:00
// Cannot upgrade an npc at max rank
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (this.getRank() == 7)
return;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Cannot upgrade an npc who is currently ranking
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (this.isRanking())
return;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
rankCost = this.getUpgradeCost();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// SEND NOT ENOUGH GOLD ERROR
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (!building.hasFunds(rankCost)) {
sendErrorPopup(player, 127);
return;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (rankCost > building.getStrongboxValue()) {
sendErrorPopup(player, 127);
return;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
try {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if (!building.transferGold(-rankCost, false))
return;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
dateToUpgrade = DateTime.now().plusHours(this.getUpgradeTime());
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
this.setUpgradeDateTime(dateToUpgrade);
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Schedule upgrade job
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
this.submitUpgradeJob();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
} catch (Exception e) {
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
}
} catch (Exception e) {
Logger.error(e);
} finally {
this.lock.writeLock().unlock();
}
}
2022-04-30 09:41:17 -04:00
}