Initial Repository Push
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,235 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.GameObjectType;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.job.JobContainer;
|
||||
import engine.job.JobScheduler;
|
||||
import engine.jobs.DatabaseUpdateJob;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public abstract class AbstractGameObject {
|
||||
private GameObjectType objectType = GameObjectType.unknown;
|
||||
private int objectUUID;
|
||||
|
||||
private byte ver = 1;
|
||||
|
||||
private ConcurrentHashMap<String, JobContainer> databaseJobs = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public AbstractGameObject() {
|
||||
super();
|
||||
setObjectType();
|
||||
this.objectUUID = MBServerStatics.NO_DB_ROW_ASSIGNED_YET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public AbstractGameObject(int objectUUID) {
|
||||
this();
|
||||
this.objectUUID = objectUUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*
|
||||
* @param rs
|
||||
* ResultSet containing record for this object
|
||||
*/
|
||||
public AbstractGameObject(ResultSet rs, int objectUUID) throws SQLException {
|
||||
this();
|
||||
this.objectUUID = objectUUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor; assumes first column in ResultSet is ID
|
||||
*
|
||||
* @param rs
|
||||
* ResultSet containing record for this object
|
||||
*/
|
||||
public AbstractGameObject(ResultSet rs) throws SQLException {
|
||||
this(rs, rs.getInt(1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public GameObjectType getObjectType() {
|
||||
return this.objectType;
|
||||
}
|
||||
|
||||
protected final void setObjectType() {
|
||||
try {
|
||||
this.objectType = GameObjectType.valueOf(this.getClass().getSimpleName());
|
||||
} catch (SecurityException | IllegalArgumentException e) {
|
||||
Logger.error("Failed to find class " + this.getClass().getSimpleName()
|
||||
+ " in GameObjectTypes file. Defaulting ObjectType to 0.");
|
||||
}
|
||||
}
|
||||
|
||||
public int getObjectUUID() {
|
||||
return this.objectUUID;
|
||||
}
|
||||
|
||||
protected void setObjectUUID(int objectUUID) {
|
||||
this.objectUUID = objectUUID;
|
||||
}
|
||||
|
||||
public byte getVer() {
|
||||
return this.ver;
|
||||
}
|
||||
|
||||
public void incVer() {
|
||||
this.ver++;
|
||||
if (this.ver == (byte)-1) //-1 reserved
|
||||
this.ver++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Util
|
||||
*/
|
||||
|
||||
public static int extractUUID(GameObjectType type, long compositeID) {
|
||||
if (type == null || type == GameObjectType.unknown || compositeID == 0L) {
|
||||
return -1;
|
||||
}
|
||||
int out = (int) compositeID;
|
||||
if (out > Long.MAX_VALUE || out < 0) {
|
||||
Logger.error("There was a problem reverse calculating a UUID from a compositeID. \tcomposID: "
|
||||
+ compositeID + " \ttype: " + type.toString() + "\tresult: " + out);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public static GameObjectType extractTypeID(long compositeID) {
|
||||
int ordinal = (int) (compositeID >>> 32);
|
||||
return GameObjectType.values()[ordinal];
|
||||
}
|
||||
|
||||
public boolean equals(AbstractGameObject obj) {
|
||||
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
||||
if (obj.objectType != this.objectType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return obj.getObjectUUID() == this.getObjectUUID();
|
||||
}
|
||||
|
||||
public void removeFromCache() {
|
||||
DbManager.removeFromCache(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a {@link PreparedStatementShared} based on the specified query.
|
||||
* <p>
|
||||
* If {@link AbstractGameObject} Database functions will properly release
|
||||
* the PreparedStatementShared upon completion. If these functions are not
|
||||
* used, then {@link PreparedStatementShared#release release()} must be
|
||||
* called when finished with this object.
|
||||
*
|
||||
* @param sql
|
||||
* The SQL string used to generate the PreparedStatementShared
|
||||
* @return {@link PreparedStatementShared}
|
||||
* @throws {@link SQLException}
|
||||
**/
|
||||
protected static PreparedStatementShared prepareStatement(String sql) throws SQLException {
|
||||
return new PreparedStatementShared(sql);
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<String, JobContainer> getDatabaseJobs() {
|
||||
return this.databaseJobs;
|
||||
}
|
||||
|
||||
public void addDatabaseJob(String type, int duration) {
|
||||
DatabaseUpdateJob updateJob;
|
||||
|
||||
if (databaseJobs.containsKey(type))
|
||||
return;
|
||||
|
||||
updateJob = new DatabaseUpdateJob(this, type);
|
||||
JobContainer jc = JobScheduler.getInstance().scheduleJob(updateJob, duration);
|
||||
databaseJobs.put(type, jc);
|
||||
}
|
||||
|
||||
public void removeDatabaseJob(String type, boolean canceled) {
|
||||
if (databaseJobs.containsKey(type)) {
|
||||
if (canceled) {
|
||||
JobContainer jc = databaseJobs.get(type);
|
||||
if (jc != null)
|
||||
jc.cancelJob();
|
||||
}
|
||||
databaseJobs.remove(type);
|
||||
}
|
||||
}
|
||||
|
||||
public static AbstractGameObject getFromTypeAndID(long compositeID) {
|
||||
int objectTypeID = extractTypeOrdinal(compositeID);
|
||||
int tableID = extractTableID(objectTypeID, compositeID);
|
||||
GameObjectType objectType = GameObjectType.values()[objectTypeID];
|
||||
|
||||
switch (objectType) {
|
||||
case PlayerCharacter:
|
||||
return PlayerCharacter.getPlayerCharacter(tableID);
|
||||
|
||||
case NPC:
|
||||
return NPC.getNPC(tableID);
|
||||
|
||||
case Mob:
|
||||
return Mob.getMob(tableID);
|
||||
|
||||
case Building:
|
||||
return BuildingManager.getBuilding(tableID);
|
||||
|
||||
case Guild:
|
||||
return Guild.getGuild(tableID);
|
||||
|
||||
case Item:
|
||||
return Item.getFromCache(tableID);
|
||||
|
||||
case MobLoot:
|
||||
return MobLoot.getFromCache(tableID);
|
||||
|
||||
default:
|
||||
Logger.error("Failed to convert compositeID to AbstractGameObject. " + "Unsupported type encountered. "
|
||||
+ "CompositeID: " + compositeID + " ObjectType: 0x" + Integer.toHexString(objectTypeID) + " TableID: " + tableID);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int extractTypeOrdinal(long compositeID) {
|
||||
return (int) (compositeID >>> 32);
|
||||
}
|
||||
public static int extractTableID(int type, long compositeID) {
|
||||
if (type == 0 || compositeID == 0L) {
|
||||
return -1;
|
||||
}
|
||||
return (int) compositeID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Abstract Methods
|
||||
*/
|
||||
|
||||
public abstract void updateDatabase();
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.Enum.GameObjectType;
|
||||
import engine.Enum.ModType;
|
||||
import engine.Enum.SourceType;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.ai.MobileFSM.STATE;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.PetMsg;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
|
||||
private boolean assist = false;
|
||||
private AbstractCharacter callForHelpAggro = null;
|
||||
private int type = 0; //Mob: 0, Pet: 1, Guard: 2
|
||||
protected Vector3fImmutable lastBindLoc;
|
||||
private boolean clearAggro = false;
|
||||
|
||||
|
||||
public AbstractIntelligenceAgent(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
}
|
||||
|
||||
public AbstractIntelligenceAgent(ResultSet rs, boolean isPlayer)
|
||||
throws SQLException {
|
||||
super(rs, isPlayer);
|
||||
}
|
||||
|
||||
|
||||
public AbstractIntelligenceAgent(ResultSet rs,
|
||||
int UUID) throws SQLException {
|
||||
super(rs, UUID);
|
||||
}
|
||||
|
||||
public AbstractIntelligenceAgent( String firstName,
|
||||
String lastName, short statStrCurrent, short statDexCurrent,
|
||||
short statConCurrent, short statIntCurrent, short statSpiCurrent,
|
||||
short level, int exp, boolean sit, boolean walk, boolean combat,
|
||||
Vector3fImmutable bindLoc, Vector3fImmutable currentLoc, Vector3fImmutable faceDir,
|
||||
short healthCurrent, short manaCurrent, short stamCurrent,
|
||||
Guild guild, byte runningTrains) {
|
||||
super(firstName, lastName, statStrCurrent, statDexCurrent, statConCurrent,
|
||||
statIntCurrent, statSpiCurrent, level, exp, bindLoc,
|
||||
currentLoc, faceDir, guild,
|
||||
runningTrains);
|
||||
}
|
||||
|
||||
public AbstractIntelligenceAgent(String firstName,
|
||||
String lastName, short statStrCurrent, short statDexCurrent,
|
||||
short statConCurrent, short statIntCurrent, short statSpiCurrent,
|
||||
short level, int exp, boolean sit, boolean walk, boolean combat,
|
||||
Vector3fImmutable bindLoc, Vector3fImmutable currentLoc, Vector3fImmutable faceDir,
|
||||
short healthCurrent, short manaCurrent, short stamCurrent,
|
||||
Guild guild, byte runningTrains, int newUUID) {
|
||||
super(firstName, lastName, statStrCurrent, statDexCurrent, statConCurrent,
|
||||
statIntCurrent, statSpiCurrent, level, exp, bindLoc,
|
||||
currentLoc, faceDir, guild,
|
||||
runningTrains, newUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectTypeMask(int mask) {
|
||||
mask |= MBServerStatics.MASK_IAGENT;
|
||||
super.setObjectTypeMask(mask);
|
||||
}
|
||||
|
||||
/* AI Job Management */
|
||||
|
||||
public MobBase getMobBase() {
|
||||
|
||||
if (this.getObjectType().equals(GameObjectType.Mob))
|
||||
return this.getMobBase();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setCallForHelpAggro(AbstractCharacter ac) {
|
||||
this.callForHelpAggro = ac;
|
||||
}
|
||||
|
||||
public AbstractCharacter getCallForHelpAggro() {
|
||||
return callForHelpAggro;
|
||||
}
|
||||
|
||||
public void setMob() {
|
||||
this.type = 0;
|
||||
}
|
||||
|
||||
public void setPet(PlayerCharacter owner, boolean summoned) {
|
||||
if (summoned)
|
||||
this.type = 1; //summoned
|
||||
else
|
||||
this.type = 2; //charmed
|
||||
if (this.getObjectType().equals(GameObjectType.Mob)) {
|
||||
((Mob)this).setOwner(owner);
|
||||
}
|
||||
}
|
||||
|
||||
public void setGuard() {
|
||||
this.type = 3;
|
||||
}
|
||||
|
||||
public boolean isMob() {
|
||||
return (this.type == 0);
|
||||
}
|
||||
|
||||
public boolean isPet() {
|
||||
return (this.type == 1 || this.type == 2);
|
||||
}
|
||||
|
||||
public boolean isSummonedPet() {
|
||||
return (this.type == 1);
|
||||
}
|
||||
|
||||
public boolean isCharmedPet() {
|
||||
return (this.type == 2);
|
||||
}
|
||||
|
||||
public boolean isGuard() {
|
||||
return (this.type == 3);
|
||||
}
|
||||
|
||||
public boolean assist() {
|
||||
return this.assist;
|
||||
}
|
||||
|
||||
public void setAssist(boolean value) {
|
||||
this.assist = value;
|
||||
}
|
||||
|
||||
public void toggleAssist() {
|
||||
this.assist = (this.assist) ? false : true;
|
||||
}
|
||||
|
||||
public int getDBID() {
|
||||
|
||||
if (this.getObjectType().equals(GameObjectType.Mob))
|
||||
return this.getDBID();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean clearAggro() {
|
||||
return clearAggro;
|
||||
}
|
||||
|
||||
public void setClearAggro(boolean value) {
|
||||
this.clearAggro = value;
|
||||
}
|
||||
|
||||
public Vector3fImmutable getLastBindLoc() {
|
||||
if (this.lastBindLoc == null)
|
||||
this.lastBindLoc = this.getBindLoc();
|
||||
return this.lastBindLoc;
|
||||
}
|
||||
|
||||
public PlayerCharacter getOwner() {
|
||||
|
||||
if (this .getObjectType().equals(GameObjectType.Mob))
|
||||
return this.getOwner();
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean getSafeZone() {
|
||||
ArrayList<Zone>allIn = ZoneManager.getAllZonesIn(this.getLoc());
|
||||
for (Zone zone : allIn) {
|
||||
if (zone.getSafeZone() == (byte)1)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
//return this.safeZone;
|
||||
}
|
||||
|
||||
public abstract AbstractWorldObject getFearedObject();
|
||||
|
||||
public float getAggroRange() {
|
||||
float ret = MBServerStatics.AI_BASE_AGGRO_RANGE;
|
||||
if (this.bonuses != null)
|
||||
ret *= (1 +this.bonuses.getFloatPercentAll(ModType.ScanRange, SourceType.None));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
|
||||
if (this.isPet()) {
|
||||
|
||||
if (this.isSummonedPet()) { //delete summoned pet
|
||||
|
||||
WorldGrid.RemoveWorldObject(this);
|
||||
if (this.getObjectType() == GameObjectType.Mob){
|
||||
((Mob)this).setState(STATE.Disabled);
|
||||
if (((Mob)this).getParentZone() != null)
|
||||
((Mob)this).getParentZone().zoneMobSet.remove(this);
|
||||
}
|
||||
|
||||
} else { //revert charmed pet
|
||||
this.setMob();
|
||||
this.setCombatTarget(null);
|
||||
// if (this.isAlive())
|
||||
// WorldServer.updateObject(this);
|
||||
}
|
||||
//clear owner
|
||||
PlayerCharacter owner = this.getOwner();
|
||||
|
||||
//close pet window
|
||||
if (owner != null) {
|
||||
Mob pet = owner.getPet();
|
||||
PetMsg pm = new PetMsg(5, null);
|
||||
Dispatch dispatch = Dispatch.borrow(owner, pm);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
|
||||
|
||||
if (pet != null && pet.getObjectUUID() == this.getObjectUUID())
|
||||
owner.setPet(null);
|
||||
|
||||
if (this.getObjectType().equals(GameObjectType.Mob))
|
||||
((Mob)this).setOwner(null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,638 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.DispatchChannel;
|
||||
import engine.Enum.EffectSourceType;
|
||||
import engine.Enum.GameObjectType;
|
||||
import engine.Enum.GridObjectType;
|
||||
import engine.InterestManagement.HeightMap;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.job.AbstractScheduleJob;
|
||||
import engine.job.JobContainer;
|
||||
import engine.job.JobScheduler;
|
||||
import engine.jobs.NoTimeJob;
|
||||
import engine.math.AtomicFloat;
|
||||
import engine.math.Bounds;
|
||||
import engine.math.Vector3f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.UpdateEffectsMsg;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
public abstract class AbstractWorldObject extends AbstractGameObject {
|
||||
|
||||
private String name = "";
|
||||
|
||||
protected final ReadWriteLock locationLock = new ReentrantReadWriteLock(true);
|
||||
protected final ReadWriteLock updateLock = new ReentrantReadWriteLock(true);
|
||||
|
||||
protected Vector3fImmutable loc = new Vector3fImmutable(0.0f, 0.0f, 0.0f);
|
||||
private byte tier = 0;
|
||||
private Vector3f rot = new Vector3f(0.0f, 0.0f, 0.0f);
|
||||
protected AtomicFloat health = new AtomicFloat();
|
||||
public float healthMax;
|
||||
protected boolean load = true;
|
||||
protected ConcurrentHashMap<String, Effect> effects = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private int objectTypeMask = 0;
|
||||
private Bounds bounds;
|
||||
|
||||
public int gridX = -1;
|
||||
public int gridZ = -1;
|
||||
|
||||
protected GridObjectType gridObjectType;
|
||||
|
||||
protected float altitude = 0;
|
||||
protected Regions region;
|
||||
protected boolean movingUp = false;
|
||||
public Regions landingRegion = null;
|
||||
public Vector3fImmutable lastLoc = Vector3fImmutable.ZERO;
|
||||
|
||||
/**
|
||||
* No Id Constructor
|
||||
*/
|
||||
public AbstractWorldObject() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public AbstractWorldObject(int objectUUID) {
|
||||
super(objectUUID);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public AbstractWorldObject(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
}
|
||||
|
||||
//this should be called to handle any after load functions.
|
||||
public abstract void runAfterLoad();
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public float getHealth() {
|
||||
|
||||
|
||||
return this.health.get();
|
||||
|
||||
}
|
||||
public float getCurrentHitpoints(){
|
||||
return this.health.get();
|
||||
}
|
||||
|
||||
public float getHealthMax() {
|
||||
return this.healthMax;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<String, Effect> getEffects() {
|
||||
return this.effects;
|
||||
}
|
||||
|
||||
//Add new effect
|
||||
public void addEffect(String name, int duration, AbstractScheduleJob asj, EffectsBase eb, int trains) {
|
||||
|
||||
if (!isAlive() && eb.getToken() != 1672601862) {
|
||||
return;
|
||||
}
|
||||
JobContainer jc = JobScheduler.getInstance().scheduleJob(asj, duration);
|
||||
Effect eff = new Effect(jc, eb, trains);
|
||||
this.effects.put(name, eff);
|
||||
applyAllBonuses();
|
||||
}
|
||||
|
||||
public Effect addEffectNoTimer(String name, EffectsBase eb, int trains, boolean isStatic) {
|
||||
NoTimeJob ntj = new NoTimeJob(this, name, eb, trains); //infinite timer
|
||||
|
||||
if (this.getObjectType() == GameObjectType.Item || this.getObjectType() == GameObjectType.City){
|
||||
ntj.setEffectSourceType(this.getObjectType().ordinal());
|
||||
ntj.setEffectSourceID(this.getObjectUUID());
|
||||
}
|
||||
|
||||
JobContainer jc = new JobContainer(ntj);
|
||||
Effect eff = new Effect(jc, eb, trains);
|
||||
if (isStatic)
|
||||
eff.setIsStatic(isStatic);
|
||||
this.effects.put(name, eff);
|
||||
applyAllBonuses();
|
||||
return eff;
|
||||
}
|
||||
|
||||
//called when an effect runs it's course
|
||||
public void endEffect(String name) {
|
||||
|
||||
Effect eff = this.effects.get(name);
|
||||
if (eff == null) {
|
||||
return;
|
||||
}
|
||||
if (!isAlive() && eff.getEffectsBase().getToken() != 1672601862) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (eff.cancel()) {
|
||||
|
||||
eff.endEffect();
|
||||
this.effects.remove(name);
|
||||
if (this.getObjectType().equals(GameObjectType.PlayerCharacter))
|
||||
if (name.equals("Flight")){
|
||||
((PlayerCharacter)this).update();
|
||||
PlayerCharacter.GroundPlayer((PlayerCharacter)this);
|
||||
}
|
||||
}
|
||||
applyAllBonuses();
|
||||
}
|
||||
|
||||
public void endEffectNoPower(String name) {
|
||||
|
||||
Effect eff = this.effects.get(name);
|
||||
if (eff == null) {
|
||||
return;
|
||||
}
|
||||
if (!isAlive() && eff.getEffectsBase().getToken() != 1672601862) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (eff.cancel()) {
|
||||
eff.cancelJob();
|
||||
eff.endEffectNoPower();
|
||||
this.effects.remove(name);
|
||||
}
|
||||
applyAllBonuses();
|
||||
}
|
||||
|
||||
//Called to cancel an effect prematurely.
|
||||
public void cancelEffect(String name, boolean overwrite) {
|
||||
|
||||
Effect eff = this.effects.get(name);
|
||||
if (eff == null) {
|
||||
return;
|
||||
}
|
||||
if (!isAlive() && eff.getEffectsBase().getToken() != 1672601862) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (eff.cancel()) {
|
||||
eff.cancelJob();
|
||||
this.effects.remove(name);
|
||||
if (AbstractWorldObject.IsAbstractCharacter(this)) {
|
||||
((AbstractCharacter) this).cancelLastChantIfSame(eff);
|
||||
}
|
||||
}
|
||||
if (!overwrite) {
|
||||
applyAllBonuses();
|
||||
}
|
||||
}
|
||||
|
||||
//Called when an object dies/is destroyed
|
||||
public void clearEffects() {
|
||||
for (String name : this.effects.keySet()) {
|
||||
Effect eff = this.effects.get(name);
|
||||
if (eff == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Dont remove deathshroud here!
|
||||
if (eff.getEffectToken() == 1672601862)
|
||||
continue;
|
||||
|
||||
if (eff.cancel()) {
|
||||
if (eff.getPower() == null) {
|
||||
if (!eff.isStatic())
|
||||
eff.endEffectNoPower();
|
||||
}
|
||||
if (!eff.isStatic())
|
||||
eff.cancelJob();
|
||||
}
|
||||
|
||||
this.effects.remove(name);
|
||||
}
|
||||
if (AbstractWorldObject.IsAbstractCharacter(this)) {
|
||||
((AbstractCharacter) this).cancelLastChant();
|
||||
}
|
||||
applyAllBonuses();
|
||||
}
|
||||
|
||||
public void removeEffectBySource(EffectSourceType source, int trains, boolean removeAll) {
|
||||
if (!isAlive() && source.equals(EffectSourceType.DeathShroud) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
//hacky way to dispell trebs.
|
||||
if (this.getObjectType() == GameObjectType.Mob){
|
||||
Mob mob = (Mob)this;
|
||||
if (mob.isSiege()){
|
||||
if (mob.isPet()){
|
||||
PlayerCharacter petOwner = mob.getOwner();
|
||||
if (petOwner != null && source.equals(EffectSourceType.Effect)){
|
||||
petOwner.dismissPet();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean changed = false;
|
||||
String toRemove = "";
|
||||
int toRemoveToken = Integer.MAX_VALUE;
|
||||
for (String name : this.effects.keySet()) {
|
||||
Effect eff = this.effects.get(name);
|
||||
if (eff == null) {
|
||||
continue;
|
||||
}
|
||||
if (eff.containsSource(source) && trains >= eff.getTrains()) {
|
||||
if (removeAll) {
|
||||
//remove all effects of source type
|
||||
if (eff.cancel()) {
|
||||
eff.cancelJob();
|
||||
}
|
||||
this.effects.remove(name);
|
||||
changed = true;
|
||||
|
||||
if (source.equals("Flight")){
|
||||
//ground player
|
||||
if (this.getObjectType().equals(GameObjectType.PlayerCharacter)){
|
||||
((PlayerCharacter)this).update();
|
||||
PlayerCharacter.GroundPlayer((PlayerCharacter)this);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//find lowest token of source type to remove
|
||||
int tok = eff.getEffectToken();
|
||||
if (tok != 0 && tok < toRemoveToken) {
|
||||
toRemove = name;
|
||||
toRemoveToken = tok;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//WTF IS THIS?
|
||||
if (toRemoveToken < Integer.MAX_VALUE && this.effects.containsKey(toRemove)) {
|
||||
//remove lowest found token of source type
|
||||
Effect eff = this.effects.get(toRemove);
|
||||
if (eff != null) {
|
||||
changed = true;
|
||||
if (eff.cancel()) {
|
||||
eff.cancelJob();
|
||||
}
|
||||
this.effects.remove(toRemove);
|
||||
|
||||
if (source.equals("Flight")){
|
||||
//ground player
|
||||
if (this.getObjectType().equals(GameObjectType.PlayerCharacter)){
|
||||
((PlayerCharacter)this).update();
|
||||
PlayerCharacter.GroundPlayer((PlayerCharacter)this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
applyAllBonuses();
|
||||
}
|
||||
}
|
||||
|
||||
public void sendAllEffects(ClientConnection cc) {
|
||||
UpdateEffectsMsg msg = new UpdateEffectsMsg(this);
|
||||
Dispatch dispatch = Dispatch.borrow((PlayerCharacter)this, msg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
|
||||
}
|
||||
|
||||
public void applyAllBonuses() {
|
||||
if (AbstractWorldObject.IsAbstractCharacter(this)) {
|
||||
((AbstractCharacter) this).applyBonuses();
|
||||
}
|
||||
}
|
||||
|
||||
public JobContainer getEffectJobContainer(String name) {
|
||||
Effect ef = this.effects.get(name);
|
||||
if (ef != null) {
|
||||
return ef.getJobContainer();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public AbstractScheduleJob getEffectJob(String name) {
|
||||
Effect ef = this.effects.get(name);
|
||||
if (ef == null) {
|
||||
return null;
|
||||
}
|
||||
JobContainer jc = ef.getJobContainer();
|
||||
if (jc != null) {
|
||||
return (AbstractScheduleJob) jc.getJob();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean containsEffect(int token) {
|
||||
for (Effect eff : this.effects.values()) {
|
||||
if (eff != null) {
|
||||
if (eff.getEffectsBase() != null) {
|
||||
if (eff.getEffectsBase().getToken() == token) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getObjectTypeMask() {
|
||||
return objectTypeMask;
|
||||
}
|
||||
|
||||
|
||||
public Vector3fImmutable getLoc() {
|
||||
return this.loc;
|
||||
}
|
||||
|
||||
public Vector3f getRot() {
|
||||
return rot;
|
||||
}
|
||||
|
||||
public byte getTier() {
|
||||
return tier;
|
||||
}
|
||||
|
||||
public boolean isAlive() {
|
||||
if (AbstractWorldObject.IsAbstractCharacter(this)) {
|
||||
return this.isAlive();
|
||||
} else if (this.getObjectType().equals(GameObjectType.Building)) {
|
||||
return (!(((Building) this).getRank() < 0));
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setters
|
||||
*/
|
||||
public void setObjectTypeMask(int mask) {
|
||||
this.objectTypeMask = mask;
|
||||
}
|
||||
|
||||
//TODO return false if something goes wrong? resync player?
|
||||
public void setLoc(Vector3fImmutable loc) {
|
||||
locationLock.writeLock().lock();
|
||||
try {
|
||||
if (Float.isNaN(loc.x) || Float.isNaN(loc.z))
|
||||
return;
|
||||
|
||||
if (loc.equals(Vector3fImmutable.ZERO))
|
||||
return;
|
||||
|
||||
if (loc.x > MBServerStatics.MAX_WORLD_WIDTH || loc.z < MBServerStatics.MAX_WORLD_HEIGHT)
|
||||
return;
|
||||
this.lastLoc = new Vector3fImmutable(this.loc);
|
||||
this.loc = loc;
|
||||
this.loc = this.loc.setY(HeightMap.getWorldHeight(this) + this.getAltitude());
|
||||
|
||||
//lets not add mob to world grid if he is currently despawned.
|
||||
if (this.getObjectType().equals(GameObjectType.Mob) && ((Mob)this).despawned)
|
||||
return;
|
||||
|
||||
//do not add objectUUID 0 to world grid. dunno da fuck this doing why its doing but its doing... da fuck.
|
||||
if (this.getObjectUUID() == 0)
|
||||
return;
|
||||
WorldGrid.addObject(this,loc.x,loc.z);
|
||||
|
||||
}catch(Exception e){
|
||||
Logger.error("Failed to set location for World Object. Type = " + this.getObjectType().name() + " : Name = " + this.getName());
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
locationLock.writeLock().unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setY(float y){
|
||||
this.loc = this.loc.setY(y);
|
||||
}
|
||||
|
||||
|
||||
public void setRot(Vector3f rotation) {
|
||||
synchronized (this.rot) {
|
||||
this.rot = rotation;
|
||||
}
|
||||
}
|
||||
|
||||
public void setTier(byte tier) {
|
||||
synchronized (this.rot) {
|
||||
this.tier = tier;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getType() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean load() {
|
||||
return this.load;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utils
|
||||
*/
|
||||
public String getName() {
|
||||
if (this.name.length() == 0) {
|
||||
return "Unnamed " + '('
|
||||
+ this.getObjectUUID() + ')';
|
||||
} else {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
public String getSimpleName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the bounds
|
||||
*/
|
||||
public Bounds getBounds() {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
public void setBounds(Bounds bounds) {
|
||||
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param health the health to set
|
||||
*/
|
||||
public void setHealth(float health) {
|
||||
|
||||
this.health.set(health);
|
||||
}
|
||||
|
||||
public static boolean IsAbstractCharacter(AbstractWorldObject awo){
|
||||
|
||||
if (awo == null)
|
||||
return false;
|
||||
|
||||
if (awo.getObjectType() == GameObjectType.PlayerCharacter || awo.getObjectType() == GameObjectType.Mob || awo.getObjectType() == GameObjectType.NPC)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void RemoveFromWorldGrid(AbstractWorldObject gridObjectToRemove){
|
||||
if (gridObjectToRemove.gridX < 0 || gridObjectToRemove.gridZ < 0)
|
||||
return;
|
||||
|
||||
ConcurrentHashMap<Integer,AbstractWorldObject> gridMap;
|
||||
switch(gridObjectToRemove.gridObjectType){
|
||||
case STATIC:
|
||||
gridMap = WorldGrid.StaticGridMap[gridObjectToRemove.gridX][gridObjectToRemove.gridZ];
|
||||
break;
|
||||
case DYNAMIC:
|
||||
gridMap = WorldGrid.DynamicGridMap[gridObjectToRemove.gridX][gridObjectToRemove.gridZ];
|
||||
break;
|
||||
default:
|
||||
gridMap = WorldGrid.StaticGridMap[gridObjectToRemove.gridX][gridObjectToRemove.gridZ];
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (gridMap == null){
|
||||
Logger.info("Null gridmap for Object UUD: " + gridObjectToRemove);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
gridMap.remove(gridObjectToRemove.getObjectUUID());
|
||||
gridObjectToRemove.gridX = -1;
|
||||
gridObjectToRemove.gridZ = -1;
|
||||
|
||||
}
|
||||
|
||||
public static boolean AddToWorldGrid(AbstractWorldObject gridObjectToAdd, int x, int z){
|
||||
try{
|
||||
|
||||
ConcurrentHashMap<Integer,AbstractWorldObject> gridMap;
|
||||
if (gridObjectToAdd.gridObjectType.equals(GridObjectType.STATIC))
|
||||
gridMap = WorldGrid.StaticGridMap[x][z];
|
||||
else
|
||||
gridMap = WorldGrid.DynamicGridMap[x][z];
|
||||
|
||||
gridMap.put(gridObjectToAdd.getObjectUUID(),gridObjectToAdd);
|
||||
gridObjectToAdd.gridX = x;
|
||||
gridObjectToAdd.gridZ = z;
|
||||
return true;
|
||||
}catch(Exception e){
|
||||
Logger.error(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Regions GetRegionByWorldObject(AbstractWorldObject worldObject){
|
||||
Regions region = null;
|
||||
|
||||
if (worldObject.getObjectType().equals(GameObjectType.PlayerCharacter))
|
||||
if (((PlayerCharacter)worldObject).isFlying())
|
||||
return null;
|
||||
//Find building
|
||||
for (AbstractWorldObject awo:WorldGrid.getObjectsInRangePartial(worldObject.getLoc(), MBServerStatics.STRUCTURE_LOAD_RANGE, MBServerStatics.MASK_BUILDING)){
|
||||
Building building = (Building)awo;
|
||||
if (!Bounds.collide(worldObject.getLoc(), building.getBounds()))
|
||||
continue;
|
||||
|
||||
//find regions that intersect x and z, check if object can enter.
|
||||
for (Regions toEnter: building.getBounds().getRegions()){
|
||||
if (toEnter.isPointInPolygon(worldObject.getLoc())){
|
||||
if (Regions.CanEnterRegion(worldObject, toEnter))
|
||||
if (region == null)
|
||||
region = toEnter;
|
||||
else // we're using a low level to high level tree structure, database not always in order low to high.
|
||||
//check for highest level index.
|
||||
if(region != null && toEnter.highLerp.y > region.highLerp.y)
|
||||
region = toEnter;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//set players new altitude to region lerp altitude.
|
||||
if (region != null)
|
||||
if (region.center.y == region.highLerp.y)
|
||||
worldObject.loc = worldObject.loc.setY(region.center.y + worldObject.getAltitude());
|
||||
else
|
||||
worldObject.loc = worldObject.loc.setY(region.lerpY(worldObject) + worldObject.getAltitude());
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
public static Regions GetRegionFromBuilding(Vector3fImmutable worldLoc, Building building){
|
||||
Regions region = null;
|
||||
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
public float getAltitude() {
|
||||
return altitude;
|
||||
}
|
||||
|
||||
|
||||
public ReadWriteLock getUpdateLock() {
|
||||
return updateLock;
|
||||
}
|
||||
|
||||
public GridObjectType getGridObjectType() {
|
||||
return gridObjectType;
|
||||
}
|
||||
|
||||
public Regions getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMovingUp() {
|
||||
return movingUp;
|
||||
}
|
||||
|
||||
public void setMovingUp(boolean movingUp) {
|
||||
this.movingUp = movingUp;
|
||||
}
|
||||
|
||||
public void setRegion(Regions region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
//used for interestmanager loading and unloading objects to client.
|
||||
// if not in grid, unload from player.
|
||||
public boolean isInWorldGrid(){
|
||||
if (this.gridX == -1 && this.gridZ == -1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,390 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.Enum.DispatchChannel;
|
||||
import engine.Enum.ItemContainerType;
|
||||
import engine.gameManager.ConfigManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.SessionManager;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.ClientMessagePump;
|
||||
import engine.net.client.msg.*;
|
||||
import engine.util.ByteUtils;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class Account extends AbstractGameObject {
|
||||
|
||||
private final String uname;
|
||||
private String passwd;
|
||||
private int lastCharIDUsed;
|
||||
private String salt;
|
||||
public String discordAccount;
|
||||
private byte loginAttempts = 0;
|
||||
private long lastLoginFailure = System.currentTimeMillis();
|
||||
public HashMap<Integer, PlayerCharacter> characterMap = new HashMap<>();
|
||||
public static ConcurrentHashMap<String, Integer> AccountsMap = new ConcurrentHashMap<>();
|
||||
private ArrayList<Item> vault = new ArrayList<>();
|
||||
public Item vaultGold = null;
|
||||
public long lastPasswordCheck = 0;
|
||||
public Enum.AccountStatus status;
|
||||
|
||||
public ArrayList<Item> getVault() {
|
||||
return vault;
|
||||
}
|
||||
|
||||
public Account(ResultSet resultSet) throws SQLException {
|
||||
super(resultSet);
|
||||
|
||||
this.uname = resultSet.getString("acct_uname");
|
||||
this.passwd = resultSet.getString("acct_passwd");
|
||||
this.lastCharIDUsed = resultSet.getInt("acct_lastCharUID");
|
||||
this.salt = resultSet.getString("acct_salt");
|
||||
this.discordAccount = resultSet.getString("discordAccount");
|
||||
this.status = Enum.AccountStatus.valueOf(resultSet.getString("status"));
|
||||
}
|
||||
|
||||
public String getUname() {
|
||||
return uname;
|
||||
}
|
||||
|
||||
public String getPasswd() {
|
||||
return passwd;
|
||||
}
|
||||
|
||||
public String getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
public int getLastCharIDUsed() {
|
||||
return lastCharIDUsed;
|
||||
}
|
||||
|
||||
public byte getLoginAttempts() {
|
||||
return loginAttempts;
|
||||
}
|
||||
|
||||
public long getLastLoginFailure() {
|
||||
return this.lastLoginFailure;
|
||||
}
|
||||
|
||||
public void setLastCharIDUsed(int lastCharIDUsed) {
|
||||
this.lastCharIDUsed = lastCharIDUsed;
|
||||
}
|
||||
|
||||
public void setLastLoginFailure() {
|
||||
this.lastLoginFailure = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void setLastCharacter(int uuid) {
|
||||
this.lastCharIDUsed = uuid;
|
||||
// this.updateDatabase();
|
||||
}
|
||||
|
||||
public void incrementLoginAttempts() {
|
||||
++this.loginAttempts;
|
||||
this.setLastLoginFailure();
|
||||
}
|
||||
|
||||
public void resetLoginAttempts() {
|
||||
this.loginAttempts = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* on successfully matching the password, this method additionally calls to
|
||||
* associateIpToAccount for IPAddress tracking. dokks
|
||||
*/
|
||||
public boolean passIsValid(String pw, String ip, String machineID) throws IllegalArgumentException {
|
||||
boolean result = false;
|
||||
// see if it was entered in plain text first, if the plain text matches,
|
||||
// hash it and save to the database.
|
||||
try {
|
||||
pw = ByteUtils.byteArrayToSafeStringHex(MessageDigest
|
||||
.getInstance("md5").digest(pw.getBytes("UTF-8")))
|
||||
+ salt;
|
||||
pw = ByteUtils.byteArrayToSafeStringHex(MessageDigest
|
||||
.getInstance("md5").digest(pw.getBytes()));
|
||||
result = this.passwd.equals(pw);
|
||||
} catch ( NoSuchAlgorithmException | UnsupportedEncodingException e) {
|
||||
Logger.error( e.toString());
|
||||
}
|
||||
|
||||
if (result) {
|
||||
// TODO: should use an executor here so that we can
|
||||
// fire and forget this update.
|
||||
// this is a valid user, so let's also update the
|
||||
// database with login time and IP.
|
||||
if((ip==null)||(ip.length()==0)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public ClientConnection getClientConnection() {
|
||||
return SessionManager.getClientConnection(this);
|
||||
}
|
||||
|
||||
public PlayerCharacter getPlayerCharacter() {
|
||||
return SessionManager.getPlayerCharacter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
DbManager.AccountQueries.updateDatabase(this);
|
||||
}
|
||||
|
||||
//this should be called to handle any after load functions.
|
||||
|
||||
public void runAfterLoad() {
|
||||
|
||||
try {
|
||||
|
||||
if (ConfigManager.serverType.equals(Enum.ServerType.LOGINSERVER)){
|
||||
ArrayList<PlayerCharacter> playerList = DbManager.PlayerCharacterQueries.GET_CHARACTERS_FOR_ACCOUNT(this.getObjectUUID());
|
||||
|
||||
for(PlayerCharacter player:playerList) {
|
||||
PlayerCharacter.initializePlayer(player);
|
||||
this.characterMap.putIfAbsent(player.getObjectUUID(), player);
|
||||
}
|
||||
|
||||
playerList.clear();
|
||||
}
|
||||
|
||||
if (ConfigManager.serverType.equals(Enum.ServerType.WORLDSERVER)) {
|
||||
this.vault = DbManager.ItemQueries.GET_ITEMS_FOR_ACCOUNT(this.getObjectUUID());
|
||||
|
||||
for (Item item : this.vault) {
|
||||
if (item.getItemBase().getUUID() == 7) {
|
||||
this.vaultGold = item;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.vaultGold == null) {
|
||||
this.vaultGold = Item.newGoldItem(this.getObjectUUID(), ItemBase.getItemBase(7), ItemContainerType.VAULT);
|
||||
|
||||
if (this.vaultGold != null)
|
||||
this.vault.add(this.vaultGold);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error( e);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void transferItemFromInventoryToVault(TransferItemFromInventoryToVaultMsg msg, ClientConnection origin) {
|
||||
|
||||
PlayerCharacter player = origin.getPlayerCharacter();
|
||||
Dispatch dispatch;
|
||||
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
if (!ClientMessagePump.NPCVaultBankRangeCheck(player, origin, "vault")) {
|
||||
ClientMessagePump.forceTransferFromVaultToInventory(msg, origin, "You are out of range of the vault.");
|
||||
return;
|
||||
}
|
||||
|
||||
int uuid = msg.getUUID();
|
||||
Item item = Item.getFromCache(uuid);
|
||||
|
||||
if (item == null) {
|
||||
ClientMessagePump.forceTransferFromVaultToInventory(msg, origin, "Can't find the item.");
|
||||
return;
|
||||
}
|
||||
|
||||
//dupe check
|
||||
if (!item.validForInventory(origin, player, player.getCharItemManager()))
|
||||
return;
|
||||
|
||||
if (item.containerType == Enum.ItemContainerType.INVENTORY && player.getCharItemManager().isVaultOpen()) {
|
||||
if (!player.getCharItemManager().hasRoomVault(item.getItemBase().getWeight())) {
|
||||
ClientMessagePump.forceTransferFromVaultToInventory(msg, origin, "There is no room in your vault.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getCharItemManager().moveItemToVault(item)) {
|
||||
this.vault.add(item);
|
||||
dispatch = Dispatch.borrow(player, msg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
|
||||
} else
|
||||
ClientMessagePump.forceTransferFromVaultToInventory(msg, origin, "Failed to transfer item.");
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void transferItemFromVaultToInventory(TransferItemFromVaultToInventoryMsg msg, ClientConnection origin) {
|
||||
|
||||
PlayerCharacter player = origin.getPlayerCharacter();
|
||||
Dispatch dispatch;
|
||||
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
if (!ClientMessagePump.NPCVaultBankRangeCheck(player, origin, "vault")) {
|
||||
ClientMessagePump.forceTransferFromInventoryToVault(msg, origin, "You are out of range of the vault.");
|
||||
return;
|
||||
}
|
||||
|
||||
CharacterItemManager itemManager = player.getCharItemManager();
|
||||
|
||||
if (itemManager == null) {
|
||||
ClientMessagePump.forceTransferFromInventoryToVault(msg, origin, "Can't find your item manager.");
|
||||
return;
|
||||
}
|
||||
|
||||
Item item = Item.getFromCache(msg.getUUID());
|
||||
|
||||
if (item == null) {
|
||||
ClientMessagePump.forceTransferFromInventoryToVault(msg, origin, "Can't find the item.");
|
||||
return;
|
||||
}
|
||||
|
||||
//dupe check
|
||||
if (!item.validForVault(origin, player, itemManager))
|
||||
return;
|
||||
|
||||
if (item.containerType == Enum.ItemContainerType.VAULT && itemManager.isVaultOpen()) {
|
||||
if (!itemManager.hasRoomInventory(item.getItemBase().getWeight())) {
|
||||
ClientMessagePump.forceTransferFromInventoryToVault(msg, origin, "There is no room in your inventory.");
|
||||
return;
|
||||
}
|
||||
if (itemManager.moveItemToInventory(item)) {
|
||||
this.vault.remove(item);
|
||||
|
||||
dispatch = Dispatch.borrow(player, msg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
|
||||
|
||||
} else
|
||||
ClientMessagePump.forceTransferFromInventoryToVault(msg, origin, "Failed to transfer item.");
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void transferGoldFromVaultToInventory(TransferGoldFromVaultToInventoryMsg msg, ClientConnection origin) {
|
||||
|
||||
PlayerCharacter player = origin.getPlayerCharacter();
|
||||
Dispatch dispatch;
|
||||
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
Account account = player.getAccount();
|
||||
|
||||
if (account == null)
|
||||
return;
|
||||
|
||||
if (!ClientMessagePump.NPCVaultBankRangeCheck(player, origin, "vault"))
|
||||
return;
|
||||
|
||||
NPC npc = player.getLastNPCDialog();
|
||||
|
||||
if (npc == null)
|
||||
return;
|
||||
|
||||
CharacterItemManager itemManager = player.getCharItemManager();
|
||||
|
||||
if (itemManager == null)
|
||||
return;
|
||||
|
||||
if (itemManager.isVaultOpen() == false)
|
||||
return;
|
||||
|
||||
if (itemManager.moveGoldToInventory(itemManager.getGoldVault(), msg.getAmount()) == false)
|
||||
return;
|
||||
|
||||
OpenVaultMsg open = new OpenVaultMsg(player, npc);
|
||||
ShowVaultInventoryMsg show = new ShowVaultInventoryMsg(player, account, npc); // 37??
|
||||
|
||||
UpdateGoldMsg ugm = new UpdateGoldMsg(player);
|
||||
ugm.configure();
|
||||
dispatch = Dispatch.borrow(player, ugm);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
|
||||
|
||||
UpdateVaultMsg uvm = new UpdateVaultMsg(account);
|
||||
dispatch = Dispatch.borrow(player, uvm);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
|
||||
|
||||
dispatch = Dispatch.borrow(player, open);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
|
||||
|
||||
dispatch = Dispatch.borrow(player, show);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
|
||||
|
||||
}
|
||||
|
||||
public synchronized void transferGoldFromInventoryToVault(TransferGoldFromInventoryToVaultMsg msg, ClientConnection origin) {
|
||||
|
||||
PlayerCharacter player = origin.getPlayerCharacter();
|
||||
Dispatch dispatch;
|
||||
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
Account account = player.getAccount();
|
||||
|
||||
if (account == null)
|
||||
return;
|
||||
|
||||
if (!ClientMessagePump.NPCVaultBankRangeCheck(player, origin, "vault"))
|
||||
return;
|
||||
|
||||
CharacterItemManager itemManager = player.getCharItemManager();
|
||||
|
||||
if (itemManager == null)
|
||||
return;
|
||||
|
||||
NPC npc = player.getLastNPCDialog();
|
||||
|
||||
if (npc == null)
|
||||
return;
|
||||
|
||||
// Cannot have bank and vault open concurrently
|
||||
// Dupe prevention
|
||||
|
||||
if (itemManager.isVaultOpen() == false)
|
||||
return;
|
||||
|
||||
// Something went horribly wrong. Should be log this?
|
||||
|
||||
if (itemManager.moveGoldToVault(itemManager.getGoldInventory(), msg.getAmount()) == false)
|
||||
return;
|
||||
|
||||
UpdateGoldMsg ugm = new UpdateGoldMsg(player);
|
||||
ugm.configure();
|
||||
dispatch = Dispatch.borrow(player, ugm);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
|
||||
|
||||
UpdateVaultMsg uvm = new UpdateVaultMsg(account);
|
||||
dispatch = Dispatch.borrow(player, uvm);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
|
||||
|
||||
OpenVaultMsg open = new OpenVaultMsg(player, npc);
|
||||
dispatch = Dispatch.borrow(player, open);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
|
||||
//
|
||||
//
|
||||
ShowVaultInventoryMsg show = new ShowVaultInventoryMsg(player, account, npc); // 37??
|
||||
dispatch = Dispatch.borrow(player, show);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,650 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.Enum.ProtectionState;
|
||||
import engine.Enum.SiegePhase;
|
||||
import engine.Enum.SiegeResult;
|
||||
import engine.InterestManagement.HeightMap;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.db.archive.BaneRecord;
|
||||
import engine.db.archive.DataWarehouse;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.job.JobScheduler;
|
||||
import engine.jobs.ActivateBaneJob;
|
||||
import engine.jobs.BaneDefaultTimeJob;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.PlaceAssetMsg;
|
||||
import engine.net.client.msg.chat.ChatSystemMsg;
|
||||
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.Date;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public final class Bane {
|
||||
|
||||
private final int cityUUID;
|
||||
private int ownerUUID;
|
||||
private final int stoneUUID;
|
||||
private DateTime placementDate = null;
|
||||
private DateTime liveDate = null;
|
||||
private BaneDefaultTimeJob defaultTimeJob;
|
||||
private ActivateBaneJob activateBaneJob;
|
||||
|
||||
// Internal cache for banes
|
||||
|
||||
public static ConcurrentHashMap<Integer, Bane> banes = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public Bane(ResultSet rs) throws SQLException {
|
||||
|
||||
Date sqlDateTime;
|
||||
ActivateBaneJob abtj;
|
||||
|
||||
this.cityUUID = rs.getInt("cityUUID");
|
||||
this.ownerUUID = rs.getInt("ownerUUID");
|
||||
this.stoneUUID = rs.getInt("stoneUUID");
|
||||
|
||||
sqlDateTime = rs.getTimestamp("placementDate");
|
||||
|
||||
if (sqlDateTime != null)
|
||||
this.placementDate = new DateTime(sqlDateTime);
|
||||
|
||||
sqlDateTime = rs.getTimestamp("liveDate");
|
||||
|
||||
if (sqlDateTime != null)
|
||||
this.liveDate = new DateTime(sqlDateTime);
|
||||
|
||||
switch (this.getSiegePhase()) {
|
||||
|
||||
case CHALLENGE:
|
||||
break;
|
||||
case WAR:
|
||||
|
||||
// cancel old job if exists
|
||||
|
||||
if (this.activateBaneJob != null)
|
||||
this.activateBaneJob.cancelJob();
|
||||
|
||||
abtj = new ActivateBaneJob(cityUUID);
|
||||
JobScheduler.getInstance().scheduleJob(abtj, this.liveDate.getMillis());
|
||||
this.activateBaneJob = abtj;
|
||||
|
||||
break;
|
||||
case STANDOFF:
|
||||
|
||||
// cancel old job if exists
|
||||
|
||||
if (this.activateBaneJob != null)
|
||||
this.activateBaneJob.cancelJob();
|
||||
|
||||
abtj = new ActivateBaneJob(cityUUID);
|
||||
JobScheduler.getInstance().scheduleJob(abtj, this.liveDate.getMillis());
|
||||
this.activateBaneJob = abtj;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.liveDate == null)
|
||||
setDefaultTime();
|
||||
}
|
||||
|
||||
public static boolean summonBanestone(PlayerCharacter player, ClientConnection origin, int rank) {
|
||||
|
||||
Guild baningGuild;
|
||||
Zone cityZone;
|
||||
City targetCity;
|
||||
|
||||
ArrayList<Bane> nationBanes;
|
||||
|
||||
baningGuild = player.getGuild();
|
||||
|
||||
if (baningGuild.getNation().isErrant()) {
|
||||
PlaceAssetMsg.sendPlaceAssetError( origin, 55, ""); // You must be in a Nation
|
||||
return false;
|
||||
}
|
||||
|
||||
if (baningGuild.getNation().isNPCGuild()) {
|
||||
PlaceAssetMsg.sendPlaceAssetError( origin, 72, ""); // Cannot be in an NPC nation
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false) {
|
||||
PlaceAssetMsg.sendPlaceAssetError( origin, 10, ""); // You must be a guild leader
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cannot place banestones underwater;
|
||||
|
||||
if (HeightMap.isLocUnderwater(player.getLoc())) {
|
||||
PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater
|
||||
return false;
|
||||
}
|
||||
|
||||
// figure out which city we're standing on
|
||||
// must be within a city's seige Bounds
|
||||
|
||||
targetCity = ZoneManager.getCityAtLocation(player.getLoc());
|
||||
|
||||
if (targetCity == null) {
|
||||
PlaceAssetMsg.sendPlaceAssetError( origin, 59, ""); // No city to siege at this location!
|
||||
return false;
|
||||
}
|
||||
|
||||
if (targetCity.isSafeHold()) {
|
||||
PlaceAssetMsg.sendPlaceAssetError( origin, 15, ""); // Cannot place assets in peace zone
|
||||
return false;
|
||||
}
|
||||
|
||||
if (targetCity.getRank() > rank) {
|
||||
PlaceAssetMsg.sendPlaceAssetError( origin, 60, ""); // Bane rank is too low
|
||||
return false;
|
||||
}
|
||||
|
||||
cityZone = targetCity.getParent();
|
||||
|
||||
// Cannot place assets on a dead tree
|
||||
|
||||
if ((cityZone.isPlayerCity()) &&
|
||||
(City.getCity(cityZone.getPlayerCityUUID()).getTOL().getRank() == -1)) {
|
||||
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Cannot bane a dead tree!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (baningGuild.getNation() == targetCity.getGuild().getNation()) {
|
||||
PlaceAssetMsg.sendPlaceAssetError( origin, 20, ""); //Cannot bane yourself!
|
||||
return false;
|
||||
}
|
||||
|
||||
if (targetCity.getTOL() == null) {
|
||||
PlaceAssetMsg.sendPlaceAssetError( origin, 65, ""); // Cannot find tree to target
|
||||
return false;
|
||||
}
|
||||
|
||||
if (targetCity.getBane() != null) {
|
||||
PlaceAssetMsg.sendPlaceAssetError( origin, 23, ""); // Tree is already baned.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getBaneByAttackerGuild(baningGuild) != null) {
|
||||
PlaceAssetMsg.sendPlaceAssetError( origin, 1, "Your guild has already placed a bane!");
|
||||
return false;
|
||||
}
|
||||
|
||||
nationBanes = getBanesByNation(baningGuild.getNation());
|
||||
|
||||
// A nation can only have 3 concurrent banes
|
||||
|
||||
if (nationBanes.size() == 3) {
|
||||
PlaceAssetMsg.sendPlaceAssetError( origin, 64, ""); // Your nation is already at war and your limit has been reached
|
||||
return false;
|
||||
}
|
||||
|
||||
if (targetCity.isLocationOnCityGrid(player.getLoc()) == true) {
|
||||
PlaceAssetMsg.sendPlaceAssetError( origin, 1, "Cannot place banestone on city grid.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Blueprint blueprint = Blueprint.getBlueprint(24300); // Banestone
|
||||
|
||||
//Let's drop a banestone!
|
||||
|
||||
Vector3fImmutable localLocation = ZoneManager.worldToLocal(player.getLoc(), cityZone);
|
||||
|
||||
if (localLocation == null) {
|
||||
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
|
||||
Logger.info("Failed to Convert World coordinates to local zone coordinates");
|
||||
return false;
|
||||
}
|
||||
|
||||
Building stone = DbManager.BuildingQueries.CREATE_BUILDING(
|
||||
cityZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getBlueprintUUID(),
|
||||
localLocation, 1.0f, blueprint.getMaxHealth(rank), ProtectionState.PROTECTED, 0, rank,
|
||||
null, blueprint.getBlueprintUUID(), 1, 0.0f);
|
||||
|
||||
if (stone == null) {
|
||||
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
|
||||
return false;
|
||||
}
|
||||
|
||||
stone.addEffectBit((1 << 19));
|
||||
stone.setMaxHitPoints(stone.getBlueprint().getMaxHealth(stone.getRank()));
|
||||
stone.setCurrentHitPoints(stone.getMaxHitPoints());
|
||||
BuildingManager.setUpgradeDateTime(stone, null, 0);
|
||||
|
||||
//Make the bane
|
||||
|
||||
Bane bane = makeBane(player, targetCity, stone);
|
||||
|
||||
if (bane == null) {
|
||||
//delete bane stone, failed to make bane object
|
||||
DbManager.BuildingQueries.DELETE_FROM_DATABASE(stone);
|
||||
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldGrid.addObject(stone, player);
|
||||
|
||||
//Add bane effect to TOL
|
||||
|
||||
targetCity.getTOL().addEffectBit((1 << 16));
|
||||
targetCity.getTOL().updateEffects();
|
||||
|
||||
Vector3fImmutable movePlayerOutsideStone = player.getLoc();
|
||||
movePlayerOutsideStone = movePlayerOutsideStone.setX(movePlayerOutsideStone.x + 10);
|
||||
movePlayerOutsideStone = movePlayerOutsideStone.setZ(movePlayerOutsideStone.z + 10);
|
||||
player.teleport(movePlayerOutsideStone);
|
||||
|
||||
// Notify players
|
||||
|
||||
ChatSystemMsg chatMsg = new ChatSystemMsg(null, "[Bane Channel] " + targetCity.getCityName() + " has been baned by " + baningGuild.getName() + ". Standoff phase has begun!");
|
||||
chatMsg.setMessageType(4);
|
||||
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
|
||||
|
||||
DispatchMessage.dispatchMsgToAll(chatMsg);
|
||||
|
||||
// Push this event to the DataWarehouse
|
||||
|
||||
BaneRecord baneRecord = BaneRecord.borrow(bane, Enum.RecordEventType.PENDING);
|
||||
DataWarehouse.pushToWarehouse(baneRecord);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public SiegePhase getSiegePhase() {
|
||||
|
||||
SiegePhase phase;
|
||||
|
||||
if (this.liveDate == null) {
|
||||
phase = SiegePhase.CHALLENGE; //challenge
|
||||
return phase;
|
||||
}
|
||||
|
||||
if (DateTime.now().isAfter(this.liveDate)) {
|
||||
phase = SiegePhase.WAR; //war
|
||||
return phase;
|
||||
}
|
||||
|
||||
// If code reaches this point we are in standoff mode.
|
||||
phase = SiegePhase.STANDOFF; //standoff
|
||||
|
||||
return phase;
|
||||
}
|
||||
|
||||
private void setDefaultTime() {
|
||||
|
||||
DateTime timeToSetDefault = new DateTime(this.placementDate);
|
||||
timeToSetDefault = timeToSetDefault.plusDays(1);
|
||||
|
||||
DateTime currentTime = DateTime.now();
|
||||
DateTime defaultTime = new DateTime(this.placementDate);
|
||||
defaultTime = defaultTime.plusDays(2);
|
||||
defaultTime = defaultTime.hourOfDay().setCopy(22);
|
||||
defaultTime = defaultTime.minuteOfHour().setCopy(0);
|
||||
defaultTime = defaultTime.secondOfMinute().setCopy(0);
|
||||
|
||||
if (currentTime.isAfter(timeToSetDefault))
|
||||
this.setLiveDate(defaultTime);
|
||||
else {
|
||||
|
||||
if (this.defaultTimeJob != null)
|
||||
this.defaultTimeJob.cancelJob();
|
||||
|
||||
BaneDefaultTimeJob bdtj = new BaneDefaultTimeJob(this);
|
||||
JobScheduler.getInstance().scheduleJob(bdtj, timeToSetDefault.getMillis());
|
||||
this.defaultTimeJob = bdtj;
|
||||
}
|
||||
}
|
||||
|
||||
public void setLiveDate(DateTime baneTime) {
|
||||
|
||||
if (DbManager.BaneQueries.SET_BANE_TIME(baneTime, this.getCity().getObjectUUID())) {
|
||||
this.liveDate = new DateTime(baneTime);
|
||||
|
||||
// Push event to warehouse
|
||||
|
||||
BaneRecord.updateLiveDate(this, baneTime);
|
||||
|
||||
ChatManager.chatGuildInfo(this.getOwner().getGuild(), "The bane on " + this.getCity().getGuild().getName() + " has been set! Standoff phase has begun!");
|
||||
Guild attackerNation = this.getOwner().getGuild().getNation();
|
||||
|
||||
if (attackerNation != null)
|
||||
|
||||
for (Guild subGuild : attackerNation.getSubGuildList()) {
|
||||
|
||||
//Don't send the message twice.
|
||||
if (subGuild.equals(attackerNation))
|
||||
continue;
|
||||
|
||||
ChatManager.chatGuildInfo(subGuild, "The bane on " + this.getCity().getGuild().getName() + " has been set! Standoff phase has begun!");
|
||||
}
|
||||
|
||||
ChatManager.chatGuildInfo(this.getCity().getGuild(), "The bane on " + this.getCity().getGuild().getName() + " has been set! Standoff phase has begun!");
|
||||
|
||||
Guild defenderNation = this.getCity().getGuild().getNation();
|
||||
|
||||
if (defenderNation != null) {
|
||||
|
||||
if (defenderNation != this.getCity().getGuild())
|
||||
ChatManager.chatGuildInfo(defenderNation, "The bane on " + this.getCity().getGuild().getName() + " has been set! Standoff phase has begun!");
|
||||
|
||||
for (Guild subGuild : defenderNation.getSubGuildList()) {
|
||||
//Don't send the message twice.
|
||||
if (subGuild == this.getCity().getGuild())
|
||||
continue;
|
||||
ChatManager.chatGuildInfo(subGuild, "The bane on " + this.getCity().getGuild().getName() + " has been set! Standoff phase has begun!");
|
||||
}
|
||||
}
|
||||
|
||||
if (activateBaneJob != null)
|
||||
this.activateBaneJob.cancelJob();
|
||||
|
||||
ActivateBaneJob abtj = new ActivateBaneJob(cityUUID);
|
||||
|
||||
JobScheduler.getInstance().scheduleJob(abtj, this.liveDate.getMillis());
|
||||
this.activateBaneJob = abtj;
|
||||
} else {
|
||||
Logger.debug( "error with city " + this.getCity().getName());
|
||||
ChatManager.chatGuildInfo(this.getOwner().getGuild(), "A Serious error has occurred. Please post details for to ensure transaction integrity");
|
||||
ChatManager.chatGuildInfo(this.getCity().getGuild(), "A Serious error has occurred. Please post details for to ensure transaction integrity");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public City getCity() {
|
||||
return City.getCity(this.cityUUID);
|
||||
}
|
||||
|
||||
public PlayerCharacter getOwner() {
|
||||
return (PlayerCharacter) DbManager.getObject(Enum.GameObjectType.PlayerCharacter, ownerUUID);
|
||||
}
|
||||
|
||||
//Call this to prematurely end a bane
|
||||
|
||||
public boolean remove() {
|
||||
|
||||
Building baneStone;
|
||||
|
||||
baneStone = this.getStone();
|
||||
|
||||
if (baneStone == null) {
|
||||
Logger.debug("Removing bane without a stone.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reassert protection contracts
|
||||
|
||||
this.getCity().protectionEnforced = true;
|
||||
|
||||
// Remove visual effects on Bane and TOL.
|
||||
|
||||
this.getStone().removeAllVisualEffects();
|
||||
this.getStone().updateEffects();
|
||||
|
||||
this.getCity().getTOL().removeAllVisualEffects();
|
||||
this.getCity().getTOL().updateEffects();
|
||||
|
||||
// Remove bane from the database
|
||||
|
||||
if (DbManager.BaneQueries.REMOVE_BANE(this) == false) {
|
||||
Logger.error("Database call failed for city UUID: " + this.getCity().getObjectUUID());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove bane from ingame cache
|
||||
|
||||
Bane.banes.remove(cityUUID);
|
||||
|
||||
// Delete stone from database
|
||||
|
||||
if (DbManager.BuildingQueries.DELETE_FROM_DATABASE(baneStone) == false) {
|
||||
Logger.error( "Database error when deleting stone object");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove object from simulation
|
||||
|
||||
baneStone.removeFromCache();
|
||||
WorldGrid.RemoveWorldObject(baneStone);
|
||||
WorldGrid.removeObject(baneStone);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Cache access
|
||||
|
||||
public static Bane getBane(int cityUUID) {
|
||||
|
||||
Bane outBane;
|
||||
|
||||
// Check cache first
|
||||
|
||||
outBane = banes.get(cityUUID);
|
||||
|
||||
// Last resort attempt to load from database
|
||||
|
||||
if (outBane == null)
|
||||
outBane = DbManager.BaneQueries.LOAD_BANE(cityUUID);
|
||||
else
|
||||
return outBane;
|
||||
|
||||
// As we loaded from the db, store it in the internal cache
|
||||
|
||||
if (outBane != null)
|
||||
banes.put(cityUUID, outBane);
|
||||
|
||||
return outBane;
|
||||
}
|
||||
|
||||
//Returns a guild's bane
|
||||
|
||||
public static Bane getBaneByAttackerGuild(Guild guild) {
|
||||
|
||||
|
||||
if (guild == null || guild.isErrant())
|
||||
return null;
|
||||
ArrayList<Bane> baneList;
|
||||
|
||||
baneList = new ArrayList<>(banes.values());
|
||||
|
||||
for (Bane bane : baneList) {
|
||||
if (bane.getOwner().getGuild().equals(guild))
|
||||
return bane;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ArrayList<Bane> getBanesByNation(Guild guild) {
|
||||
|
||||
ArrayList<Bane> baneList;
|
||||
ArrayList<Bane> returnList;
|
||||
|
||||
baneList = new ArrayList<>(banes.values());
|
||||
returnList = new ArrayList<>();
|
||||
|
||||
for (Bane bane : baneList) {
|
||||
if (bane.getOwner().getGuild().getNation().equals(guild))
|
||||
returnList.add(bane);
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public static void addBane(Bane bane) {
|
||||
|
||||
Bane.banes.put(bane.cityUUID, bane);
|
||||
|
||||
}
|
||||
|
||||
public static Bane makeBane(PlayerCharacter owner, City city, Building stone) {
|
||||
|
||||
Bane newBane;
|
||||
|
||||
if (DbManager.BaneQueries.CREATE_BANE(city, owner, stone) == false) {
|
||||
Logger.error("Error writing to database");
|
||||
return null;
|
||||
}
|
||||
|
||||
newBane = DbManager.BaneQueries.LOAD_BANE(city.getObjectUUID());
|
||||
|
||||
return newBane;
|
||||
}
|
||||
|
||||
public final DateTime getPlacementDate() {
|
||||
return placementDate;
|
||||
}
|
||||
|
||||
public final boolean isAccepted() {
|
||||
|
||||
return (this.getSiegePhase() != SiegePhase.CHALLENGE);
|
||||
}
|
||||
|
||||
public final DateTime getLiveDate() {
|
||||
return liveDate;
|
||||
}
|
||||
|
||||
public final void endBane(SiegeResult siegeResult) {
|
||||
|
||||
boolean baneRemoved;
|
||||
|
||||
// No matter what the outcome of a bane, we re-asset
|
||||
// protection contracts at this time. They don't quite
|
||||
// matter if the city falls, as they are invalidated.
|
||||
|
||||
this.getCity().protectionEnforced = true;
|
||||
|
||||
switch (siegeResult) {
|
||||
case DEFEND:
|
||||
|
||||
// Push event to warehouse
|
||||
|
||||
BaneRecord.updateResolution(this, Enum.RecordEventType.DEFEND);
|
||||
|
||||
baneRemoved = remove();
|
||||
|
||||
if (baneRemoved) {
|
||||
|
||||
// Update seieges withstood
|
||||
|
||||
this.getCity().setSiegesWithstood(this.getCity().getSiegesWithstood() + 1);
|
||||
|
||||
// Notify players
|
||||
|
||||
ChatSystemMsg msg = new ChatSystemMsg(null, "[Bane Channel]" + this.getCity().getGuild().getName() + " has rallied against " + this.getOwner().getGuild().getName() + ". The siege on " + this.getCity().getCityName() + " has been broken!");
|
||||
msg.setMessageType(4);
|
||||
msg.setChannel(engine.Enum.ChatChannelType.SYSTEM.getChannelID());
|
||||
|
||||
DispatchMessage.dispatchMsgToAll(msg);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case CAPTURE:
|
||||
|
||||
// Push event to warehouse
|
||||
|
||||
BaneRecord.updateResolution(this, Enum.RecordEventType.CAPTURE);
|
||||
|
||||
baneRemoved = this.remove();
|
||||
|
||||
if (baneRemoved) {
|
||||
|
||||
ChatSystemMsg msg = new ChatSystemMsg(null, "[Bane Channel]" + this.getOwner().getGuild().getName() + " have defeated " + this.getCity().getGuild().getName() + " and captured " + this.getCity().getCityName() + '!');
|
||||
msg.setMessageType(4);
|
||||
msg.setChannel(engine.Enum.ChatChannelType.SYSTEM.getChannelID());
|
||||
|
||||
DispatchMessage.dispatchMsgToAll(msg);
|
||||
}
|
||||
break;
|
||||
case DESTROY:
|
||||
|
||||
// Push event to warehouse
|
||||
|
||||
BaneRecord.updateResolution(this, Enum.RecordEventType.DESTROY);
|
||||
|
||||
baneRemoved = this.remove();
|
||||
|
||||
if (baneRemoved) {
|
||||
|
||||
ChatSystemMsg msg = new ChatSystemMsg(null, "[Bane Channel]" + this.getOwner().getGuild().getName() + " have defeated " + this.getCity().getGuild().getName() + " and razed " + this.getCity().getCityName() + '!');
|
||||
msg.setMessageType(4);
|
||||
msg.setChannel(engine.Enum.ChatChannelType.SYSTEM.getChannelID());
|
||||
|
||||
DispatchMessage.dispatchMsgToAll(msg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Zone cityZone = this.getCity().getParent();
|
||||
|
||||
if (cityZone == null)
|
||||
return;
|
||||
|
||||
//UNPROTECT ALL SIEGE EQUIPMENT AFTER A BANE
|
||||
for (Building toUnprotect: cityZone.zoneBuildingSet){
|
||||
if (toUnprotect.getBlueprint() != null && toUnprotect.getBlueprint().isSiegeEquip() && toUnprotect.assetIsProtected() == true)
|
||||
toUnprotect.setProtectionState(ProtectionState.NONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isErrant() {
|
||||
|
||||
boolean isErrant = true;
|
||||
|
||||
if (this.getOwner() == null)
|
||||
return isErrant;
|
||||
|
||||
|
||||
if (this.getOwner().getGuild().isErrant() == true)
|
||||
return isErrant;
|
||||
|
||||
if (this.getOwner().getGuild().getNation().isErrant() == true)
|
||||
return isErrant;
|
||||
|
||||
// Bane passes validation
|
||||
|
||||
isErrant = false;
|
||||
|
||||
return isErrant;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the stone
|
||||
*/
|
||||
public Building getStone() {
|
||||
return BuildingManager.getBuilding(this.stoneUUID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cityUUID
|
||||
*/
|
||||
public int getCityUUID() {
|
||||
return cityUUID;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.net.ByteBufferWriter;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class BaseClass extends AbstractGameObject {
|
||||
|
||||
private final String name;
|
||||
private final String description;
|
||||
|
||||
private final byte strMod;
|
||||
private final byte dexMod;
|
||||
private final byte conMod;
|
||||
private final byte intMod;
|
||||
private final byte spiMod;
|
||||
|
||||
private final float healthMod;
|
||||
private final float manaMod;
|
||||
private final float staminaMod;
|
||||
|
||||
private int token = 0;
|
||||
|
||||
private final ArrayList<SkillReq> skillsGranted;
|
||||
private final ArrayList<PowerReq> powersGranted;
|
||||
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
||||
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public BaseClass(String name, String description, byte strMod, byte dexMod, byte conMod, byte intMod, byte spiMod,
|
||||
ArrayList<RuneBase> allowedRunes, ArrayList<SkillReq> skillsGranted, ArrayList<PowerReq> powersGranted) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.strMod = strMod;
|
||||
this.dexMod = dexMod;
|
||||
this.conMod = conMod;
|
||||
this.intMod = intMod;
|
||||
this.spiMod = spiMod;
|
||||
this.healthMod = 1;
|
||||
this.manaMod = 1;
|
||||
this.staminaMod = 1;
|
||||
|
||||
this.skillsGranted = skillsGranted;
|
||||
this.powersGranted = powersGranted;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public BaseClass(String name, String description, byte strMod, byte dexMod, byte conMod, byte intMod, byte spiMod,
|
||||
ArrayList<RuneBase> allowedRunes, ArrayList<SkillReq> skillsGranted, ArrayList<PowerReq> powersGranted, int newUUID) {
|
||||
super(newUUID);
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.strMod = strMod;
|
||||
this.dexMod = dexMod;
|
||||
this.conMod = conMod;
|
||||
this.intMod = intMod;
|
||||
this.spiMod = spiMod;
|
||||
this.healthMod = 1;
|
||||
this.manaMod = 1;
|
||||
this.staminaMod = 1;
|
||||
this.skillsGranted = skillsGranted;
|
||||
this.powersGranted = powersGranted;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public BaseClass(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
this.name = rs.getString("name");
|
||||
this.description = rs.getString("description");
|
||||
this.strMod = rs.getByte("strMod");
|
||||
this.dexMod = rs.getByte("dexMod");
|
||||
this.conMod = rs.getByte("conMod");
|
||||
this.intMod = rs.getByte("intMod");
|
||||
this.spiMod = rs.getByte("spiMod");
|
||||
this.token = rs.getInt("token");
|
||||
this.healthMod = rs.getInt("healthMod");
|
||||
this.manaMod = rs.getInt("manaMod");
|
||||
this.staminaMod = rs.getInt("staminaMod");
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
||||
this.effectsList = (DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID()));
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public byte getStrMod() {
|
||||
return strMod;
|
||||
}
|
||||
|
||||
public byte getDexMod() {
|
||||
return dexMod;
|
||||
}
|
||||
|
||||
public byte getConMod() {
|
||||
return conMod;
|
||||
}
|
||||
|
||||
public byte getIntMod() {
|
||||
return intMod;
|
||||
}
|
||||
|
||||
public byte getSpiMod() {
|
||||
return spiMod;
|
||||
}
|
||||
|
||||
public int getToken() {
|
||||
return this.token;
|
||||
}
|
||||
|
||||
public float getHealthMod() {
|
||||
return this.healthMod;
|
||||
}
|
||||
|
||||
public float getManaMod() {
|
||||
return this.manaMod;
|
||||
}
|
||||
|
||||
public float getStaminaMod() {
|
||||
return this.staminaMod;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getRuneList() {
|
||||
return RuneBase.AllowedBaseClassRunesMap.get(this.getObjectUUID());
|
||||
}
|
||||
|
||||
public ArrayList<SkillReq> getSkillsGranted() {
|
||||
return this.skillsGranted;
|
||||
}
|
||||
|
||||
public ArrayList<PowerReq> getPowersGranted() {
|
||||
return this.powersGranted;
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
||||
return RuneBaseEffect.RuneIDBaseEffectMap.get(this.getObjectUUID());
|
||||
}
|
||||
|
||||
/*
|
||||
* Utils
|
||||
*/
|
||||
public boolean isAllowedRune(RuneBase rb) {
|
||||
|
||||
if (this.getRuneList().contains(rb.getObjectUUID()))
|
||||
return true;
|
||||
|
||||
if (RuneBase.AllowedBaseClassRunesMap.containsKey(111111)){
|
||||
if (RuneBase.AllowedBaseClassRunesMap.get(111111).contains(rb.getObjectUUID()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void LoadAllBaseClasses(){
|
||||
DbManager.BaseClassQueries.GET_ALL_BASE_CLASSES();
|
||||
}
|
||||
|
||||
/*
|
||||
* Serializing
|
||||
*/
|
||||
|
||||
public static void serializeForClientMsg(BaseClass baseClass, ByteBufferWriter writer) {
|
||||
serializeForClientMsg(baseClass,writer, 3);
|
||||
}
|
||||
|
||||
public static void serializeForClientMsg(BaseClass baseClass,ByteBufferWriter writer, int type) {
|
||||
writer.putInt(type); // For BaseClass
|
||||
writer.putInt(0); // Pad
|
||||
writer.putInt(baseClass.getObjectUUID());
|
||||
writer.putInt(baseClass.getObjectType().ordinal()); // Is this correct?
|
||||
writer.putInt(baseClass.getObjectUUID());
|
||||
}
|
||||
|
||||
public static BaseClass getBaseClass(final int UUID) {
|
||||
return DbManager.BaseClassQueries.GET_BASE_CLASS(UUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
; //Never update..
|
||||
}
|
||||
|
||||
public ArrayList<MobBaseEffects> getEffectsList() {
|
||||
return effectsList;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,630 @@
|
||||
package engine.objects;
|
||||
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
|
||||
import engine.Enum.BuildingGroup;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.math.Vector2f;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
|
||||
/* @Summary - Blueprint class is used for determining
|
||||
characteristics of instanced player owned
|
||||
structures such as available slots, upgrade
|
||||
cost/time and the target window symbol icon.
|
||||
*/
|
||||
public class Blueprint {
|
||||
|
||||
public final static Vector2f IrikieForgeExtents = new Vector2f(32, 32);
|
||||
public final static Vector2f IrikieBarracksExtents = new Vector2f(32, 32);
|
||||
|
||||
private static HashMap<Integer, Blueprint> _blueprints = new HashMap<>();
|
||||
private static HashMap<Integer, Integer> _doorNumbers = new HashMap<>();
|
||||
public static HashMap<Integer, Blueprint> _meshLookup = new HashMap<>();
|
||||
|
||||
private final int blueprintUUID;
|
||||
private final String name;
|
||||
private final BuildingGroup buildingGroup;
|
||||
private final int icon;
|
||||
private final int maxRank;
|
||||
private final int maxSlots;
|
||||
private final int rank1UUID;
|
||||
private final int rank3UUID;
|
||||
private final int rank7UUID;
|
||||
private final int destroyedUUID;
|
||||
|
||||
private Blueprint() {
|
||||
this.blueprintUUID = 0;
|
||||
this.name = "";
|
||||
this.icon = 0;
|
||||
this.buildingGroup = BuildingGroup.BANESTONE;
|
||||
this.maxRank = 0;
|
||||
this.maxSlots = 0;
|
||||
this.rank1UUID = 0;
|
||||
this.rank3UUID = 0;
|
||||
this.rank7UUID = 0;
|
||||
this.destroyedUUID = 0;
|
||||
}
|
||||
|
||||
public Blueprint(ResultSet rs) throws SQLException {
|
||||
|
||||
this.blueprintUUID = rs.getInt("Rank0UUID");
|
||||
this.name = rs.getString("MeshName");
|
||||
this.icon = rs.getInt("Icon");
|
||||
this.buildingGroup = BuildingGroup.valueOf(rs.getString("BuildingGroup"));
|
||||
this.maxRank = rs.getInt("MaxRank");
|
||||
this.maxSlots = rs.getInt("MaxSlots");
|
||||
this.rank1UUID = rs.getInt("Rank1UUID");
|
||||
this.rank3UUID = rs.getInt("Rank3UUID");
|
||||
this.rank7UUID = rs.getInt("Rank7UUID");
|
||||
this.destroyedUUID = rs.getInt("DestroyedUUID");
|
||||
|
||||
}
|
||||
|
||||
// Accessors
|
||||
|
||||
public static Blueprint getBlueprint(int blueprintUUID) {
|
||||
|
||||
return _blueprints.get(blueprintUUID);
|
||||
|
||||
}
|
||||
|
||||
public static BuildingGroup getBuildingGroup(int blueprintUUID) {
|
||||
|
||||
Blueprint blueprint;
|
||||
|
||||
blueprint = _blueprints.get(blueprintUUID);
|
||||
|
||||
return blueprint.buildingGroup;
|
||||
}
|
||||
|
||||
public static int getMaxShrines(int treeRank) {
|
||||
|
||||
// Returns the number of allowed spires/shrines
|
||||
// for a given rank.
|
||||
|
||||
int maxShrines;
|
||||
|
||||
switch (treeRank) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
maxShrines = 0;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
maxShrines = 1;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
maxShrines = 2;
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
maxShrines = 3;
|
||||
break;
|
||||
default:
|
||||
maxShrines = 0;
|
||||
|
||||
}
|
||||
|
||||
return maxShrines;
|
||||
}
|
||||
|
||||
public static void loadAllBlueprints() {
|
||||
|
||||
_blueprints = DbManager.BlueprintQueries.LOAD_ALL_BLUEPRINTS();
|
||||
|
||||
}
|
||||
|
||||
// Method returns a blueprint based on a blueprintUUID
|
||||
|
||||
public static void loadAllDoorNumbers() {
|
||||
|
||||
_doorNumbers = DbManager.BlueprintQueries.LOAD_ALL_DOOR_NUMBERS();
|
||||
|
||||
}
|
||||
|
||||
public static int getDoorNumberbyMesh(int doorMeshUUID) {
|
||||
|
||||
if (_doorNumbers.containsKey(doorMeshUUID))
|
||||
return _doorNumbers.get(doorMeshUUID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static boolean isMeshWallPiece(int meshUUID) {
|
||||
|
||||
Blueprint buildingBlueprint = Blueprint.getBlueprint(meshUUID);
|
||||
|
||||
if (buildingBlueprint == null)
|
||||
return false;
|
||||
|
||||
switch (buildingBlueprint.buildingGroup) {
|
||||
case WALLSTRAIGHT:
|
||||
case ARTYTOWER:
|
||||
case WALLCORNER:
|
||||
case SMALLGATE:
|
||||
case WALLSTAIRS:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// Method calculates available vendor slots
|
||||
// based upon the building's current rank
|
||||
|
||||
public static int getNpcMaintCost(int rank) {
|
||||
int maintCost = Integer.MAX_VALUE;
|
||||
|
||||
maintCost = (9730 * rank) + 1890;
|
||||
|
||||
return maintCost;
|
||||
}
|
||||
|
||||
public int getMaxRank() {
|
||||
return maxRank;
|
||||
}
|
||||
|
||||
public int getMaxSlots() {
|
||||
if (this.buildingGroup != null && this.buildingGroup.equals(BuildingGroup.BARRACK))
|
||||
return 1;
|
||||
return maxSlots;
|
||||
}
|
||||
|
||||
// Method returns a mesh UUID for this blueprint
|
||||
// based upon a given rank.
|
||||
|
||||
public BuildingGroup getBuildingGroup() {
|
||||
return this.buildingGroup;
|
||||
}
|
||||
|
||||
// Method returns a cost to upgrade a building to a given rank
|
||||
// based upon this blueprint's maintenance group
|
||||
|
||||
public int getMaxHealth(int currentRank) {
|
||||
|
||||
int maxHealth;
|
||||
|
||||
// Return 0 health for a destroyed building
|
||||
// or 1 for a destroyed mine (cleint looting restriction)
|
||||
|
||||
if (currentRank == -1) {
|
||||
|
||||
return this.buildingGroup == BuildingGroup.MINE ? 1 : 0;
|
||||
}
|
||||
|
||||
// Return 15k for a constructing mesh
|
||||
|
||||
if (currentRank == 0)
|
||||
return 15000;
|
||||
|
||||
switch (this.buildingGroup) {
|
||||
|
||||
case TOL:
|
||||
maxHealth = (70000 * currentRank) + 10000;
|
||||
break;
|
||||
case BARRACK:
|
||||
maxHealth = (35000 * currentRank) + 5000;
|
||||
break;
|
||||
case BANESTONE:
|
||||
maxHealth = (170000 * currentRank) - 120000;
|
||||
break;
|
||||
case CHURCH:
|
||||
maxHealth = (28000 * currentRank) + 4000;
|
||||
break;
|
||||
case MAGICSHOP:
|
||||
case FORGE:
|
||||
case INN:
|
||||
case TAILOR:
|
||||
maxHealth = (17500 * currentRank) + 2500;
|
||||
break;
|
||||
case VILLA:
|
||||
case ESTATE:
|
||||
case FORTRESS:
|
||||
maxHealth = 300000;
|
||||
break;
|
||||
case CITADEL:
|
||||
maxHealth = 500000;
|
||||
break;
|
||||
case SPIRE:
|
||||
maxHealth = (37000 * currentRank) - 9000;
|
||||
break;
|
||||
case GENERICNOUPGRADE:
|
||||
case SHACK:
|
||||
case SIEGETENT:
|
||||
maxHealth = 40000;
|
||||
break;
|
||||
case BULWARK:
|
||||
if (currentRank == 1)
|
||||
maxHealth = 110000;
|
||||
else
|
||||
maxHealth = 40000;
|
||||
break;
|
||||
case WALLSTRAIGHT:
|
||||
case WALLSTRAIGHTTOWER:
|
||||
case WALLSTAIRS:
|
||||
maxHealth = 1000000;
|
||||
break;
|
||||
case WALLCORNER:
|
||||
case ARTYTOWER:
|
||||
maxHealth = 900000;
|
||||
break;
|
||||
case SMALLGATE:
|
||||
maxHealth = 1100000;
|
||||
break;
|
||||
case AMAZONHALL:
|
||||
case CATHEDRAL:
|
||||
case GREATHALL:
|
||||
case KEEP:
|
||||
case THIEFHALL:
|
||||
case TEMPLEHALL:
|
||||
case WIZARDHALL:
|
||||
case ELVENHALL:
|
||||
case ELVENSANCTUM:
|
||||
case IREKEIHALL:
|
||||
case FORESTHALL:
|
||||
maxHealth = (28000 * currentRank) + 4000;
|
||||
break;
|
||||
case MINE:
|
||||
maxHealth = 125000;
|
||||
break;
|
||||
case RUNEGATE:
|
||||
maxHealth = 100000;
|
||||
break;
|
||||
case SHRINE:
|
||||
maxHealth = 100000;
|
||||
break;
|
||||
case WAREHOUSE:
|
||||
maxHealth = 40000;
|
||||
break;
|
||||
|
||||
default:
|
||||
maxHealth = 40000;
|
||||
break;
|
||||
|
||||
}
|
||||
return maxHealth;
|
||||
}
|
||||
|
||||
// Returns number of vendor slots available
|
||||
// for the building's current rank.
|
||||
|
||||
public int getSlotsForRank(int currentRank) {
|
||||
|
||||
int availableSlots;
|
||||
|
||||
// Early exit for buildings not yet constructed
|
||||
|
||||
if (currentRank == 0)
|
||||
return 0;
|
||||
|
||||
// Early exit for buildings with single or no slots
|
||||
|
||||
if (this.maxSlots <= 1)
|
||||
return maxSlots;
|
||||
|
||||
if (this.maxRank == 1 && currentRank == 1)
|
||||
return getMaxSlots();
|
||||
|
||||
switch (currentRank) {
|
||||
|
||||
case 1:
|
||||
case 2:
|
||||
availableSlots = 1;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
availableSlots = 2;
|
||||
break;
|
||||
case 7:
|
||||
availableSlots = 3;
|
||||
break;
|
||||
case 8:
|
||||
availableSlots = 1;
|
||||
break;
|
||||
default:
|
||||
availableSlots = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return availableSlots;
|
||||
}
|
||||
|
||||
// Returns the half extents of this blueprint's
|
||||
// bounding box, based upon it's buildinggroup
|
||||
|
||||
public int getIcon() {
|
||||
return this.icon;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public int getMeshForRank(int targetRank) {
|
||||
|
||||
int targetMesh = this.blueprintUUID;
|
||||
|
||||
// The Blueprint UUID is the 'constructing' mesh so
|
||||
// we return that value if the rank passed is 0.
|
||||
|
||||
if ((maxRank == 1) && (this.rank1UUID == 0)) {
|
||||
return blueprintUUID;
|
||||
}
|
||||
|
||||
// Set the return value to the proper mesh UID for rank
|
||||
|
||||
switch (targetRank) {
|
||||
|
||||
case -1:
|
||||
targetMesh = this.destroyedUUID; // -1 Rank is a destroyed mesh
|
||||
break;
|
||||
case 0:
|
||||
targetMesh = this.blueprintUUID; // Rank 0 is the 'constructing' mesh
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
targetMesh = this.rank1UUID;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
targetMesh = this.rank3UUID;
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
targetMesh = this.rank7UUID;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return targetMesh;
|
||||
}
|
||||
|
||||
public int getRankCost(int targetRank) {
|
||||
|
||||
// Set a MAXINT rankcost in case something goes wrong
|
||||
|
||||
int rankCost = Integer.MAX_VALUE;
|
||||
|
||||
// Sanity chack for retrieving a rankcost outside proper range
|
||||
|
||||
if ((targetRank > maxRank) || (targetRank < 0)) {
|
||||
Logger.error( "Attempt to retrieve rankcost for rank of" + targetRank);
|
||||
return rankCost;
|
||||
}
|
||||
|
||||
// Select linear equation for rank cost based upon the
|
||||
// buildings current Maintenance BuildingGroup.
|
||||
|
||||
switch (this.buildingGroup) {
|
||||
|
||||
case GENERICNOUPGRADE:
|
||||
case WALLSTRAIGHT:
|
||||
case WALLSTAIRS:
|
||||
case WALLCORNER:
|
||||
case SMALLGATE:
|
||||
case ARTYTOWER:
|
||||
case SIEGETENT:
|
||||
case BULWARK:
|
||||
case BANESTONE:
|
||||
case SHACK:
|
||||
break; // This set cannot be upgraded. Returns max integer.
|
||||
|
||||
case TOL:
|
||||
rankCost = (880000 * targetRank) - 440000;
|
||||
break;
|
||||
case BARRACK:
|
||||
case VILLA:
|
||||
case ESTATE:
|
||||
case FORTRESS:
|
||||
case CITADEL:
|
||||
rankCost = (451000 * targetRank) - 308000;
|
||||
break;
|
||||
case CHURCH:
|
||||
rankCost = (682000 * targetRank) - 110000;
|
||||
break;
|
||||
case FORGE:
|
||||
case INN:
|
||||
case TAILOR:
|
||||
case MAGICSHOP:
|
||||
rankCost = (440000 * targetRank) - 550000;
|
||||
break;
|
||||
case SPIRE:
|
||||
rankCost = (176000 * targetRank) - 88000;
|
||||
break;
|
||||
case AMAZONHALL:
|
||||
case CATHEDRAL:
|
||||
case GREATHALL:
|
||||
case KEEP:
|
||||
case THIEFHALL:
|
||||
case TEMPLEHALL:
|
||||
case WIZARDHALL:
|
||||
case ELVENHALL:
|
||||
case ELVENSANCTUM:
|
||||
case IREKEIHALL:
|
||||
case FORESTHALL:
|
||||
rankCost = (682000 * targetRank) - 110000;
|
||||
break;
|
||||
default:
|
||||
Logger.error("Attempt to retrieve rankcost without MaintGroup for " + this.buildingGroup.name());
|
||||
break;
|
||||
}
|
||||
|
||||
return rankCost;
|
||||
}
|
||||
|
||||
public int getRankTime(int targetRank) {
|
||||
|
||||
// Set a very long rankTime in case something goes wrong
|
||||
|
||||
int rankTime = (Integer.MAX_VALUE / 2);
|
||||
|
||||
// Set all initial construction to a default of 4 hours.
|
||||
|
||||
if (targetRank == 1)
|
||||
return 4;
|
||||
|
||||
// Sanity chack for retrieving a ranktime outside proper range
|
||||
|
||||
if ((targetRank > maxRank) || (targetRank < 1)) {
|
||||
Logger.error( "Attempt to retrieve ranktime for rank of" + targetRank);
|
||||
return rankTime;
|
||||
}
|
||||
|
||||
// Select equation for rank time based upon the
|
||||
// buildings current Maintenance BuildingGroup. These values
|
||||
// are expressed in hours
|
||||
|
||||
switch (this.buildingGroup) {
|
||||
|
||||
case GENERICNOUPGRADE:
|
||||
break; // Cannot be upgraded
|
||||
case VILLA:
|
||||
case ESTATE:
|
||||
case FORTRESS:
|
||||
case CITADEL:
|
||||
rankTime = (7 * targetRank) - 7;
|
||||
break;
|
||||
case TOL:
|
||||
rankTime = (7 * targetRank) - 7;
|
||||
break;
|
||||
case BARRACK:
|
||||
rankTime = (7 * targetRank) - 7;
|
||||
break;
|
||||
case CHURCH:
|
||||
rankTime = (7 * targetRank) - 7;
|
||||
break;
|
||||
case FORGE:
|
||||
case INN:
|
||||
case TAILOR:
|
||||
case MAGICSHOP:
|
||||
rankTime = (7 * targetRank) - 7;
|
||||
break;
|
||||
case SPIRE:
|
||||
rankTime = (4 * targetRank) + 4;
|
||||
break;
|
||||
case AMAZONHALL:
|
||||
case CATHEDRAL:
|
||||
case GREATHALL:
|
||||
case KEEP:
|
||||
case THIEFHALL:
|
||||
case TEMPLEHALL:
|
||||
case WIZARDHALL:
|
||||
case ELVENHALL:
|
||||
case ELVENSANCTUM:
|
||||
case IREKEIHALL:
|
||||
case FORESTHALL:
|
||||
rankTime = (7 * targetRank) - 7;
|
||||
break;
|
||||
default:
|
||||
Logger.error("Attempt to retrieve ranktime without MaintGroup");
|
||||
break;
|
||||
}
|
||||
|
||||
return rankTime;
|
||||
}
|
||||
|
||||
public Vector2f getExtents() {
|
||||
|
||||
if (blueprintUUID == 1302600)
|
||||
return Blueprint.IrikieForgeExtents;
|
||||
else if (blueprintUUID == 1300600)
|
||||
return Blueprint.IrikieBarracksExtents;
|
||||
|
||||
return this.buildingGroup.getExtents();
|
||||
|
||||
}
|
||||
|
||||
public boolean isWallPiece() {
|
||||
|
||||
switch (this.buildingGroup) {
|
||||
case WALLSTRAIGHT:
|
||||
case WALLSTAIRS:
|
||||
case ARTYTOWER:
|
||||
case WALLCORNER:
|
||||
case SMALLGATE:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSiegeEquip() {
|
||||
|
||||
switch (this.buildingGroup) {
|
||||
case BULWARK:
|
||||
case SIEGETENT:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public int getBlueprintUUID() {
|
||||
return blueprintUUID;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
|
||||
if ((object instanceof Blueprint) == false)
|
||||
return false;
|
||||
|
||||
Blueprint blueprint = (Blueprint) object;
|
||||
|
||||
return this.blueprintUUID == blueprint.blueprintUUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
return this.blueprintUUID ;
|
||||
}
|
||||
|
||||
public int getMaintCost(int rank) {
|
||||
|
||||
int maintCost = Integer.MAX_VALUE;
|
||||
|
||||
switch (this.buildingGroup) {
|
||||
case TOL:
|
||||
case BARRACK:
|
||||
maintCost = (61500 * rank) + 19500;
|
||||
break;
|
||||
case SPIRE:
|
||||
maintCost = (4800 * rank) + 1200;
|
||||
break;
|
||||
default:
|
||||
if (maxRank == 1)
|
||||
maintCost = 22500;
|
||||
else
|
||||
maintCost = (15900 * rank) + 3300;
|
||||
break;
|
||||
}
|
||||
|
||||
return maintCost;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.ShrineType;
|
||||
import engine.gameManager.DbManager;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
|
||||
public class Boon {
|
||||
|
||||
private ShrineType shrineType;
|
||||
private int amount;
|
||||
private int itemBaseID;
|
||||
public static HashMap<Integer,ArrayList<Boon>> GetBoonsForItemBase = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public Boon(ResultSet rs) throws SQLException {
|
||||
|
||||
this.shrineType = ShrineType.valueOf(rs.getString("shrineType"));
|
||||
this.itemBaseID = rs.getInt("itemBaseID");
|
||||
this.amount = rs.getInt("amount");
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getItemBaseID() {
|
||||
return itemBaseID;
|
||||
}
|
||||
|
||||
|
||||
public ShrineType getShrineType() {
|
||||
return shrineType;
|
||||
}
|
||||
|
||||
|
||||
public static void HandleBoonListsForItemBase(int itemBaseID){
|
||||
ArrayList<Boon> boons = null;
|
||||
boons = DbManager.BoonQueries.GET_BOON_AMOUNTS_FOR_ITEMBASEUUID(itemBaseID);
|
||||
if (boons != null)
|
||||
GetBoonsForItemBase.put(itemBaseID, boons);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class BuildingFriends {
|
||||
|
||||
private int playerUID;
|
||||
private int buildingUID;
|
||||
private int guildUID;
|
||||
private int friendType;
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public BuildingFriends(ResultSet rs) throws SQLException {
|
||||
this.playerUID = rs.getInt("playerUID");
|
||||
this.buildingUID = rs.getInt("buildingUID");
|
||||
this.guildUID = rs.getInt("guildUID");
|
||||
this.friendType = rs.getInt("friendType");
|
||||
}
|
||||
|
||||
public BuildingFriends(int playerUID, int buildingUID, int guildUID, int friendType) {
|
||||
super();
|
||||
this.playerUID = playerUID;
|
||||
this.buildingUID = buildingUID;
|
||||
this.guildUID = guildUID;
|
||||
this.friendType = friendType;
|
||||
}
|
||||
|
||||
public int getPlayerUID() {
|
||||
return playerUID;
|
||||
}
|
||||
public int getGuildUID() {
|
||||
return guildUID;
|
||||
}
|
||||
public int getFriendType() {
|
||||
return friendType;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.math.Vector3fImmutable;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class BuildingLocation extends AbstractGameObject {
|
||||
|
||||
private final int buildingUUID;
|
||||
private final int type;
|
||||
private final int slot;
|
||||
private final int unknown;
|
||||
private final Vector3fImmutable loc;
|
||||
private final Vector3fImmutable rot;
|
||||
private final float w;
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public BuildingLocation(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
this.buildingUUID = rs.getInt("BuildingID");
|
||||
this.type = rs.getInt("type");
|
||||
this.slot = rs.getInt("slot");
|
||||
this.unknown = rs.getInt("unknown");
|
||||
this.loc = new Vector3fImmutable(rs.getFloat("locX"), rs.getFloat("locY"), rs.getFloat("locZ"));
|
||||
this.rot = new Vector3fImmutable(rs.getFloat("rotX"), rs.getFloat("rotY"), rs.getFloat("rotZ"));
|
||||
this.w = rs.getFloat("w");
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
|
||||
public int getBuildingUUID() {
|
||||
return this.buildingUUID;
|
||||
}
|
||||
|
||||
public Vector3fImmutable rotatedLoc() {
|
||||
Vector3fImmutable convertLoc = null;
|
||||
|
||||
|
||||
double rotY = 2.0 * Math.asin(this.rot.y);
|
||||
|
||||
|
||||
// handle building rotation
|
||||
|
||||
convertLoc = new Vector3fImmutable(
|
||||
(float) ((loc.z * Math.sin(rotY)) + (loc.x * Math.cos(rotY))),
|
||||
loc.y,
|
||||
(float) ((loc.z * Math.cos(rotY)) - (loc.x * Math.sin(rotY))));
|
||||
|
||||
return convertLoc;
|
||||
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public int getSlot() {
|
||||
return this.slot;
|
||||
}
|
||||
|
||||
public int getUnknown() {
|
||||
return this.unknown;
|
||||
}
|
||||
|
||||
public float getLocX() {
|
||||
return this.loc.x;
|
||||
}
|
||||
|
||||
public float getLocY() {
|
||||
return this.loc.y;
|
||||
}
|
||||
|
||||
public float getLocZ() {
|
||||
return this.loc.z;
|
||||
}
|
||||
|
||||
public float getRotX() {
|
||||
return this.rot.x;
|
||||
}
|
||||
|
||||
public float getRotY() {
|
||||
return this.rot.y;
|
||||
}
|
||||
|
||||
public float getRotZ() {
|
||||
return this.rot.z;
|
||||
}
|
||||
|
||||
public float getW() {
|
||||
return this.w;
|
||||
}
|
||||
|
||||
public Vector3fImmutable getLoc() {
|
||||
return this.loc;
|
||||
}
|
||||
|
||||
public Vector3fImmutable getRot() {
|
||||
return this.rot;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
}
|
||||
|
||||
|
||||
public static void loadAllLocations() {
|
||||
ArrayList<BuildingLocation> bls = DbManager.BuildingLocationQueries.LOAD_ALL_BUILDING_LOCATIONS();
|
||||
ConcurrentHashMap<Integer, BuildingModelBase> mbs = BuildingModelBase.getModelBases();
|
||||
for (BuildingLocation bl : bls) {
|
||||
int modelID = bl.buildingUUID;
|
||||
BuildingModelBase mb = null;
|
||||
if (!mbs.containsKey(modelID)) {
|
||||
mb = new BuildingModelBase(modelID);
|
||||
mbs.put(modelID, mb);
|
||||
} else
|
||||
mb = mbs.get(modelID);
|
||||
mb.addLocation(bl);
|
||||
|
||||
if (bl.type == 6)
|
||||
mb.addSlotLocation(bl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class BuildingModelBase extends AbstractGameObject {
|
||||
|
||||
private ArrayList<BuildingLocation> locations = new ArrayList<>();
|
||||
private static ConcurrentHashMap<Integer, BuildingModelBase> modelBases = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private final int buildingBaseID;
|
||||
|
||||
private ArrayList<BuildingLocation> slotLocations = new ArrayList<>();
|
||||
|
||||
public BuildingModelBase(int buildingBaseID) {
|
||||
super();
|
||||
this.buildingBaseID = buildingBaseID;
|
||||
}
|
||||
|
||||
public void addLocation(BuildingLocation bl) {
|
||||
this.locations.add(bl);
|
||||
}
|
||||
|
||||
public void addSlotLocation(BuildingLocation bl) {
|
||||
this.slotLocations.add(bl);
|
||||
}
|
||||
|
||||
public ArrayList<BuildingLocation> getLocations() {
|
||||
return this.locations;
|
||||
}
|
||||
|
||||
public BuildingLocation getNPCLocation(int slot) {
|
||||
for (BuildingLocation bl : this.locations) {
|
||||
if (bl.getType() == 6 && bl.getSlot() == slot)
|
||||
return bl;
|
||||
}
|
||||
return null; //not found
|
||||
}
|
||||
|
||||
public BuildingLocation getStuckLocation() {
|
||||
|
||||
for (BuildingLocation bl : this.locations) {
|
||||
if (bl.getType() == 8)
|
||||
return bl;
|
||||
}
|
||||
return null; //not found
|
||||
}
|
||||
|
||||
public BuildingLocation getSlotLocation(int slot) {
|
||||
|
||||
try{
|
||||
return this.slotLocations.get(slot - 1);
|
||||
}catch(Exception e){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
}
|
||||
|
||||
public int getBuildingBaseID() {
|
||||
return this.buildingBaseID;
|
||||
}
|
||||
|
||||
public static ConcurrentHashMap<Integer, BuildingModelBase> getModelBases() {
|
||||
return BuildingModelBase.modelBases;
|
||||
}
|
||||
|
||||
public static BuildingModelBase getModelBase(int ID) {
|
||||
if (!BuildingModelBase.modelBases.containsKey(ID))
|
||||
BuildingModelBase.modelBases.put(ID, new BuildingModelBase(ID));
|
||||
return BuildingModelBase.modelBases.get(ID);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,388 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.math.Vector3f;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class BuildingRegions {
|
||||
|
||||
|
||||
private int buildingID;
|
||||
private int level;
|
||||
private int numVertex ;
|
||||
private float vertex1X ;
|
||||
private float vertex1Y ;
|
||||
private float vertex1Z ;
|
||||
private float vertex2X ;
|
||||
private float vertex2Y ;
|
||||
private float vertex2Z ;
|
||||
private float vertex3X ;
|
||||
private float vertex3Y ;
|
||||
private float vertex3Z ;
|
||||
private float vertex4X ;
|
||||
private float vertex4Y ;
|
||||
private float vertex4Z ;
|
||||
private byte ground1;
|
||||
private byte ground2;
|
||||
private byte ground3;
|
||||
private byte ground4;
|
||||
|
||||
private short contentBehavior;
|
||||
private boolean outside;
|
||||
private float centerX;
|
||||
private float centerZ;
|
||||
private int room = 0;
|
||||
public static HashMap<Integer,ArrayList<BuildingRegions>> _staticRegions = new HashMap<>();
|
||||
private final boolean exitRegion;
|
||||
private final boolean stairs;
|
||||
|
||||
private ArrayList<Vector3f> regionPoints = new ArrayList<>();
|
||||
public Vector3f center;
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public BuildingRegions(ResultSet rs) throws SQLException {
|
||||
|
||||
buildingID = rs.getInt("buildingID");
|
||||
level = rs.getInt("level");
|
||||
room = rs.getInt("room");
|
||||
numVertex = rs.getInt("numVertex");
|
||||
vertex1X = rs.getFloat("vertex1X");
|
||||
vertex1Y = rs.getFloat("vertex1Y");
|
||||
vertex1Z = rs.getFloat("vertex1Z");
|
||||
vertex2X = rs.getFloat("vertex2X");
|
||||
vertex2Y = rs.getFloat("vertex2Y");
|
||||
vertex2Z = rs.getFloat("vertex2Z");
|
||||
vertex3X = rs.getFloat("vertex3X");
|
||||
vertex3Y = rs.getFloat("vertex3Y");
|
||||
vertex3Z = rs.getFloat("vertex3Z");
|
||||
vertex4X = rs.getFloat("vertex4X");
|
||||
vertex4Y = rs.getFloat("vertex4Y");
|
||||
vertex4Z = rs.getFloat("vertex4Z");
|
||||
|
||||
regionPoints.add(new Vector3f(vertex1X,vertex1Y,vertex1Z));
|
||||
regionPoints.add(new Vector3f(vertex2X,vertex2Y,vertex2Z));
|
||||
regionPoints.add(new Vector3f(vertex3X,vertex3Y,vertex3Z));
|
||||
|
||||
|
||||
if(numVertex ==4)
|
||||
regionPoints.add(new Vector3f(vertex4X,vertex4Y,vertex4Z));
|
||||
|
||||
|
||||
this.contentBehavior = (rs.getShort("unknown_Order1"));
|
||||
short state = rs.getShort("unknown_Order2");
|
||||
|
||||
if (state == 2)
|
||||
this.outside = (true);
|
||||
else
|
||||
this.outside = (false);
|
||||
|
||||
this.exitRegion = rs.getBoolean("colOrder1");
|
||||
this.stairs = rs.getBoolean("colOrder2");
|
||||
|
||||
|
||||
|
||||
ground1 = rs.getByte("colOrder1");
|
||||
ground2 = rs.getByte("colOrder2");
|
||||
ground3 = rs.getByte("colOrder3");
|
||||
ground4 = rs.getByte("colOrder4");
|
||||
|
||||
float centerY = rs.getFloat("unknown_VectorY");
|
||||
centerX = rs.getFloat("unknown_VectorX");
|
||||
centerZ = rs.getFloat("unknown_VectorZ");
|
||||
|
||||
this.center = new Vector3f(centerX,centerY,centerZ);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getBuildingID() {
|
||||
return buildingID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setBuildingID(int buildingID) {
|
||||
this.buildingID = buildingID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setLevel(int level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getNumVertex() {
|
||||
return numVertex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setNumVertex(int numVertex) {
|
||||
this.numVertex = numVertex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getVertex1X() {
|
||||
return vertex1X;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setVertex1X(float vertex1x) {
|
||||
vertex1X = vertex1x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getVertex1Y() {
|
||||
return vertex1Y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setVertex1Y(float vertex1y) {
|
||||
vertex1Y = vertex1y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getVertex1Z() {
|
||||
return vertex1Z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setVertex1Z(float vertex1z) {
|
||||
vertex1Z = vertex1z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getVertex2X() {
|
||||
return vertex2X;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setVertex2X(float vertex2x) {
|
||||
vertex2X = vertex2x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getVertex2Y() {
|
||||
return vertex2Y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setVertex2Y(float vertex2y) {
|
||||
vertex2Y = vertex2y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getVertex2Z() {
|
||||
return vertex2Z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setVertex2Z(float vertex2z) {
|
||||
vertex2Z = vertex2z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getVertex3X() {
|
||||
return vertex3X;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setVertex3X(float vertex3x) {
|
||||
vertex3X = vertex3x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getVertex3Y() {
|
||||
return vertex3Y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setVertex3Y(float vertex3y) {
|
||||
vertex3Y = vertex3y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getVertex3Z() {
|
||||
return vertex3Z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setVertex3Z(float vertex3z) {
|
||||
vertex3Z = vertex3z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getVertex4X() {
|
||||
return vertex4X;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setVertex4X(float vertex4x) {
|
||||
vertex4X = vertex4x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getVertex4Y() {
|
||||
return vertex4Y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setVertex4Y(float vertex4y) {
|
||||
vertex4Y = vertex4y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getVertex4Z() {
|
||||
return vertex4Z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setVertex4Z(float vertex4z) {
|
||||
vertex4Z = vertex4z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static HashMap<Integer, ArrayList<BuildingRegions>> get_staticRegions() {
|
||||
return _staticRegions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void set_staticRegions(HashMap<Integer, ArrayList<BuildingRegions>> _staticRegions) {
|
||||
BuildingRegions._staticRegions = _staticRegions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void loadAllStaticColliders(){
|
||||
_staticRegions = DbManager.BuildingQueries.LOAD_BUILDING_REGIONS();
|
||||
}
|
||||
|
||||
public static ArrayList<BuildingRegions> GetStaticCollidersForMeshID(int meshID) {
|
||||
return _staticRegions.get(meshID);
|
||||
}
|
||||
|
||||
public boolean isGroundLevel(){
|
||||
if (this.level > 0)
|
||||
return false;
|
||||
|
||||
if (this.ground1 == 0)
|
||||
return true;
|
||||
if (this.ground2 == 0)
|
||||
return true;
|
||||
if (this.ground3 == 0)
|
||||
return true;
|
||||
return this.ground4 == 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getCenterX() {
|
||||
return centerX;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setCenterX(float centerX) {
|
||||
this.centerX = centerX;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getCenterY() {
|
||||
return centerZ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setCenterY(float centerY) {
|
||||
this.centerZ = centerY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isOutside() {
|
||||
return outside;
|
||||
}
|
||||
|
||||
public short getContentBehavior() {
|
||||
return contentBehavior;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getRoom() {
|
||||
return room;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ArrayList<Vector3f> getRegionPoints() {
|
||||
return regionPoints;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isExitRegion() {
|
||||
return exitRegion;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isStairs() {
|
||||
return stairs;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,628 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.powers.PowersBase;
|
||||
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.atomic.AtomicInteger;
|
||||
|
||||
|
||||
public class CharacterPower extends AbstractGameObject {
|
||||
|
||||
private final PowersBase power;
|
||||
private AtomicInteger trains = new AtomicInteger();
|
||||
private short grantedTrains;
|
||||
private int ownerUID;
|
||||
private boolean trained = false;
|
||||
private int requiredLevel = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public CharacterPower(PowersBase power, PlayerCharacter pc) {
|
||||
super();
|
||||
this.power = power;
|
||||
this.trains.set(0);
|
||||
this.grantedTrains = this.grantedTrains;
|
||||
this.ownerUID = pc.getObjectUUID();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public CharacterPower(PowersBase power, PlayerCharacter pc, int newUUID) {
|
||||
super(newUUID);
|
||||
this.power = power;
|
||||
this.trains.set(0);
|
||||
this.grantedTrains = this.grantedTrains;
|
||||
this.ownerUID = pc.getObjectUUID();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public CharacterPower(ResultSet rs, PlayerCharacter pc) throws SQLException {
|
||||
super(rs);
|
||||
int powersBaseToken = rs.getInt("PowersBaseToken");
|
||||
this.power = PowersManager.getPowerByToken(powersBaseToken);
|
||||
|
||||
if (this.power != null && this.power.isWeaponPower())
|
||||
this.trains.set(0);
|
||||
else
|
||||
this.trains.set(rs.getInt("trains"));
|
||||
this.grantedTrains = this.grantedTrains;
|
||||
this.ownerUID = pc.getObjectUUID();
|
||||
|
||||
}
|
||||
|
||||
public CharacterPower(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
int powersBaseToken = rs.getInt("PowersBaseToken");
|
||||
this.power = PowersManager.getPowerByToken(powersBaseToken);
|
||||
this.trains.set(rs.getInt("trains"));
|
||||
this.grantedTrains = this.grantedTrains;
|
||||
this.ownerUID = rs.getInt("CharacterID");
|
||||
|
||||
// this.owner = DbManager.PlayerCharacterQueries.GET_PLAYER_CHARACTER(rs.getInt("CharacterID"));
|
||||
}
|
||||
|
||||
private short getGrantedTrains(PlayerCharacter pc) {
|
||||
if (this.power != null && pc != null) {
|
||||
// if (this.power.isWeaponPower()) {
|
||||
// SkillsBase sb = null;
|
||||
// try {
|
||||
// sb = SkillsBase.getSkillsBaseByName(this.power.getSkillName());
|
||||
// } catch (SQLException e) {}
|
||||
// if (sb != null) {
|
||||
// return pc.getBonuses().getByte("gt." + sb.getToken());
|
||||
// } else
|
||||
// return pc.getBonuses().getByte("gt." + this.power.getToken());
|
||||
// } else
|
||||
// return pc.getBonuses().getByte("gt." + this.power.getToken());
|
||||
return PowerGrant.getGrantedTrains(this.power.getToken(), pc);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public PowersBase getPower() {
|
||||
return power;
|
||||
}
|
||||
|
||||
public int getPowerID() {
|
||||
return power.getUUID();
|
||||
}
|
||||
|
||||
public boolean isTrained() {
|
||||
return trained;
|
||||
}
|
||||
|
||||
public static PlayerCharacter getOwner(CharacterPower cp) {
|
||||
return PlayerCharacter.getFromCache(cp.ownerUID);
|
||||
}
|
||||
|
||||
public void setTrained(boolean b) {
|
||||
trained = b;
|
||||
}
|
||||
|
||||
public int getTrains() {
|
||||
return this.trains.get();
|
||||
}
|
||||
|
||||
public short getGrantedTrains() {
|
||||
return this.grantedTrains;
|
||||
}
|
||||
|
||||
public int getTotalTrains() {
|
||||
return (this.trains.get() + this.grantedTrains);
|
||||
}
|
||||
|
||||
public float getTrainingCost(PlayerCharacter pc, NPC trainer){
|
||||
int charLevel = pc.getLevel();
|
||||
int skillRank = this.trains.get() -1 + this.requiredLevel;
|
||||
|
||||
|
||||
float baseCost = 50 * this.requiredLevel ; //TODO GET BASE COSTS OF SKILLS.
|
||||
|
||||
|
||||
|
||||
float sellPercent = -4f; //NOT SELL PERCENT!
|
||||
float cost;
|
||||
float const5;
|
||||
int const2 = 1;
|
||||
float const3 = 50;
|
||||
float const4 = const3 + const2;
|
||||
if (charLevel > 50)
|
||||
const5 = 50 / const4;
|
||||
else
|
||||
const5 = charLevel/const4;
|
||||
|
||||
const5 = 1-const5;
|
||||
const5 = (float) (Math.log(const5) / Math.log(2) * .75f);
|
||||
float rounded5 = Math.round(const5);
|
||||
const5 = rounded5 - const5;
|
||||
|
||||
const5 *= -1;
|
||||
|
||||
const5 = (float) (Math.pow(2, const5) - 1);
|
||||
|
||||
const5 +=1;
|
||||
const5 = Math.scalb(const5, (int) rounded5);
|
||||
const5 *= (charLevel - skillRank);
|
||||
const5 *= sellPercent;
|
||||
|
||||
const5 = (float) (Math.log(const5) / Math.log(2) * 3);
|
||||
rounded5 = Math.round(const5);
|
||||
const5 = rounded5 - const5;
|
||||
const5 *= -1;
|
||||
const5 = (float) (Math.pow(2, const5) - 1);
|
||||
const5 +=1;
|
||||
|
||||
|
||||
const5 = Math.scalb(const5, (int) rounded5);
|
||||
const5 += 1;
|
||||
cost = const5 * baseCost;
|
||||
|
||||
|
||||
if (Float.isNaN(cost))
|
||||
cost = baseCost;
|
||||
return cost;
|
||||
}
|
||||
|
||||
public synchronized boolean train(PlayerCharacter pc) {
|
||||
if (pc == null || this.power == null)
|
||||
return false;
|
||||
|
||||
//see if any prereqs to train this power is met
|
||||
if (!canTrain(pc))
|
||||
return false;
|
||||
|
||||
boolean succeeded=true;
|
||||
int oldTrains = this.trains.get();
|
||||
int tr = oldTrains + this.grantedTrains;
|
||||
if (pc.getTrainsAvailable() <= 0)
|
||||
return false;
|
||||
if (tr == this.power.getMaxTrains()) //at max, stop here
|
||||
return false;
|
||||
else if (tr > this.power.getMaxTrains()) //catch incase we somehow go over
|
||||
this.trains.set((this.power.getMaxTrains() - this.grantedTrains));
|
||||
else //add the train
|
||||
succeeded = this.trains.compareAndSet(oldTrains, oldTrains+1);
|
||||
|
||||
if (this.trains.get() > this.power.getMaxTrains()) { //double check not over max trains
|
||||
this.trains.set(this.power.getMaxTrains());
|
||||
succeeded = false;
|
||||
}
|
||||
|
||||
if (succeeded) {
|
||||
this.trained = true;
|
||||
|
||||
//update database
|
||||
pc.addDatabaseJob("Skills", MBServerStatics.THIRTY_SECONDS);
|
||||
|
||||
//subtract from trains available
|
||||
pc.modifyTrainsAvailable(-1);
|
||||
|
||||
pc.calculateSkills();
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean reset(PlayerCharacter pc) {
|
||||
if (pc == null || this.power == null)
|
||||
return false;
|
||||
|
||||
//see if any prereqs to refine this power is met
|
||||
|
||||
boolean succeeded=true;
|
||||
int oldTrains = this.trains.get();
|
||||
int tr = oldTrains + this.grantedTrains;
|
||||
if (oldTrains < 1)
|
||||
return false;
|
||||
else //subtract the train
|
||||
succeeded = this.trains.compareAndSet(oldTrains, 0);
|
||||
if (succeeded) {
|
||||
this.trained = true;
|
||||
|
||||
//update database
|
||||
pc.addDatabaseJob("Skills", MBServerStatics.THIRTY_SECONDS);
|
||||
|
||||
//subtract from trains available
|
||||
pc.modifyTrainsAvailable(oldTrains);
|
||||
|
||||
pc.calculateSkills();
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean refine(PlayerCharacter pc) {
|
||||
if (pc == null || this.power == null)
|
||||
return false;
|
||||
|
||||
//see if any prereqs to refine this power is met
|
||||
if (!canRefine(pc))
|
||||
return false;
|
||||
|
||||
boolean succeeded=true;
|
||||
int oldTrains = this.trains.get();
|
||||
int tr = oldTrains + this.grantedTrains;
|
||||
if (oldTrains < 1)
|
||||
return false;
|
||||
else //subtract the train
|
||||
succeeded = this.trains.compareAndSet(oldTrains, oldTrains-1);
|
||||
if (succeeded) {
|
||||
this.trained = true;
|
||||
|
||||
//update database
|
||||
pc.addDatabaseJob("Skills", MBServerStatics.THIRTY_SECONDS);
|
||||
|
||||
//subtract from trains available
|
||||
pc.modifyTrainsAvailable(1);
|
||||
|
||||
pc.calculateSkills();
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Utils
|
||||
*/
|
||||
|
||||
/*
|
||||
* This iterates through players runes and adds and removes powers as needed
|
||||
* Don't Call this directly. Instead call pc.calculateSkills().
|
||||
*/
|
||||
public static void calculatePowers(PlayerCharacter pc) {
|
||||
if (pc == null)
|
||||
return;
|
||||
|
||||
// First add powers that don't exist
|
||||
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
|
||||
// ArrayList<PowerReq> genericPowers = PowerReq.getPowerReqsForAll();
|
||||
// CharacterPower.grantPowers(genericPowers, powers, pc);
|
||||
Race race = pc.getRace();
|
||||
if (race != null) {
|
||||
CharacterPower.grantPowers(race.getPowersGranted(), powers, pc);
|
||||
} else
|
||||
Logger.error( "Failed to find Race for player " + pc.getObjectUUID());
|
||||
BaseClass bc = pc.getBaseClass();
|
||||
if (bc != null) {
|
||||
CharacterPower.grantPowers(bc.getPowersGranted(), powers, pc);
|
||||
} else
|
||||
Logger.error( "Failed to find BaseClass for player " + pc.getObjectUUID());
|
||||
PromotionClass promo = pc.getPromotionClass();
|
||||
if (promo != null)
|
||||
CharacterPower.grantPowers(promo.getPowersGranted(), powers, pc);
|
||||
ArrayList<CharacterRune> runes = pc.getRunes();
|
||||
if (runes != null) {
|
||||
for (CharacterRune rune : runes) {
|
||||
CharacterPower.grantPowers(rune.getPowersGranted(), powers, pc);
|
||||
}
|
||||
} else
|
||||
Logger.error("Failed to find Runes list for player " + pc.getObjectUUID());
|
||||
|
||||
// next remove any skills that no longer belong
|
||||
Iterator<Integer> it = powers.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Integer token = it.next();
|
||||
boolean valid = false;
|
||||
// if (CharacterPower.powerAllowed(token, genericPowers, pc))
|
||||
// continue;
|
||||
if (CharacterPower.powerAllowed(token, race.getPowersGranted(), pc))
|
||||
continue;
|
||||
if (CharacterPower.powerAllowed(token, bc.getPowersGranted(), pc))
|
||||
continue;
|
||||
if (promo != null)
|
||||
if (CharacterPower.powerAllowed(token, promo.getPowersGranted(), pc))
|
||||
continue;
|
||||
for (CharacterRune rune : runes) {
|
||||
if (CharacterPower.powerAllowed(token, rune.getPowersGranted(), pc)) {
|
||||
valid = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// if power doesn't belong to any runes or skill, then remove it
|
||||
if (!valid) {
|
||||
CharacterPower cp = powers.get(token);
|
||||
DbManager.CharacterPowerQueries.DELETE_CHARACTER_POWER(cp.getObjectUUID());
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This grants powers for specific runes
|
||||
*/
|
||||
private static void grantPowers(ArrayList<PowerReq> powersGranted, ConcurrentHashMap<Integer, CharacterPower> powers, PlayerCharacter pc) {
|
||||
ConcurrentHashMap<String, CharacterSkill> skills = pc.getSkills();
|
||||
|
||||
for (PowerReq powerreq : powersGranted) {
|
||||
PowersBase powersBase = powerreq.getPowersBase();
|
||||
|
||||
if (powersBase == null)
|
||||
continue;
|
||||
// skip if player already has power
|
||||
if (powers.containsKey(powerreq.getToken())){
|
||||
CharacterPower cp = powers.get(powersBase.getToken());
|
||||
if (cp != null)
|
||||
if (cp.requiredLevel == 0) {
|
||||
cp.requiredLevel = (int) powerreq.getLevel();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// If player not high enough level for power, then skip
|
||||
if (pc.getLevel() < powerreq.getLevel())
|
||||
continue;
|
||||
|
||||
// See if any prereq powers needed
|
||||
boolean valid = true;
|
||||
ConcurrentHashMap<Integer, Byte> preqs = powerreq.getPowerReqs();
|
||||
for (Integer tok : preqs.keySet()) {
|
||||
if (!powers.containsKey(tok))
|
||||
valid = false;
|
||||
else {
|
||||
CharacterPower cpp = powers.get(tok);
|
||||
if ((cpp.getTrains() + cpp.grantedTrains) < preqs.get(tok))
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
if (!valid)
|
||||
continue;
|
||||
|
||||
// See if any prereq skills needed
|
||||
preqs = powerreq.getSkillReqs();
|
||||
for (Integer tok : preqs.keySet()) {
|
||||
if (tok == 0)
|
||||
continue;
|
||||
CharacterSkill found = null;
|
||||
for (CharacterSkill sk : skills.values()) {
|
||||
if (sk.getToken() == tok) {
|
||||
found = sk;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (found != null) {
|
||||
if (found.getModifiedAmountBeforeMods() < preqs.get(tok))
|
||||
valid = false;
|
||||
} else
|
||||
valid = false;
|
||||
}
|
||||
if (!valid)
|
||||
continue;
|
||||
|
||||
|
||||
if (!powers.containsKey(powersBase.getToken())) {
|
||||
CharacterPower newPower = new CharacterPower(powersBase, pc);
|
||||
CharacterPower cp = null;
|
||||
try {
|
||||
cp = DbManager.CharacterPowerQueries.ADD_CHARACTER_POWER(newPower);
|
||||
} catch (Exception e) {
|
||||
cp = null;
|
||||
}
|
||||
if (cp != null){
|
||||
cp.requiredLevel = (int) powerreq.getLevel();
|
||||
powers.put(powersBase.getToken(), cp);
|
||||
}
|
||||
|
||||
else
|
||||
Logger.error("Failed to add CharacterPower to player " + pc.getObjectUUID());
|
||||
}else{
|
||||
CharacterPower cp = powers.get(powersBase.getToken());
|
||||
if (cp != null)
|
||||
if (cp.requiredLevel == 0) {
|
||||
cp.requiredLevel = (int) powerreq.getLevel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void grantTrains(PlayerCharacter pc) {
|
||||
if (pc == null)
|
||||
return;
|
||||
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
|
||||
for (CharacterPower cp : powers.values()) {
|
||||
cp.grantedTrains = cp.getGrantedTrains(pc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This verifies if a power is valid for a players rune
|
||||
*/
|
||||
private static boolean powerAllowed(Integer token, ArrayList<PowerReq> powersGranted, PlayerCharacter pc) {
|
||||
ConcurrentHashMap<String, CharacterSkill> skills = pc.getSkills();
|
||||
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
|
||||
if (skills == null || powers == null)
|
||||
return false;
|
||||
for (PowerReq powerreq : powersGranted) {
|
||||
PowersBase pb = powerreq.getPowersBase();
|
||||
if (pb != null) {
|
||||
if (pb.getToken() == token) {
|
||||
|
||||
//test level requirements
|
||||
if (powerreq.getLevel() > pc.getLevel()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//test skill requirements are met
|
||||
ConcurrentHashMap<Integer, Byte> skillReqs = powerreq.getSkillReqs();
|
||||
for (int tok : skillReqs.keySet()) {
|
||||
boolean valid = false;
|
||||
if (tok == 0)
|
||||
continue;
|
||||
for (CharacterSkill skill : skills.values()) {
|
||||
if (skill.getToken() == tok) {
|
||||
if (skill.getModifiedAmountBeforeMods() < skillReqs.get(tok))
|
||||
return false;
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!valid)
|
||||
return false;
|
||||
}
|
||||
|
||||
//test power prerequisites are met
|
||||
ConcurrentHashMap<Integer, Byte> powerReqs = powerreq.getPowerReqs();
|
||||
for (int tok : powerReqs.keySet()) {
|
||||
if (!powers.containsKey(tok))
|
||||
return false;
|
||||
CharacterPower cp = powers.get(tok);
|
||||
if (cp.getTotalTrains() < powerReqs.get(tok))
|
||||
return false;
|
||||
}
|
||||
|
||||
//everything passed. power is valid
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//This verifies the power is not blocked from refining by prereqs on other powers.
|
||||
private boolean canRefine(PlayerCharacter pc) {
|
||||
if (this.power == null || pc == null)
|
||||
return false;
|
||||
|
||||
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
|
||||
Race race = pc.getRace();
|
||||
if (race != null) {
|
||||
if (!canRefine(race.getPowersGranted(), powers, pc))
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
BaseClass bc = pc.getBaseClass();
|
||||
if (bc != null) {
|
||||
if (!canRefine(bc.getPowersGranted(), powers, pc))
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
PromotionClass promo = pc.getPromotionClass();
|
||||
if (promo != null)
|
||||
if (!canRefine(promo.getPowersGranted(), powers, pc))
|
||||
return false;
|
||||
ArrayList<CharacterRune> runes = pc.getRunes();
|
||||
if (runes != null) {
|
||||
for (CharacterRune rune : runes) {
|
||||
if (!canRefine(rune.getPowersGranted(), powers, pc))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//all tests passed. Can refine
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean canRefine(ArrayList<PowerReq> powersGranted, ConcurrentHashMap<Integer, CharacterPower> powers, PlayerCharacter pc) {
|
||||
for (PowerReq pr : powersGranted) {
|
||||
ConcurrentHashMap<Integer, Byte> powerReqs = pr.getPowerReqs();
|
||||
for (int token : powerReqs.keySet()) {
|
||||
if (token == this.power.getToken()) {
|
||||
//this is a prereq, find the power and make sure it has enough trains
|
||||
int trainsReq = (int)powerReqs.get(token);
|
||||
for (CharacterPower cp : powers.values()) {
|
||||
if (cp.power.getToken() == pr.getToken()) {
|
||||
if (this.getTotalTrains() <= trainsReq && cp.getTrains() > 0) {
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "You must refine " + cp.power.getName() + " to 0 before refining any more from this power.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean canTrain(PlayerCharacter pc) {
|
||||
if (this.power == null || pc == null)
|
||||
return false;
|
||||
int token = this.power.getToken();
|
||||
boolean valid = false;
|
||||
Race race = pc.getRace();
|
||||
if (race != null) {
|
||||
if (CharacterPower.powerAllowed(token, race.getPowersGranted(), pc))
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
BaseClass bc = pc.getBaseClass();
|
||||
if (bc != null) {
|
||||
if (CharacterPower.powerAllowed(token, bc.getPowersGranted(), pc))
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
PromotionClass promo = pc.getPromotionClass();
|
||||
if (promo != null)
|
||||
if (CharacterPower.powerAllowed(token, promo.getPowersGranted(), pc))
|
||||
return true;
|
||||
ArrayList<CharacterRune> runes = pc.getRunes();
|
||||
for (CharacterRune rune : runes)
|
||||
if (CharacterPower.powerAllowed(token, rune.getPowersGranted(), pc))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Serializing
|
||||
*/
|
||||
|
||||
public static void serializeForClientMsg(CharacterPower characterPower, ByteBufferWriter writer) {
|
||||
if (characterPower.power != null)
|
||||
writer.putInt(characterPower.power.getToken());
|
||||
else
|
||||
writer.putInt(0);
|
||||
writer.putInt(characterPower.getTrains());
|
||||
}
|
||||
|
||||
public static CharacterPower getPower(int tableId) {
|
||||
return DbManager.CharacterPowerQueries.GET_CHARACTER_POWER(tableId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
DbManager.CharacterPowerQueries.updateDatabase(this);
|
||||
}
|
||||
|
||||
public int getRequiredLevel() {
|
||||
return requiredLevel;
|
||||
}
|
||||
|
||||
public void setRequiredLevel(int requiredLevel) {
|
||||
this.requiredLevel = requiredLevel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.DispatchChannel;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.ApplyRuneMsg;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CharacterRune extends AbstractGameObject {
|
||||
|
||||
private final RuneBase runeBase;
|
||||
private final int player;
|
||||
private final ArrayList<SkillReq> skillsGranted;
|
||||
private final ArrayList<PowerReq> powersGranted;
|
||||
private final ArrayList<RuneBaseEffect> effectsGranted;
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public CharacterRune(RuneBase runeBase, int characterID) {
|
||||
super();
|
||||
this.runeBase = runeBase;
|
||||
this.player = characterID;
|
||||
if (this.runeBase != null) {
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
||||
} else {
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.powersGranted = new ArrayList<>();
|
||||
}
|
||||
if (this.runeBase != null)
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
||||
else
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public CharacterRune(RuneBase runeBase, int characterID, int newUUID) {
|
||||
super(newUUID);
|
||||
this.runeBase = runeBase;
|
||||
this.player = characterID;
|
||||
if (this.runeBase != null) {
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
||||
} else {
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.powersGranted = new ArrayList<>();
|
||||
}
|
||||
if (this.runeBase != null)
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
||||
else
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public CharacterRune(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
this.runeBase = RuneBase.getRuneBase(rs.getInt("RuneBaseID"));
|
||||
this.player = rs.getInt("CharacterID");
|
||||
if (this.runeBase != null) {
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
||||
} else {
|
||||
Logger.error("Failed to find RuneBase for CharacterRune " + this.getObjectUUID());
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.powersGranted = new ArrayList<>();
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public RuneBase getRuneBase() {
|
||||
return this.runeBase;
|
||||
}
|
||||
|
||||
public int getRuneBaseID() {
|
||||
if (this.runeBase != null)
|
||||
return this.runeBase.getObjectUUID();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getPlayerID() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public ArrayList<SkillReq> getSkillsGranted() {
|
||||
return this.skillsGranted;
|
||||
}
|
||||
|
||||
public ArrayList<PowerReq> getPowersGranted() {
|
||||
return this.powersGranted;
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
||||
return this.effectsGranted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Serializing
|
||||
*/
|
||||
|
||||
public static void serializeForClientMsg(CharacterRune characterRune, ByteBufferWriter writer) {
|
||||
if (characterRune.runeBase != null) {
|
||||
int idd = characterRune.runeBase.getObjectUUID();
|
||||
if (idd > 3000 && idd < 3050)
|
||||
writer.putInt(4);
|
||||
else
|
||||
writer.putInt(5);
|
||||
// writer.putInt(this.runeBase.getMessageType());
|
||||
writer.putInt(0);
|
||||
writer.putInt(characterRune.runeBase.getObjectUUID());
|
||||
writer.putInt(characterRune.getObjectType().ordinal());
|
||||
writer.putInt(characterRune.getObjectUUID());
|
||||
} else {
|
||||
for (int i = 0; i < 5; i++)
|
||||
writer.putInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean grantRune(PlayerCharacter pc, int runeID) {
|
||||
//Verify not too many runes
|
||||
ArrayList<CharacterRune> runes = pc.getRunes();
|
||||
boolean worked = false;
|
||||
synchronized (runes) {
|
||||
if (runes == null || runes.size() > 12)
|
||||
return false;
|
||||
|
||||
//Verify player doesn't already have rune
|
||||
for (CharacterRune rune : runes) {
|
||||
RuneBase rb = rune.runeBase;
|
||||
if (rb == null || rb.getObjectUUID() == runeID)
|
||||
return false;
|
||||
}
|
||||
|
||||
RuneBase rb = RuneBase.getRuneBase(runeID);
|
||||
if (rb == null)
|
||||
return false;
|
||||
|
||||
//Attempt to add rune to database
|
||||
CharacterRune toAdd = new CharacterRune(rb, pc.getObjectUUID());
|
||||
CharacterRune rune = null;
|
||||
try {
|
||||
rune = DbManager.CharacterRuneQueries.ADD_CHARACTER_RUNE(toAdd);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
if (rune == null)
|
||||
return false;
|
||||
|
||||
//attempt add rune to player
|
||||
worked = pc.addRune(rune);
|
||||
|
||||
//worked, send ApplyRuneMsg
|
||||
if (worked) {
|
||||
ApplyRuneMsg arm = new ApplyRuneMsg(pc.getObjectType().ordinal(), pc.getObjectUUID(), runeID, rune.getObjectType().ordinal(), rune.getObjectUUID(), true);
|
||||
DispatchMessage.dispatchMsgToInterestArea(pc, arm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
|
||||
CharacterSkill.calculateSkills(pc);
|
||||
pc.applyBonuses();
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean removeRune(PlayerCharacter pc, int runeID) {
|
||||
ArrayList<CharacterRune> runes = pc.getRunes();
|
||||
synchronized (runes) {
|
||||
for (CharacterRune rune : runes) {
|
||||
RuneBase rb = rune.runeBase;
|
||||
if (rb == null)
|
||||
continue;
|
||||
if (rb.getObjectUUID() == runeID && DbManager.CharacterRuneQueries.DELETE_CHARACTER_RUNE(rune)) {
|
||||
runes.remove(runes.indexOf(rune));
|
||||
CharacterSkill.calculateSkills(pc);
|
||||
pc.applyBonuses();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
DbManager.CharacterRuneQueries.updateDatabase(this);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,121 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.net.ByteBufferWriter;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public enum CharacterTitle {
|
||||
|
||||
NONE(0,0,0,""),
|
||||
CSR_1(255,0,0,"CCR"),
|
||||
CSR_2(255,0,0,"CCR"),
|
||||
CSR_3(255,0,0,"CCR"),
|
||||
CSR_4(251,181,13,"CCR"),
|
||||
DEVELOPER(166,153,114,"Programmer"),
|
||||
QA(88,250,244,"GIRLFRIEND");
|
||||
|
||||
CharacterTitle(int _r, int _g, int _b, String _prefix) {
|
||||
char[] str_header = ("^\\c" +
|
||||
(((_r < 100)?((_r < 10)?"00":"0"):"") + ((byte) _r & 0xFF)) +
|
||||
(((_g < 100)?((_g < 10)?"00":"0"):"") + ((byte) _g & 0xFF)) +
|
||||
(((_b < 100)?((_b < 10)?"00":"0"):"") + ((byte) _b & 0xFF)) +
|
||||
'<' + _prefix + "> ").toCharArray();
|
||||
|
||||
char[] str_footer = ("^\\c255255255").toCharArray();
|
||||
|
||||
this.headerLength = str_header.length;
|
||||
this.footerLength = str_footer.length;
|
||||
|
||||
this.header = ByteBuffer.allocateDirect(headerLength << 1);
|
||||
this.footer = ByteBuffer.allocateDirect(footerLength << 1);
|
||||
|
||||
ByteBufferWriter headWriter= new ByteBufferWriter(header);
|
||||
|
||||
for(char c : str_header) {
|
||||
headWriter.putChar(c);
|
||||
}
|
||||
|
||||
ByteBufferWriter footWriter = new ByteBufferWriter(footer);
|
||||
|
||||
for(char c : str_footer) {
|
||||
footWriter.putChar(c);
|
||||
}
|
||||
}
|
||||
|
||||
int headerLength, footerLength;
|
||||
private ByteBuffer header;
|
||||
private ByteBuffer footer;
|
||||
|
||||
public void _serializeFirstName(ByteBufferWriter writer, String firstName) {
|
||||
_serializeFirstName(writer, firstName, false);
|
||||
}
|
||||
|
||||
public void _serializeFirstName(ByteBufferWriter writer, String firstName, boolean smallString) {
|
||||
if(this.ordinal() == 0) {
|
||||
if (smallString)
|
||||
writer.putSmallString(firstName);
|
||||
else
|
||||
writer.putString(firstName);
|
||||
return;
|
||||
}
|
||||
|
||||
char[] chars = firstName.toCharArray();
|
||||
|
||||
if (smallString)
|
||||
writer.put((byte)(chars.length + this.headerLength));
|
||||
else
|
||||
writer.putInt(chars.length + this.headerLength);
|
||||
writer.putBB(header);
|
||||
|
||||
for(char c : chars) {
|
||||
writer.putChar(c);
|
||||
}
|
||||
}
|
||||
|
||||
public void _serializeLastName(ByteBufferWriter writer, String lastName, boolean haln, boolean asciiLastName) {
|
||||
_serializeLastName(writer, lastName, haln, asciiLastName, false);
|
||||
}
|
||||
|
||||
public void _serializeLastName(ByteBufferWriter writer, String lastName, boolean haln, boolean asciiLastName, boolean smallString) {
|
||||
if (!haln || asciiLastName) {
|
||||
if(this.ordinal() == 0) {
|
||||
if (smallString)
|
||||
writer.putSmallString(lastName);
|
||||
else
|
||||
writer.putString(lastName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!haln || asciiLastName) {
|
||||
char[] chars = lastName.toCharArray();
|
||||
|
||||
if (smallString)
|
||||
writer.put((byte)(chars.length + this.footerLength));
|
||||
else
|
||||
writer.putInt(chars.length + this.footerLength);
|
||||
|
||||
for(char c : chars) {
|
||||
writer.putChar(c);
|
||||
}
|
||||
|
||||
writer.putBB(footer);
|
||||
} else {
|
||||
if (smallString)
|
||||
writer.put((byte)this.footerLength);
|
||||
else
|
||||
writer.putInt(this.footerLength);
|
||||
writer.putBB(footer);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,65 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.awt.geom.Line2D;
|
||||
|
||||
|
||||
public class Colliders {
|
||||
|
||||
|
||||
private Line2D collider;
|
||||
private int doorID;
|
||||
private boolean link = false;
|
||||
public float startX;
|
||||
public float startY;
|
||||
public float endX;
|
||||
public float endY;
|
||||
|
||||
public Colliders(Line2D collider, int doorID, boolean link) {
|
||||
super();
|
||||
this.collider = collider;
|
||||
this.doorID = doorID;
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public Colliders(float startX, float startY, float endX ,float endY, int doorID, boolean link) {
|
||||
super();
|
||||
this.startX = startX;
|
||||
this.startY = startY;
|
||||
this.endX = endX;
|
||||
this.endY = endY;
|
||||
this.doorID = doorID;
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
|
||||
public int getDoorID() {
|
||||
return doorID;
|
||||
}
|
||||
|
||||
public Line2D getCollider() {
|
||||
return collider;
|
||||
}
|
||||
|
||||
|
||||
public boolean isLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
|
||||
public void setLink(boolean link) {
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
|
||||
|
||||
public class Condemned {
|
||||
|
||||
private int ID;
|
||||
private int playerUID;
|
||||
private int parent;
|
||||
private int guildUID;
|
||||
private int friendType;
|
||||
private boolean active;
|
||||
public static final int INDIVIDUAL = 2;
|
||||
public static final int GUILD = 4;
|
||||
public static final int NATION = 5;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public Condemned(ResultSet rs) throws SQLException {
|
||||
this.playerUID = rs.getInt("playerUID");
|
||||
this.parent = rs.getInt("buildingUID");
|
||||
this.guildUID = rs.getInt("guildUID");
|
||||
this.friendType = rs.getInt("friendType");
|
||||
this.active = rs.getBoolean("active");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public Condemned(int playerUID, int parent, int guildUID, int friendType) {
|
||||
super();
|
||||
this.playerUID = playerUID;
|
||||
this.parent = parent;
|
||||
this.guildUID = guildUID;
|
||||
this.friendType = friendType;
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public int getPlayerUID() {
|
||||
return playerUID;
|
||||
}
|
||||
|
||||
|
||||
public int getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
||||
public int getGuildUID() {
|
||||
return guildUID;
|
||||
}
|
||||
|
||||
|
||||
public int getFriendType() {
|
||||
return friendType;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public boolean setActive(boolean active) {
|
||||
if (!DbManager.BuildingQueries.updateActiveCondemn(this, active))
|
||||
return false;
|
||||
this.active = active;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import ch.claude_martin.enumbitset.EnumBitSet;
|
||||
import engine.Enum;
|
||||
import engine.gameManager.DbManager;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Contract extends AbstractGameObject {
|
||||
|
||||
private final int contractID;
|
||||
private final String name;
|
||||
private final int mobbaseID;
|
||||
private final int classID;
|
||||
private final int extraRune;
|
||||
private final int iconID;
|
||||
private int vendorID;
|
||||
private boolean isTrainer;
|
||||
private VendorDialog vendorDialog;
|
||||
private ArrayList<Integer> npcMenuOptions = new ArrayList<>();
|
||||
private ArrayList<Integer> npcModTypeTable = new ArrayList<>();
|
||||
private ArrayList<Integer> npcModSuffixTable = new ArrayList<>();
|
||||
private ArrayList<Byte> itemModTable = new ArrayList<>();
|
||||
private ArrayList<MobEquipment> sellInventory = new ArrayList<>();
|
||||
private EnumBitSet<Enum.BuildingGroup> allowedBuildings;
|
||||
|
||||
private ArrayList<Integer> buyItemType = new ArrayList<>();
|
||||
private ArrayList<Integer> buySkillToken = new ArrayList<>();
|
||||
private ArrayList<Integer> buyUnknownToken = new ArrayList<>();
|
||||
|
||||
public int equipmentSet = 0;
|
||||
public int inventorySet = 0;
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public Contract(int contractID, String name, int mobbaseID, int classID, int dialogID, int iconID, int extraRune) {
|
||||
super();
|
||||
this.contractID = contractID;
|
||||
this.name = name;
|
||||
this.mobbaseID = mobbaseID;
|
||||
this.classID = classID;
|
||||
this.iconID = iconID;
|
||||
this.extraRune = extraRune;
|
||||
this.vendorDialog = VendorDialog.getVendorDialog(dialogID);
|
||||
setBools();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public Contract(int contractID, String name, int mobbaseID, int classID, int dialogID, int iconID, int extraRune, int newUUID) {
|
||||
super(newUUID);
|
||||
this.contractID = contractID;
|
||||
this.name = name;
|
||||
this.mobbaseID = mobbaseID;
|
||||
this.classID = classID;
|
||||
this.iconID = iconID;
|
||||
this.extraRune = extraRune;
|
||||
this.vendorDialog = VendorDialog.getVendorDialog(dialogID);
|
||||
setBools();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public Contract(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
this.contractID = rs.getInt("contractID");
|
||||
this.name = rs.getString("name");
|
||||
this.mobbaseID = rs.getInt("mobbaseID");
|
||||
this.classID = rs.getInt("classID");
|
||||
this.extraRune = rs.getInt("extraRune");
|
||||
this.vendorDialog = VendorDialog.getVendorDialog(rs.getInt("dialogID"));
|
||||
this.iconID = rs.getInt("iconID");
|
||||
this.vendorID = rs.getInt("vendorID");
|
||||
this.allowedBuildings = EnumBitSet.asEnumBitSet(rs.getLong("allowedBuildingTypeID"), Enum.BuildingGroup.class);
|
||||
this.equipmentSet = rs.getInt("equipSetID");
|
||||
this.inventorySet = rs.getInt("inventorySet");
|
||||
|
||||
try {
|
||||
String menuoptions = rs.getString("menuoptions");
|
||||
|
||||
if (!menuoptions.isEmpty()){
|
||||
String[] data = menuoptions.split(" ");
|
||||
for (String data1 : data) {
|
||||
this.npcMenuOptions.add(Integer.parseInt(data1));
|
||||
}
|
||||
}
|
||||
|
||||
String modtypetable = rs.getString("pTable");
|
||||
if (!modtypetable.isEmpty()){
|
||||
String[] data = modtypetable.split(" ");
|
||||
for (String data1 : data) {
|
||||
this.npcModTypeTable.add(Integer.parseInt(data1));
|
||||
}
|
||||
}
|
||||
|
||||
String suffix = rs.getString("sTable");
|
||||
|
||||
if (!suffix.isEmpty()){
|
||||
String[] data1 = suffix.split(" ");
|
||||
|
||||
for (String data11 : data1) {
|
||||
this.npcModSuffixTable.add(Integer.parseInt(data11));
|
||||
}
|
||||
}
|
||||
|
||||
String itemMod = rs.getString("itemModTable");
|
||||
|
||||
if (!itemMod.isEmpty()){
|
||||
String[] data2 = itemMod.split(" ");
|
||||
for (byte i = 0; i < data2.length; i++) {
|
||||
this.itemModTable.add(Byte.parseByte(data2[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (SQLException | NumberFormatException e) {
|
||||
Logger.error( "Error when parsing mod tables");
|
||||
}
|
||||
setBools();
|
||||
}
|
||||
|
||||
//Specify if trainer, merchant, banker, etc via classID
|
||||
private void setBools() {
|
||||
DbManager.ContractQueries.GET_GENERIC_INVENTORY(this);
|
||||
DbManager.ContractQueries.GET_SELL_LISTS(this);
|
||||
|
||||
this.isTrainer = this.classID > 2499 && this.classID < 3050 || this.classID == 2028;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public int getContractID() {
|
||||
return this.contractID;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public int getMobbaseID() {
|
||||
return this.mobbaseID;
|
||||
}
|
||||
|
||||
public int getClassID() {
|
||||
return this.classID;
|
||||
}
|
||||
|
||||
public int getExtraRune() {
|
||||
return this.extraRune;
|
||||
}
|
||||
|
||||
public boolean isTrainer() {
|
||||
return this.isTrainer;
|
||||
}
|
||||
|
||||
public int getIconID() {
|
||||
return this.iconID;
|
||||
}
|
||||
|
||||
public int getVendorID() {
|
||||
return this.vendorID;
|
||||
}
|
||||
|
||||
public VendorDialog getVendorDialog() {
|
||||
return this.vendorDialog;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getNPCMenuOptions() {
|
||||
return this.npcMenuOptions;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getNPCModTypeTable() {
|
||||
return this.npcModTypeTable;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getNpcModSuffixTable() {
|
||||
return npcModSuffixTable;
|
||||
}
|
||||
|
||||
public ArrayList<Byte> getItemModTable() {
|
||||
return itemModTable;
|
||||
}
|
||||
|
||||
public ArrayList<MobEquipment> getSellInventory() {
|
||||
return this.sellInventory;
|
||||
}
|
||||
|
||||
public int getPromotionClass() {
|
||||
if (this.classID < 2504 || this.classID > 2526)
|
||||
return 0;
|
||||
return this.classID;
|
||||
}
|
||||
|
||||
public boolean isRuneMaster() {
|
||||
return (this.classID == 850);
|
||||
}
|
||||
|
||||
public boolean isArtilleryCaptain() {
|
||||
return this.contractID == 839 || this.contractID == 842 ;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
DbManager.ContractQueries.updateDatabase(this);
|
||||
}
|
||||
|
||||
public EnumBitSet<Enum.BuildingGroup> getAllowedBuildings() {
|
||||
return allowedBuildings;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getBuyItemType() {
|
||||
return this.buyItemType;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getBuySkillToken() {
|
||||
return this.buySkillToken;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getBuyUnknownToken() {
|
||||
return this.buyUnknownToken;
|
||||
}
|
||||
|
||||
public boolean canSlotinBuilding(Building building) {
|
||||
|
||||
// Need a building to slot in a building!
|
||||
if (building == null)
|
||||
return false;
|
||||
|
||||
// Can't slot in anything but a blueprintted building
|
||||
if (building.getBlueprintUUID() == 0)
|
||||
return false;
|
||||
|
||||
// No buildings no slotting
|
||||
if (this.allowedBuildings.size() == 0)
|
||||
return false;
|
||||
|
||||
// Binary match
|
||||
return (building.getBlueprint().getBuildingGroup().elementOf(this.allowedBuildings));
|
||||
|
||||
}
|
||||
|
||||
public int getEquipmentSet() {
|
||||
return equipmentSet;
|
||||
}
|
||||
|
||||
public static boolean NoSlots(Contract contract){
|
||||
switch(contract.contractID){
|
||||
case 830:
|
||||
case 838:
|
||||
case 847:
|
||||
case 860:
|
||||
case 866:
|
||||
case 865:
|
||||
case 1502003:
|
||||
case 889:
|
||||
case 890:
|
||||
case 896:
|
||||
case 974:
|
||||
case 1064:
|
||||
case 1172:
|
||||
case 1267:
|
||||
case 1368:
|
||||
case 1468:
|
||||
case 1520:
|
||||
case 1528:
|
||||
case 1553:
|
||||
case 1578:
|
||||
case 1617:
|
||||
case 1667:
|
||||
case 1712:
|
||||
case 893:
|
||||
case 820:
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
if (contract.isTrainer)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,419 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.GameObjectType;
|
||||
import engine.Enum.GridObjectType;
|
||||
import engine.Enum.ItemType;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.exception.SerializationException;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.job.JobContainer;
|
||||
import engine.job.JobScheduler;
|
||||
import engine.jobs.RemoveCorpseJob;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.UnloadObjectsMsg;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class Corpse extends AbstractWorldObject {
|
||||
|
||||
private static AtomicInteger corpseCounter = new AtomicInteger(0);
|
||||
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private int level;
|
||||
private int belongsToType;
|
||||
private int belongsToID;
|
||||
private ArrayList<Item> inventory;
|
||||
public JobContainer cleanup;
|
||||
private boolean asciiLastName = true;
|
||||
private boolean hasGold = false;
|
||||
private int inBuildingID = 0;
|
||||
private int inFloorID = -1;
|
||||
private int inBuilding = -1;
|
||||
|
||||
/**
|
||||
* No Id Constructor
|
||||
*/
|
||||
public Corpse( int newUUID, AbstractCharacter belongsTo, boolean safeZone,boolean enterWorld) {
|
||||
super(newUUID);
|
||||
this.setObjectType();
|
||||
this.inventory = new ArrayList<>();
|
||||
this.gridObjectType = GridObjectType.STATIC;
|
||||
this.setObjectTypeMask(MBServerStatics.MASK_CORPSE);
|
||||
if (belongsTo != null) {
|
||||
this.firstName = belongsTo.getFirstName();
|
||||
this.lastName = belongsTo.getLastName();
|
||||
this.asciiLastName = belongsTo.asciiLastName();
|
||||
this.level = belongsTo.getLevel();
|
||||
this.belongsToType = belongsTo.getObjectType().ordinal();
|
||||
this.belongsToID = belongsTo.getObjectUUID();
|
||||
this.inBuilding = belongsTo.getInBuilding();
|
||||
this.inFloorID = belongsTo.getInFloorID();
|
||||
this.inBuildingID = belongsTo.getInBuildingID();
|
||||
this.setLoc(belongsTo.getLoc());
|
||||
} else {
|
||||
Logger.error("No player passed in for corpse");
|
||||
this.firstName = "";
|
||||
this.lastName = "";
|
||||
this.level = 1;
|
||||
this.belongsToType = 0;
|
||||
this.belongsToID = 0;
|
||||
}
|
||||
this.setObjectTypeMask(MBServerStatics.MASK_CORPSE);
|
||||
|
||||
if (!safeZone)
|
||||
transferInventory(belongsTo,enterWorld);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public boolean removeItemFromInventory(Item item) {
|
||||
synchronized (this.inventory) {
|
||||
if (this.inventory.contains(item)) {
|
||||
this.inventory.remove(item);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void transferInventory(AbstractCharacter belongsTo,boolean enterWorld) {
|
||||
if (belongsTo == null) {
|
||||
Logger.error( "Can't find player that corpse " + this.getObjectUUID() + " belongs to");
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO transfer items from players inventory and trade window to corpse
|
||||
CharacterItemManager cim = belongsTo.getCharItemManager();
|
||||
if (cim != null)
|
||||
cim.transferEntireInventory(this.inventory, this,enterWorld);
|
||||
else
|
||||
Logger.error( "Can't find inventory for player " + belongsTo.getObjectUUID());
|
||||
}
|
||||
|
||||
public static int getNextCorpseCount() {
|
||||
return Corpse.corpseCounter.addAndGet(2); //newUUID and runeID
|
||||
}
|
||||
|
||||
//Create a new corpse
|
||||
public static Corpse makeCorpse(AbstractCharacter belongsTo,boolean enterWorld) {
|
||||
boolean safeZone = false;
|
||||
if (belongsTo != null && belongsTo.getObjectType() == GameObjectType.PlayerCharacter)
|
||||
safeZone = ((PlayerCharacter)belongsTo).isInSafeZone();
|
||||
|
||||
|
||||
|
||||
Corpse corpse = new Corpse(Corpse.getNextCorpseCount(), belongsTo, safeZone,enterWorld);
|
||||
|
||||
//create cleanup job
|
||||
if (corpse != null) {
|
||||
RemoveCorpseJob rcj = new RemoveCorpseJob(corpse);
|
||||
corpse.cleanup = JobScheduler.getInstance().scheduleJob(rcj, MBServerStatics.CORPSE_CLEANUP_TIMER_MS);
|
||||
DbManager.addToCache(corpse);
|
||||
}
|
||||
|
||||
return corpse;
|
||||
}
|
||||
|
||||
//Get existing corpse
|
||||
public static Corpse getCorpse(int newUUID) {
|
||||
return (Corpse) DbManager.getFromCache(GameObjectType.Corpse, newUUID);
|
||||
}
|
||||
|
||||
public Item lootItem(Item i, PlayerCharacter looter) {
|
||||
//make sure looter exists
|
||||
if (looter == null)
|
||||
return null;
|
||||
|
||||
//get looters item manager
|
||||
CharacterItemManager looterItems = looter.getCharItemManager();
|
||||
if (looterItems == null)
|
||||
return null;
|
||||
|
||||
synchronized (this.inventory) {
|
||||
|
||||
//make sure player has item in inventory
|
||||
if (!this.inventory.contains(i))
|
||||
return null;
|
||||
|
||||
//get weight of item
|
||||
ItemBase ib = i.getItemBase();
|
||||
if (ib == null)
|
||||
return null;
|
||||
short weight = ib.getWeight();
|
||||
|
||||
//make sure looter has room for item
|
||||
if (ib.getType().equals(ItemType.GOLD) == false && !looterItems.hasRoomInventory(weight))
|
||||
return null;
|
||||
|
||||
//attempt to transfer item in db
|
||||
if (ib.getType().equals(ItemType.GOLD)) {
|
||||
if (!looterItems.moveGoldToInventory(i, i.getNumOfItems()))
|
||||
return null;
|
||||
} else if (!i.moveItemToInventory(looter))
|
||||
return null;
|
||||
|
||||
//db transfer successful, remove from this character
|
||||
this.inventory.remove(this.inventory.indexOf(i));
|
||||
}
|
||||
|
||||
//add item to looter.
|
||||
if (!looterItems.addItemToInventory(i))
|
||||
return null;
|
||||
|
||||
//calculate new weights
|
||||
looterItems.calculateInventoryWeight();
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
//remove corpse from world
|
||||
public static void removeCorpse(int newUUID, boolean fromTimer) {
|
||||
Corpse c = (Corpse) DbManager.getFromCache(GameObjectType.Corpse, newUUID);
|
||||
if (c == null)
|
||||
Logger.error( "No corpse found of ID " + newUUID);
|
||||
else
|
||||
Corpse.removeCorpse(c, fromTimer);
|
||||
}
|
||||
|
||||
public static void removeCorpse(Corpse corpse, boolean fromTimer) {
|
||||
if (corpse == null)
|
||||
return;
|
||||
|
||||
corpse.purgeInventory();
|
||||
|
||||
//cleanup timer
|
||||
if (!fromTimer) {
|
||||
JobScheduler.getInstance().cancelScheduledJob(corpse.cleanup);
|
||||
}
|
||||
corpse.cleanup = null;
|
||||
|
||||
//Remove from world
|
||||
UnloadObjectsMsg uom = new UnloadObjectsMsg();
|
||||
uom.addObject(corpse);
|
||||
DispatchMessage.sendToAllInRange(corpse, uom);
|
||||
WorldGrid.RemoveWorldObject(corpse);
|
||||
|
||||
//clear from cache
|
||||
DbManager.removeFromCache(corpse);
|
||||
}
|
||||
|
||||
|
||||
public static void _serializeForClientMsg(Corpse corpse, ByteBufferWriter writer)
|
||||
throws SerializationException {}
|
||||
|
||||
public static void _serializeForClientMsg(Corpse corpse, ByteBufferWriter writer, boolean aln)
|
||||
throws SerializationException {
|
||||
|
||||
Building building = null;
|
||||
if (corpse.inBuildingID != 0)
|
||||
building = BuildingManager.getBuildingFromCache(corpse.inBuildingID);
|
||||
|
||||
//Send Rune Count
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
writer.putInt(1);
|
||||
|
||||
//Send Corpse Rune
|
||||
writer.putInt(1);
|
||||
writer.putInt(0);
|
||||
writer.putInt(MBServerStatics.TOMBSTONE);
|
||||
writer.putInt(corpse.getObjectType().ordinal());
|
||||
writer.putInt((corpse.getObjectUUID() + 1));
|
||||
|
||||
//Send Stats
|
||||
writer.putInt(5);
|
||||
writer.putInt(MBServerStatics.STAT_STR_ID); // Strength ID
|
||||
writer.putInt(5000);
|
||||
writer.putInt(MBServerStatics.STAT_SPI_ID); // Spirit ID
|
||||
writer.putInt(0);
|
||||
writer.putInt(MBServerStatics.STAT_CON_ID); // Constitution ID
|
||||
writer.putInt(0);
|
||||
writer.putInt(MBServerStatics.STAT_DEX_ID); // Dexterity ID
|
||||
writer.putInt(0);
|
||||
writer.putInt(MBServerStatics.STAT_INT_ID); // Intelligence ID
|
||||
writer.putInt(0);
|
||||
|
||||
//Send Name
|
||||
writer.putString(corpse.firstName);
|
||||
if (aln && !corpse.asciiLastName)
|
||||
writer.putString("");
|
||||
else
|
||||
writer.putString(corpse.lastName);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
writer.put((byte)1);
|
||||
|
||||
//Send Corpse Info
|
||||
writer.putInt(0);
|
||||
writer.putInt(corpse.getObjectType().ordinal());
|
||||
writer.putInt((corpse.getObjectUUID()));
|
||||
writer.putFloat(10f); //FaceDir or scale
|
||||
writer.putFloat(10); //FaceDir or scale
|
||||
writer.putFloat(10); //FaceDir or scale
|
||||
|
||||
writer.putFloat(corpse.getLoc().x);
|
||||
writer.putFloat(corpse.getLoc().y);
|
||||
writer.putFloat(corpse.getLoc().z);
|
||||
|
||||
writer.putFloat(6.235f); //1.548146f); //w
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
|
||||
//Send BelongsToInfo
|
||||
writer.putInt(((corpse.level / 10))); //Rank
|
||||
writer.putInt(corpse.level); //Level
|
||||
writer.putInt(1);
|
||||
writer.putInt(1);
|
||||
writer.putInt(1); //Missing this?
|
||||
writer.putInt(2);
|
||||
writer.putInt(1);
|
||||
// writer.putInt(0); //not needed?
|
||||
writer.putInt(0);
|
||||
|
||||
writer.putInt(corpse.belongsToType);
|
||||
writer.putInt(corpse.belongsToID);
|
||||
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
|
||||
|
||||
|
||||
for (int i=0;i<9;i++)
|
||||
writer.putInt(0);
|
||||
writer.putShort((short)0);
|
||||
writer.put((byte)0);
|
||||
|
||||
//Send Errant Guild Info
|
||||
for (int i=0;i<13;i++)
|
||||
writer.putInt(0);
|
||||
writer.putInt(16);
|
||||
writer.putInt(16);
|
||||
writer.putInt(16);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0); //Missing this?
|
||||
writer.putInt(16);
|
||||
writer.putInt(16);
|
||||
writer.putInt(16);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
|
||||
//Send unknown counter
|
||||
writer.putInt(1);
|
||||
writer.putInt(0x047A0E67); //What is this?
|
||||
writer.put((byte)0);
|
||||
|
||||
//Send unknown
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
writer.putFloat(1293.4449f); //Unknown
|
||||
writer.putFloat(-100f); //Unknown
|
||||
writer.putInt(0);
|
||||
writer.put((byte)0);
|
||||
|
||||
writer.put((byte)0); //End datablock
|
||||
|
||||
}
|
||||
|
||||
|
||||
public boolean hasGold() {
|
||||
return this.hasGold;
|
||||
}
|
||||
|
||||
public void setHasGold(boolean value) {
|
||||
this.hasGold = value;
|
||||
}
|
||||
|
||||
public ArrayList<Item> getInventory() {
|
||||
synchronized(this.inventory) {
|
||||
return this.inventory;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete and remove all items in the inventory
|
||||
*/
|
||||
private void purgeInventory() {
|
||||
//make a copy so we're not inside synchronized{} while waiting for all items to be junked
|
||||
ArrayList<Item> inventoryCopy;
|
||||
synchronized(this.inventory) {
|
||||
inventoryCopy = new ArrayList<>(this.inventory);
|
||||
this.inventory.clear();
|
||||
}
|
||||
|
||||
for (Item item : inventoryCopy) {
|
||||
item.junk();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runAfterLoad() {}
|
||||
|
||||
public int getBelongsToType() {
|
||||
return this.belongsToType;
|
||||
}
|
||||
|
||||
public int getBelongsToID() {
|
||||
return this.belongsToID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
if (this.firstName.length() == 0) {
|
||||
return "Unknown corpse";
|
||||
}
|
||||
if (this.lastName.length() == 0) {
|
||||
return this.firstName;
|
||||
}
|
||||
return this.firstName + ' ' + this.lastName;
|
||||
}
|
||||
|
||||
public int getInBuilding() {
|
||||
return inBuilding;
|
||||
}
|
||||
|
||||
public void setInBuilding(int inBuilding) {
|
||||
this.inBuilding = inBuilding;
|
||||
}
|
||||
|
||||
public int getInFloorID() {
|
||||
return inFloorID;
|
||||
}
|
||||
|
||||
public void setInFloorID(int inFloorID) {
|
||||
this.inFloorID = inFloorID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,665 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.DamageType;
|
||||
import engine.Enum.EffectSourceType;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.job.AbstractJob;
|
||||
import engine.job.AbstractScheduleJob;
|
||||
import engine.job.JobContainer;
|
||||
import engine.jobs.AbstractEffectJob;
|
||||
import engine.jobs.DamageOverTimeJob;
|
||||
import engine.jobs.NoTimeJob;
|
||||
import engine.jobs.PersistentAoeJob;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.powers.ActionsBase;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.PowersBase;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
|
||||
public class Effect {
|
||||
|
||||
private JobContainer jc;
|
||||
|
||||
//Fail Conditions
|
||||
private boolean cancelOnAttack;
|
||||
private boolean cancelOnAttackSwing;
|
||||
private boolean cancelOnCast;
|
||||
private boolean cancelOnCastSpell;
|
||||
private boolean cancelOnEquipChange;
|
||||
private boolean cancelOnLogout;
|
||||
private boolean cancelOnMove;
|
||||
private boolean cancelOnNewCharm;
|
||||
private boolean cancelOnSit;
|
||||
private boolean cancelOnTakeDamage;
|
||||
private boolean cancelOnTerritoryClaim;
|
||||
private boolean cancelOnUnEquip;
|
||||
private boolean cancelOnStun;
|
||||
private boolean bakedInStat = false;
|
||||
private boolean isStatic = false;
|
||||
private int effectSourceType = 0;
|
||||
private int effectSourceID = 0;
|
||||
|
||||
|
||||
private EffectsBase eb;
|
||||
private int trains;
|
||||
private float damageAmount = 0f;
|
||||
|
||||
private AtomicBoolean cancel = new AtomicBoolean(false);
|
||||
|
||||
//private AbstractWorldObject owner;
|
||||
|
||||
/**
|
||||
* Generic Constructor
|
||||
*/
|
||||
public Effect(JobContainer jc, EffectsBase eb, int trains) {
|
||||
this.jc = jc;
|
||||
this.cancelOnAttack = false;
|
||||
this.cancelOnAttackSwing = false;
|
||||
this.cancelOnCast = false;
|
||||
this.cancelOnCastSpell = false;
|
||||
this.cancelOnEquipChange = false;
|
||||
this.cancelOnLogout = false;
|
||||
this.cancelOnMove = false;
|
||||
this.cancelOnNewCharm = false;
|
||||
this.cancelOnSit = false;
|
||||
this.cancelOnTakeDamage = false;
|
||||
this.cancelOnTerritoryClaim = false;
|
||||
this.cancelOnUnEquip = false;
|
||||
this.cancelOnStun = false;
|
||||
this.eb = eb;
|
||||
this.trains = trains;
|
||||
}
|
||||
|
||||
public Effect(JobContainer jc, EffectsBase eb, int trains,boolean isStatic) {
|
||||
this.jc = jc;
|
||||
this.cancelOnAttack = false;
|
||||
this.cancelOnAttackSwing = false;
|
||||
this.cancelOnCast = false;
|
||||
this.cancelOnCastSpell = false;
|
||||
this.cancelOnEquipChange = false;
|
||||
this.cancelOnLogout = false;
|
||||
this.cancelOnMove = false;
|
||||
this.cancelOnNewCharm = false;
|
||||
this.cancelOnSit = false;
|
||||
this.cancelOnTakeDamage = false;
|
||||
this.cancelOnTerritoryClaim = false;
|
||||
this.cancelOnUnEquip = false;
|
||||
this.cancelOnStun = false;
|
||||
this.eb = eb;
|
||||
this.trains = trains;
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
//called when effect ends. Send message to client to remove effect
|
||||
public void endEffect() {
|
||||
if (this.jc != null) {
|
||||
AbstractJob aj = jc.getJob();
|
||||
if (aj == null)
|
||||
return;
|
||||
if (aj instanceof AbstractEffectJob) {
|
||||
((AbstractEffectJob)aj).setSkipCancelEffect(false);
|
||||
((AbstractEffectJob)aj).endEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void endEffectNoPower() {
|
||||
if (this.jc != null) {
|
||||
AbstractJob aj = jc.getJob();
|
||||
if (aj == null)
|
||||
return;
|
||||
if (aj instanceof AbstractEffectJob) {
|
||||
((AbstractEffectJob)aj).setSkipCancelEffect(false);
|
||||
((AbstractEffectJob)aj).endEffectNoPower();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Called when effect ends before timer done
|
||||
public void cancelJob() {
|
||||
if (this.jc != null) {
|
||||
AbstractJob aj = jc.getJob();
|
||||
if (aj == null)
|
||||
return;
|
||||
if (aj instanceof AbstractEffectJob)
|
||||
((AbstractEffectJob)aj).setSkipCancelEffect(false);
|
||||
if (aj instanceof AbstractScheduleJob) {
|
||||
((AbstractScheduleJob)aj).cancelJob();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelJob(boolean skipEffect) {
|
||||
if (this.jc != null) {
|
||||
AbstractJob aj = jc.getJob();
|
||||
if (aj == null)
|
||||
return;
|
||||
if (skipEffect && aj instanceof AbstractEffectJob) {
|
||||
((AbstractEffectJob)aj).setSkipCancelEffect(skipEffect);
|
||||
}
|
||||
if (aj instanceof AbstractScheduleJob) {
|
||||
((AbstractScheduleJob)aj).cancelJob();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean applyBonus(Item item) {
|
||||
if (this.jc == null)
|
||||
return false;
|
||||
AbstractJob aj = jc.getJob();
|
||||
if (aj == null)
|
||||
return false;
|
||||
if (aj instanceof AbstractEffectJob) {
|
||||
AbstractEffectJob aej = (AbstractEffectJob)aj;
|
||||
EffectsBase eb = aej.getEffect();
|
||||
if (eb == null)
|
||||
return false;
|
||||
HashSet<AbstractEffectModifier> aems = eb.getModifiers();
|
||||
for(AbstractEffectModifier aem : aems)
|
||||
aem.applyBonus(item, aej.getTrains());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean applyBonus(Building building) {
|
||||
if (this.jc == null)
|
||||
return false;
|
||||
AbstractJob aj = jc.getJob();
|
||||
if (aj == null)
|
||||
return false;
|
||||
if (aj instanceof AbstractEffectJob) {
|
||||
AbstractEffectJob aej = (AbstractEffectJob)aj;
|
||||
EffectsBase eb = aej.getEffect();
|
||||
if (eb == null)
|
||||
return false;
|
||||
HashSet<AbstractEffectModifier> aems = eb.getModifiers();
|
||||
for(AbstractEffectModifier aem : aems)
|
||||
aem.applyBonus(building, aej.getTrains());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean applyBonus(AbstractCharacter ac) {
|
||||
if (this.jc == null)
|
||||
return false;
|
||||
AbstractJob aj = jc.getJob();
|
||||
if (aj == null)
|
||||
return false;
|
||||
if (aj instanceof AbstractEffectJob) {
|
||||
AbstractEffectJob aej = (AbstractEffectJob)aj;
|
||||
EffectsBase eb = aej.getEffect();
|
||||
if (eb == null)
|
||||
return false;
|
||||
HashSet<AbstractEffectModifier> aems = eb.getModifiers();
|
||||
for(AbstractEffectModifier aem : aems)
|
||||
aem.applyBonus(ac, aej.getTrains());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean applyBonus(Item item, AbstractCharacter ac) {
|
||||
if (this.jc == null)
|
||||
return false;
|
||||
AbstractJob aj = jc.getJob();
|
||||
if (aj == null)
|
||||
return false;
|
||||
if (aj instanceof AbstractEffectJob) {
|
||||
AbstractEffectJob aej = (AbstractEffectJob)aj;
|
||||
EffectsBase eb = aej.getEffect();
|
||||
if (eb == null)
|
||||
return false;
|
||||
HashSet<AbstractEffectModifier> aems = eb.getModifiers();
|
||||
for(AbstractEffectModifier aem : aems) {
|
||||
aem.applyBonus(item, aej.getTrains());
|
||||
aem.applyBonus(ac, aej.getTrains());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public HashSet<AbstractEffectModifier> getEffectModifiers() {
|
||||
if (this.jc == null)
|
||||
return null;
|
||||
AbstractJob aj = jc.getJob();
|
||||
if (aj == null)
|
||||
return null;
|
||||
if (aj instanceof AbstractEffectJob) {
|
||||
AbstractEffectJob aej = (AbstractEffectJob)aj;
|
||||
EffectsBase eb = aej.getEffect();
|
||||
if (eb == null)
|
||||
return null;
|
||||
return eb.getModifiers();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
//Send this effect to a client when loading a player
|
||||
public void sendEffect(ClientConnection cc) {
|
||||
if (this.jc == null || this.eb == null || cc == null)
|
||||
return;
|
||||
AbstractJob aj = this.jc.getJob();
|
||||
if (aj == null || (!(aj instanceof AbstractEffectJob)))
|
||||
return;
|
||||
this.eb.sendEffect((AbstractEffectJob)aj, (this.jc.timeToExecutionLeft() / 1000), cc);
|
||||
}
|
||||
|
||||
public void sendEffectNoPower(ClientConnection cc) {
|
||||
if (this.jc == null || this.eb == null || cc == null)
|
||||
return;
|
||||
AbstractJob aj = this.jc.getJob();
|
||||
if (aj == null || (!(aj instanceof AbstractEffectJob)))
|
||||
return;
|
||||
this.eb.sendEffectNoPower((AbstractEffectJob)aj, (this.jc.timeToExecutionLeft() / 1000), cc);
|
||||
}
|
||||
|
||||
public void sendSpireEffect(ClientConnection cc, boolean onEnter) {
|
||||
if (this.jc == null || this.eb == null || cc == null)
|
||||
return;
|
||||
AbstractJob aj = this.jc.getJob();
|
||||
if (aj == null || (!(aj instanceof AbstractEffectJob)))
|
||||
return;
|
||||
int duration = 45;
|
||||
if (onEnter)
|
||||
duration = -1;
|
||||
this.eb.sendEffectNoPower((AbstractEffectJob)aj, duration, cc);
|
||||
}
|
||||
|
||||
public void serializeForItem(ByteBufferWriter writer, Item item) {
|
||||
if (this.jc == null) {
|
||||
blankFill(writer);
|
||||
return;
|
||||
}
|
||||
AbstractJob aj = this.jc.getJob();
|
||||
if (aj == null || (!(aj instanceof AbstractEffectJob))) {
|
||||
blankFill(writer);
|
||||
return;
|
||||
}
|
||||
AbstractEffectJob aej = (AbstractEffectJob)aj;
|
||||
PowersBase pb = aej.getPower();
|
||||
ActionsBase ab = aej.getAction();
|
||||
if (this.eb == null) {
|
||||
blankFill(writer);
|
||||
return;
|
||||
} else if (pb == null && !(this.jc.noTimer())) {
|
||||
blankFill(writer);
|
||||
return;
|
||||
}
|
||||
if (this.jc.noTimer()) {
|
||||
if (pb == null)
|
||||
writer.putInt(this.eb.getToken());
|
||||
else
|
||||
writer.putInt(pb.getToken());
|
||||
writer.putInt(aej.getTrains());
|
||||
writer.putInt(1);
|
||||
writer.put((byte)1);
|
||||
writer.putInt(item.getObjectType().ordinal());
|
||||
writer.putInt(item.getObjectUUID());
|
||||
|
||||
writer.putString(item.getName());
|
||||
writer.putFloat(-1000f);
|
||||
} else {
|
||||
float duration = this.jc.timeToExecutionLeft() / 1000;
|
||||
writer.putInt(this.eb.getToken());
|
||||
writer.putInt(aej.getTrains());
|
||||
writer.putInt(0);
|
||||
writer.put((byte)0);
|
||||
writer.putInt(pb.getToken());
|
||||
writer.putString(pb.getName());
|
||||
writer.putFloat(duration);
|
||||
}
|
||||
}
|
||||
|
||||
public void serializeForClientMsg(ByteBufferWriter writer) {
|
||||
AbstractJob aj = this.jc.getJob();
|
||||
if (aj == null || (!(aj instanceof AbstractEffectJob))) {
|
||||
//TODO put error message here
|
||||
blankFill(writer);
|
||||
return;
|
||||
}
|
||||
AbstractEffectJob aej = (AbstractEffectJob)aj;
|
||||
PowersBase pb = aej.getPower();
|
||||
ActionsBase ab = aej.getAction();
|
||||
if (ab == null || pb == null || this.eb == null) {
|
||||
//TODO put error message here
|
||||
blankFill(writer);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( aej instanceof PersistentAoeJob){
|
||||
blankFill(writer);
|
||||
return;
|
||||
}
|
||||
|
||||
float duration = this.jc.timeToExecutionLeft() / 1000;
|
||||
if (aej instanceof DamageOverTimeJob)
|
||||
duration = ab.getDurationInSeconds(aej.getTrains()) - (((DamageOverTimeJob)aej).getIteration()*5);
|
||||
|
||||
|
||||
|
||||
writer.putInt(pb.getToken());
|
||||
writer.putInt(aej.getTrains());
|
||||
writer.putInt(0);
|
||||
writer.put((byte)0);
|
||||
writer.putInt(this.eb.getToken());
|
||||
writer.putString(pb.getName());
|
||||
writer.putFloat(duration);
|
||||
}
|
||||
|
||||
public boolean serializeForLoad(ByteBufferWriter writer) {
|
||||
AbstractJob aj = this.jc.getJob();
|
||||
if (aj == null || (!(aj instanceof AbstractEffectJob))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
AbstractEffectJob aej = (AbstractEffectJob)aj;
|
||||
PowersBase pb = aej.getPower();
|
||||
ActionsBase ab = aej.getAction();
|
||||
if (this.eb == null) {
|
||||
return false;
|
||||
}
|
||||
if ( aej instanceof PersistentAoeJob){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
float duration = this.jc.timeToExecutionLeft() / 1000;
|
||||
if (aej instanceof DamageOverTimeJob)
|
||||
if (ab != null)
|
||||
duration = ab.getDurationInSeconds(aej.getTrains()) - (((DamageOverTimeJob)aej).getIteration()*5);
|
||||
if (aej instanceof NoTimeJob)
|
||||
duration = -1;
|
||||
|
||||
int sendToken = this.getEffectToken();
|
||||
|
||||
if (aej.getAction() != null)
|
||||
if ( aej.getAction().getPowerAction() != null
|
||||
&& PowersManager.ActionTokenByIDString.containsKey(aej.getAction().getPowerAction().getIDString()))
|
||||
try{
|
||||
sendToken = PowersManager.ActionTokenByIDString.get(aej.getAction().getPowerAction().getIDString());
|
||||
}catch(Exception e){
|
||||
sendToken = this.getEffectToken();
|
||||
}
|
||||
|
||||
|
||||
writer.putInt(sendToken);
|
||||
writer.putInt(this.trains);
|
||||
writer.putInt(0); //?
|
||||
if (aej.getEffectSourceID() != 0){
|
||||
writer.put((byte) 1);
|
||||
writer.putInt(aej.getEffectSourceType());
|
||||
writer.putInt(aej.getEffectSourceID());
|
||||
}else{
|
||||
writer.put((byte)0);
|
||||
writer.putInt(pb != null ? pb.getToken() : 0);
|
||||
}
|
||||
writer.putString(pb != null ? pb.getName() : eb.getName());
|
||||
|
||||
writer.putFloat(duration);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void blankFill(ByteBufferWriter writer) {
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
writer.put((byte)0);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
}
|
||||
|
||||
public float getDuration() {
|
||||
float duration = 0f;
|
||||
if (this.jc != null)
|
||||
duration = this.jc.timeToExecutionLeft() / 1000;
|
||||
return duration;
|
||||
}
|
||||
|
||||
public boolean containsSource(EffectSourceType source) {
|
||||
if (this.eb != null)
|
||||
return this.eb.containsSource(source);
|
||||
return false;
|
||||
}
|
||||
|
||||
public JobContainer getJobContainer() {
|
||||
return this.jc;
|
||||
}
|
||||
|
||||
public int getTrains() {
|
||||
return this.trains;
|
||||
}
|
||||
|
||||
public void setTrains(int value) {
|
||||
this.trains = value;
|
||||
}
|
||||
|
||||
public float getDamageAmount() {
|
||||
return this.damageAmount;
|
||||
}
|
||||
|
||||
public AbstractJob getJob() {
|
||||
if (this.jc == null)
|
||||
return null;
|
||||
return jc.getJob();
|
||||
}
|
||||
|
||||
public boolean bakedInStat() {
|
||||
return this.bakedInStat;
|
||||
}
|
||||
|
||||
public void setBakedInStat(boolean value) {
|
||||
this.bakedInStat = value;
|
||||
}
|
||||
|
||||
public PowersBase getPower() {
|
||||
if (this.jc == null)
|
||||
return null;
|
||||
AbstractJob aj = jc.getJob();
|
||||
if (aj == null || (!(aj instanceof AbstractEffectJob)))
|
||||
return null;
|
||||
return ((AbstractEffectJob)aj).getPower();
|
||||
}
|
||||
|
||||
public int getPowerToken() {
|
||||
if (this.jc == null)
|
||||
return 0;
|
||||
AbstractJob aj = jc.getJob();
|
||||
if (aj == null || (!(aj instanceof AbstractEffectJob)))
|
||||
return 0;
|
||||
PowersBase pb = ((AbstractEffectJob)aj).getPower();
|
||||
if (pb == null)
|
||||
return 0;
|
||||
return pb.getToken();
|
||||
}
|
||||
|
||||
public int getEffectToken() {
|
||||
if (this.eb != null)
|
||||
return this.eb.getToken();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public EffectsBase getEffectsBase() {
|
||||
return this.eb;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
if (this.jc == null)
|
||||
return "";
|
||||
AbstractJob aj = this.jc.getJob();
|
||||
if (aj == null || !(aj instanceof AbstractEffectJob))
|
||||
return "";
|
||||
AbstractEffectJob aej = (AbstractEffectJob)aj;
|
||||
PowersBase pb = aej.getPower();
|
||||
if (pb == null)
|
||||
return "";
|
||||
return pb.getName();
|
||||
}
|
||||
|
||||
public boolean cancel() {
|
||||
return this.cancel.compareAndSet(false, true);
|
||||
}
|
||||
|
||||
public boolean canceled() {
|
||||
return this.cancel.get();
|
||||
}
|
||||
|
||||
public boolean cancelOnAttack() {
|
||||
if (this.eb == null)
|
||||
return true;
|
||||
return this.eb.cancelOnAttack();
|
||||
}
|
||||
|
||||
public boolean cancelOnAttackSwing() {
|
||||
if (this.eb == null)
|
||||
return true;
|
||||
return this.eb.cancelOnAttackSwing();
|
||||
}
|
||||
|
||||
public boolean cancelOnCast() {
|
||||
if (this.eb == null)
|
||||
return true;
|
||||
return this.eb.cancelOnCast();
|
||||
}
|
||||
|
||||
public boolean cancelOnCastSpell() {
|
||||
if (this.eb == null)
|
||||
return true;
|
||||
return this.eb.cancelOnCastSpell();
|
||||
}
|
||||
|
||||
public boolean cancelOnEquipChange() {
|
||||
if (this.eb == null)
|
||||
return true;
|
||||
return this.eb.cancelOnEquipChange();
|
||||
}
|
||||
|
||||
public boolean cancelOnLogout() {
|
||||
if (this.eb == null)
|
||||
return true;
|
||||
return this.eb.cancelOnLogout();
|
||||
}
|
||||
|
||||
public boolean cancelOnMove() {
|
||||
if (this.eb == null || this.cancelOnMove)
|
||||
return true;
|
||||
return this.eb.cancelOnMove();
|
||||
}
|
||||
|
||||
public boolean cancelOnNewCharm() {
|
||||
if (this.eb == null)
|
||||
return true;
|
||||
return this.eb.cancelOnNewCharm();
|
||||
}
|
||||
|
||||
public boolean cancelOnSit() {
|
||||
if (this.eb == null)
|
||||
return true;
|
||||
return this.eb.cancelOnSit();
|
||||
}
|
||||
|
||||
public boolean cancelOnStun() {
|
||||
if (this.eb == null)
|
||||
return true;
|
||||
return this.cancelOnStun;
|
||||
}
|
||||
|
||||
public boolean cancelOnTakeDamage() {
|
||||
if (this.eb == null)
|
||||
return true;
|
||||
if (this.eb.damageTypeSpecific()) {
|
||||
return false; //handled in call from resists
|
||||
} else {
|
||||
return this.eb.cancelOnTakeDamage();
|
||||
}
|
||||
}
|
||||
|
||||
//Used for verifying when damage absorbers fails
|
||||
public boolean cancelOnTakeDamage(DamageType type, float amount) {
|
||||
if (!this.eb.cancelOnTakeDamage())
|
||||
return false;
|
||||
if (this.eb == null || amount < 0f)
|
||||
return false;
|
||||
if (this.eb.damageTypeSpecific()) {
|
||||
if (type == null)
|
||||
return false;
|
||||
if (this.eb.containsDamageType(type)) {
|
||||
this.damageAmount += amount;
|
||||
return this.damageAmount > this.eb.getDamageAmount(this.trains);
|
||||
} else
|
||||
return false;
|
||||
} else
|
||||
return false; //handled by call from AbstractCharacter
|
||||
}
|
||||
|
||||
public boolean isDamageAbsorber() {
|
||||
if (this.eb == null)
|
||||
return false;
|
||||
if (!this.eb.cancelOnTakeDamage())
|
||||
return false;
|
||||
return this.eb.damageTypeSpecific();
|
||||
}
|
||||
|
||||
public boolean cancelOnTerritoryClaim() {
|
||||
if (this.eb == null)
|
||||
return true;
|
||||
return this.eb.cancelOnTerritoryClaim();
|
||||
}
|
||||
|
||||
public boolean cancelOnUnEquip() {
|
||||
if (this.eb == null)
|
||||
return true;
|
||||
return this.eb.cancelOnUnEquip();
|
||||
}
|
||||
|
||||
public void setPAOE() {
|
||||
this.cancelOnStun = true;
|
||||
this.cancelOnMove = true;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
|
||||
public void setIsStatic(boolean isStatic) {
|
||||
this.isStatic = isStatic;
|
||||
|
||||
}
|
||||
|
||||
public int getEffectSourceID() {
|
||||
return effectSourceID;
|
||||
}
|
||||
|
||||
public void setEffectSourceID(int effectSourceID) {
|
||||
this.effectSourceID = effectSourceID;
|
||||
}
|
||||
|
||||
public int getEffectSourceType() {
|
||||
return effectSourceType;
|
||||
}
|
||||
|
||||
public void setEffectSourceType(int effectSourceType) {
|
||||
this.effectSourceType = effectSourceType;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
public class EffectsResourceCosts extends AbstractGameObject {
|
||||
|
||||
private String IDString;
|
||||
private int resourceID;
|
||||
private int amount;
|
||||
private int UID;
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public EffectsResourceCosts() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public EffectsResourceCosts(ResultSet rs) throws SQLException {
|
||||
|
||||
this.UID = rs.getInt("UID");
|
||||
this.IDString = rs.getString("IDString");
|
||||
this.resourceID = rs.getInt("resource");
|
||||
this.amount = rs.getInt("amount");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getIDString() {
|
||||
return this.IDString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getResourceID() {
|
||||
return resourceID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFromCache() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public int getUID() {
|
||||
return UID;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
public class EnchantmentBase extends AbstractGameObject {
|
||||
|
||||
private final String name;
|
||||
private final String prefix;
|
||||
private final String suffix;
|
||||
|
||||
private final byte attributeID;
|
||||
private final int modValue;
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public EnchantmentBase(String name, String prefix, String suffix,
|
||||
byte attributeID, int modValue) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.prefix = prefix;
|
||||
this.suffix = suffix;
|
||||
this.attributeID = attributeID;
|
||||
this.modValue = modValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public EnchantmentBase(String name, String prefix, String suffix,
|
||||
byte attributeID, int modValue, int newUUID) {
|
||||
super(newUUID);
|
||||
this.name = name;
|
||||
this.prefix = prefix;
|
||||
this.suffix = suffix;
|
||||
this.attributeID = attributeID;
|
||||
this.modValue = modValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public EnchantmentBase(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
this.name = rs.getString("name");
|
||||
this.prefix = rs.getString("prefix");
|
||||
this.suffix = rs.getString("suffix");
|
||||
this.attributeID = rs.getByte("attributeID");
|
||||
this.modValue = rs.getInt("modValue");
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public String getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
public byte getAttributeID() {
|
||||
return attributeID;
|
||||
}
|
||||
|
||||
public int getModValue() {
|
||||
return modValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Create update logic.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class EquipmentSetEntry {
|
||||
|
||||
private float dropChance;
|
||||
private int itemID;
|
||||
|
||||
static HashMap<Integer, ArrayList<EquipmentSetEntry>> EquipmentSetMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public EquipmentSetEntry(ResultSet rs) throws SQLException {
|
||||
this.dropChance = (rs.getFloat("dropChance"));
|
||||
this.itemID = (rs.getInt("itemID"));
|
||||
}
|
||||
|
||||
public static void LoadAllEquipmentSets() {
|
||||
EquipmentSetMap = DbManager.ItemBaseQueries.LOAD_EQUIPMENT_FOR_NPC_AND_MOBS();
|
||||
}
|
||||
|
||||
float getDropChance() {
|
||||
return dropChance;
|
||||
}
|
||||
|
||||
public int getItemID() {
|
||||
return itemID;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,441 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.TargetColor;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class Experience {
|
||||
|
||||
private static final TreeMap<Integer, Integer> ExpToLevel;
|
||||
private static final int[] LevelToExp = { Integer.MIN_VALUE, // Pad
|
||||
// everything
|
||||
// over 1
|
||||
|
||||
// R0
|
||||
0, // Level 1
|
||||
150, // Level 2
|
||||
1200, // Level 3
|
||||
4050, // Level 4
|
||||
9600, // Level 5
|
||||
18750, // Level 6
|
||||
32400, // Level 7
|
||||
51450, // Level 8
|
||||
76800, // Level 9
|
||||
|
||||
// R1
|
||||
109350, // Level 10
|
||||
150000, // Level 11
|
||||
199650, // Level 12
|
||||
259200, // Level 13
|
||||
329550, // Level 14
|
||||
411600, // Level 15
|
||||
506250, // Level 16
|
||||
614400, // Level 17
|
||||
736950, // Level 18
|
||||
874800, // Level 19
|
||||
|
||||
// R2
|
||||
1028850, // Level 20
|
||||
1200000, // Level 21
|
||||
1389150, // Level 22
|
||||
1597200, // Level 23
|
||||
1825050, // Level 24
|
||||
2073600, // Level 25
|
||||
2343750, // Level 26
|
||||
2636400, // Level 27
|
||||
2952450, // Level 28
|
||||
3292800, // Level 29
|
||||
|
||||
// R3
|
||||
3658350, // Level 30
|
||||
4050000, // Level 31
|
||||
4468650, // Level 32
|
||||
4915200, // Level 33
|
||||
5390550, // Level 34
|
||||
5895600, // Level 35
|
||||
6431250, // Level 36
|
||||
6998400, // Level 37
|
||||
7597950, // Level 38
|
||||
8230800, // Level 39
|
||||
|
||||
// R4
|
||||
8897850, // Level 40
|
||||
10091520, // Level 41
|
||||
11396777, // Level 42
|
||||
12820187, // Level 43
|
||||
14368505, // Level 44
|
||||
16048666, // Level 45
|
||||
17867790, // Level 46
|
||||
19833183, // Level 47
|
||||
21952335, // Level 48
|
||||
24232919, // Level 49
|
||||
|
||||
// R5
|
||||
26682793, // Level 50
|
||||
29310000, // Level 51
|
||||
32122766, // Level 52
|
||||
35129502, // Level 53
|
||||
38338805, // Level 54
|
||||
41759452, // Level 55
|
||||
45400409, // Level 56
|
||||
49270824, // Level 57
|
||||
53380030, // Level 58
|
||||
57737542, // Level 59
|
||||
|
||||
// R6
|
||||
62353064, // Level 60
|
||||
67236479, // Level 61
|
||||
72397859, // Level 62
|
||||
77847457, // Level 63
|
||||
83595712, // Level 64
|
||||
89653247, // Level 65
|
||||
96030869, // Level 66
|
||||
102739569, // Level 67
|
||||
109790524, // Level 68
|
||||
117195093, // Level 69
|
||||
|
||||
// R7
|
||||
124964822, // Level 70
|
||||
133111438, // Level 71
|
||||
141646855, // Level 72
|
||||
150583171, // Level 73
|
||||
159932666, // Level 74
|
||||
169707808, // Level 75
|
||||
179921247, // Level 76
|
||||
|
||||
};
|
||||
|
||||
private static final float[] MaxExpPerLevel = { Float.MIN_VALUE, // Pad
|
||||
// everything
|
||||
// over
|
||||
// 1
|
||||
|
||||
// R0
|
||||
15, // Level 1
|
||||
105, // Level 2
|
||||
285, // Level 3
|
||||
555, // Level 4
|
||||
610, // Level 5
|
||||
682.5f, // Level 6
|
||||
730, // Level 7
|
||||
975, // Level 8
|
||||
1251.92f, // Level 9
|
||||
|
||||
// R1
|
||||
1563.46f, // Level 10
|
||||
1909.62f, // Level 11
|
||||
2290.38f, // Level 12
|
||||
2705.77f, // Level 13
|
||||
3155.77f, // Level 14
|
||||
3640.38f, // Level 15
|
||||
4159.62f, // Level 16
|
||||
4713.46f, // Level 17
|
||||
5301.92f, // Level 18
|
||||
5925, // Level 19
|
||||
|
||||
// R2
|
||||
6582.69f, // Level 20
|
||||
7275, // Level 21
|
||||
8001.92f, // Level 22
|
||||
8763.46f, // Level 23
|
||||
9559.62f, // Level 24
|
||||
10390.38f, // Level 25
|
||||
11255.77f, // Level 26
|
||||
12155.77f, // Level 27
|
||||
13090.38f, // Level 28
|
||||
14059.62f, // Level 29
|
||||
|
||||
// R3
|
||||
15063.46f, // Level 30
|
||||
16101.92f, // Level 31
|
||||
17175, // Level 32
|
||||
18282.69f, // Level 33
|
||||
19425, // Level 34
|
||||
20601.92f, // Level 35
|
||||
21813.46f, // Level 36
|
||||
23059.62f, // Level 37
|
||||
24340.38f, // Level 38
|
||||
25655.77f, // Level 39
|
||||
|
||||
// R4
|
||||
45910.38f, // Level 40
|
||||
34348.87f, // Level 41
|
||||
37458.16f, // Level 42
|
||||
40745.21f, // Level 43
|
||||
44214.76f, // Level 44
|
||||
47871.68f, // Level 45
|
||||
51720.87f, // Level 46
|
||||
55767.16f, // Level 47
|
||||
60015.37f, // Level 48
|
||||
64470.37f, // Level 49
|
||||
|
||||
// R5
|
||||
69137.03f, // Level 50
|
||||
74020.16f, // Level 51
|
||||
79124.63f, // Level 52
|
||||
84455.34f, // Level 53
|
||||
90017.03f, // Level 54
|
||||
95814.66f, // Level 55
|
||||
101853.03f, // Level 56
|
||||
108137, // Level 57
|
||||
114671.37f, // Level 58
|
||||
121461.11f, // Level 59
|
||||
|
||||
// R6
|
||||
128510.92f, // Level 60
|
||||
135825.79f, // Level 61
|
||||
143410.47f, // Level 62
|
||||
151269.87f, // Level 63
|
||||
159408.82f, // Level 64
|
||||
167832.16f, // Level 65
|
||||
176544.74f, // Level 66
|
||||
185551.45f, // Level 67
|
||||
194857.08f, // Level 68
|
||||
204466.55f, // Level 69
|
||||
|
||||
// R7
|
||||
214384.63f, // Level 70
|
||||
224616.24f, // Level 71
|
||||
235166.21f, // Level 72
|
||||
246039.34f, // Level 73
|
||||
257240.58f, // Level 74
|
||||
1 // 268774.71 //Level 75
|
||||
|
||||
};
|
||||
|
||||
static {
|
||||
ExpToLevel = new TreeMap<>();
|
||||
|
||||
// flip keys and values for other Map
|
||||
for (int i = 1; i < LevelToExp.length; i++) {
|
||||
ExpToLevel.put(LevelToExp[i], i);
|
||||
}
|
||||
} // end Static block
|
||||
|
||||
// Used to calcuate the amount of experience a monster grants in the
|
||||
// following formula
|
||||
// expGranted = a(moblevel)^2 + b(moblevel) + c
|
||||
private static final float EXPQUADA = 10.0f;
|
||||
private static final float EXPQUADB = 6.0f;
|
||||
private static final float EXPQUADC = -10.0f;
|
||||
|
||||
// Adds addtional exp per addtional member of a group using the following
|
||||
// (expGranted / group.size()) * (groupBonus * (group.size()-1) +1)
|
||||
private static final float GROUP_BONUS = 0.5f; // 0.2 grants (20%) addtional
|
||||
// exp per group member
|
||||
|
||||
// called to determine current level based on xp
|
||||
public static int getLevel(int experience) {
|
||||
int expKey = ExpToLevel.floorKey(experience);
|
||||
int level = ExpToLevel.get(expKey);
|
||||
if (level > MBServerStatics.LEVELCAP) {
|
||||
level = MBServerStatics.LEVELCAP;
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
// Get the base xp for a level
|
||||
public static int getBaseExperience(int level) {
|
||||
if (level < LevelToExp.length) {
|
||||
return LevelToExp[level];
|
||||
}
|
||||
|
||||
int fLevel = level - 1;
|
||||
int baseXP = fLevel * fLevel * fLevel;
|
||||
return (int) ((fLevel < 40) ? (baseXP * 150)
|
||||
: (baseXP * (150 + (7.6799998 * (level - 40)))));
|
||||
}
|
||||
|
||||
// Get XP needed for the next level
|
||||
public static int getExpForNextLevel(int experience, int currentLevel) {
|
||||
return (getBaseExperience(currentLevel + 1) - experience);
|
||||
}
|
||||
|
||||
// Max XP granted for killing a blue, yellow or orange mob
|
||||
public static float maxXPPerKill(int level) {
|
||||
if (level < 1)
|
||||
level = 1;
|
||||
if (level > 75)
|
||||
level = 75;
|
||||
return MaxExpPerLevel[level];
|
||||
// return (LevelToExp[level + 1] - LevelToExp[level])/(11 + level/2);
|
||||
// return ((((level * level)-level)*50)+16);
|
||||
}
|
||||
|
||||
// Returns a penalty modifier depending on mob color
|
||||
public static double getConMod(AbstractCharacter pc, AbstractCharacter mob) {
|
||||
switch (TargetColor.getCon(pc, mob)) {
|
||||
case Red:
|
||||
return 1.25;
|
||||
case Orange:
|
||||
return 1.15;
|
||||
case Yellow:
|
||||
return 1.05;
|
||||
case Blue:
|
||||
return 1;
|
||||
case Cyan:
|
||||
return 0.8;
|
||||
case Green:
|
||||
return 0.5;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static double getGroupMemberPenalty(double leadership,
|
||||
PlayerCharacter currPlayer, ArrayList<PlayerCharacter> players,
|
||||
int highestLevel) {
|
||||
|
||||
double penalty = 0.0;
|
||||
int adjustedGroupSize = 0;
|
||||
int totalLevels = 0;
|
||||
int level = currPlayer.getLevel();
|
||||
|
||||
// Group Size Penalty
|
||||
if (players.size() > 2)
|
||||
penalty = (players.size() - 2) * 1.5;
|
||||
|
||||
// Calculate Penalty For Highest level -> Current Player difference, !=
|
||||
// check to prevent divide by zero error
|
||||
if (highestLevel != level)
|
||||
penalty += ((highestLevel - level) * .5);
|
||||
|
||||
// double avgLevels = totalLevels / adjustedGroupSize;
|
||||
// if (adjustedGroupSize >= 1)
|
||||
// if (level < avgLevels)
|
||||
// penalty += ((avgLevels - level) * .5);
|
||||
|
||||
// Extra noob penalty
|
||||
if ((highestLevel - level) > 25)
|
||||
penalty += (highestLevel - level - 25);
|
||||
|
||||
return penalty;
|
||||
}
|
||||
|
||||
public static void doExperience(PlayerCharacter killer, AbstractCharacter mob, Group g) {
|
||||
// Check for some failure conditions
|
||||
if (killer == null || mob == null)
|
||||
return;
|
||||
|
||||
double xp = 0.0;
|
||||
|
||||
//Get the xp modifier for the world
|
||||
float xpMod = MBServerStatics.EXP_RATE_MOD;
|
||||
|
||||
|
||||
|
||||
if (g != null) { // Do group EXP stuff
|
||||
|
||||
int leadership = 0;
|
||||
int highestLevel = 0;
|
||||
double penalty = 0.0;
|
||||
|
||||
ArrayList<PlayerCharacter> giveEXPTo = new ArrayList<>();
|
||||
|
||||
// Check if leader is within range of kill and then get leadership
|
||||
// skill
|
||||
Vector3fImmutable killLoc = mob.getLoc();
|
||||
if (killLoc.distanceSquared2D(g.getGroupLead().getLoc()) < (MBServerStatics.EXP_RANGE * MBServerStatics.EXP_RANGE)) {
|
||||
CharacterSkill leaderskill = g.getGroupLead().skills
|
||||
.get("Leadership");
|
||||
if (leaderskill != null)
|
||||
leadership = leaderskill.getNumTrains();
|
||||
if (leadership > 90)
|
||||
leadership = 90; // leadership caps at 90%
|
||||
}
|
||||
|
||||
// Check every group member for distance to see if they get xp
|
||||
for (PlayerCharacter pc : g.getMembers()) {
|
||||
if (pc.isAlive()) { // Skip if the player is dead.
|
||||
|
||||
// Check within range
|
||||
if (killLoc.distanceSquared2D(pc.getLoc()) < (MBServerStatics.EXP_RANGE * MBServerStatics.EXP_RANGE)) {
|
||||
giveEXPTo.add(pc);
|
||||
// Track highest level character
|
||||
if (pc.getLevel() > highestLevel)
|
||||
highestLevel = pc.getLevel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process every player in the group getting XP
|
||||
for (PlayerCharacter pc : giveEXPTo) {
|
||||
if (pc.getLevel() >= MBServerStatics.LEVELCAP)
|
||||
continue;
|
||||
|
||||
// Sets Max XP with server exp mod taken into account.
|
||||
xp = (double) xpMod * maxXPPerKill(pc.getLevel());
|
||||
|
||||
// Adjust XP for Mob Level
|
||||
xp *= getConMod(pc, mob);
|
||||
|
||||
// Process XP for this member
|
||||
penalty = getGroupMemberPenalty(leadership, pc, giveEXPTo,
|
||||
highestLevel);
|
||||
|
||||
// Leadership Penalty Reduction
|
||||
if (leadership > 0)
|
||||
penalty -= ((leadership) * 0.01) * penalty;
|
||||
|
||||
// Modify for hotzone
|
||||
if (xp != 0)
|
||||
if (ZoneManager.inHotZone(mob.getLoc()))
|
||||
xp *= MBServerStatics.HOT_EXP_RATE_MOD;
|
||||
|
||||
// Check for 0 XP due to white mob, otherwise subtract penalty
|
||||
// xp
|
||||
if (xp == 0) {
|
||||
xp = 1;
|
||||
} else {
|
||||
xp -= (penalty * 0.01) * xp;
|
||||
|
||||
// Errant Penalty Calculation
|
||||
if (pc.getGuild().isErrant())
|
||||
xp *= 0.6;
|
||||
}
|
||||
|
||||
if (xp == 0)
|
||||
xp = 1;
|
||||
|
||||
// Grant the player the EXP
|
||||
pc.grantXP((int) Math.floor(xp));
|
||||
}
|
||||
|
||||
} else { // Give EXP to a single character
|
||||
if (!killer.isAlive()) // Skip if the player is dead.
|
||||
return;
|
||||
|
||||
if (killer.getLevel() >= MBServerStatics.LEVELCAP)
|
||||
return;
|
||||
|
||||
// Get XP and adjust for Mob Level with world xp modifier taken into account
|
||||
xp = (double) xpMod * maxXPPerKill(killer.getLevel());
|
||||
xp *= getConMod(killer, mob);
|
||||
|
||||
// Modify for hotzone
|
||||
if (ZoneManager.inHotZone(mob.getLoc()))
|
||||
xp *= MBServerStatics.HOT_EXP_RATE_MOD;
|
||||
|
||||
// Errant penalty
|
||||
if (xp != 1)
|
||||
if (killer.getGuild().isErrant())
|
||||
xp *= .6;
|
||||
|
||||
// Grant XP
|
||||
killer.grantXP((int) Math.floor(xp));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.math.Vector3f;
|
||||
|
||||
public class Formation {
|
||||
|
||||
// Offsets are as follows.
|
||||
// X determines left/right offset
|
||||
// Y not used
|
||||
// Z determines front/back offset
|
||||
|
||||
private static final Vector3f[] COLUMN = { new Vector3f(0, 0, 0), // Group
|
||||
// Lead
|
||||
new Vector3f(6, 0, 0), // Player 1 offset
|
||||
new Vector3f(0, 0, -6), // Player 2 offset
|
||||
new Vector3f(6, 0, -6), // Player 3 offset
|
||||
new Vector3f(0, 0, -12), // Player 4 offset
|
||||
new Vector3f(6, 0, -12), // Player 5 offset
|
||||
new Vector3f(0, 0, -18), // Player 6 offset
|
||||
new Vector3f(6, 0, -18), // Player 7 offset
|
||||
new Vector3f(0, 0, -24), // Player 8 offset
|
||||
new Vector3f(6, 0, -24) }; // Player 9 offset
|
||||
|
||||
private static final Vector3f[] LINE = { new Vector3f(0, 0, 0),
|
||||
new Vector3f(0, 0, -6), new Vector3f(0, 0, -12),
|
||||
new Vector3f(0, 0, -18), new Vector3f(0, 0, -24),
|
||||
new Vector3f(0, 0, -30), new Vector3f(0, 0, -36),
|
||||
new Vector3f(0, 0, -42), new Vector3f(0, 0, -48),
|
||||
new Vector3f(0, 0, -54) };
|
||||
|
||||
private static final Vector3f[] BOX = { new Vector3f(0, 0, 0),
|
||||
new Vector3f(-6, 0, 0), new Vector3f(6, 0, 0),
|
||||
new Vector3f(-6, 0, -6), new Vector3f(0, 0, -6),
|
||||
new Vector3f(6, 0, -6), new Vector3f(-6, 0, -12),
|
||||
new Vector3f(0, 0, -12), new Vector3f(5, 0, -12),
|
||||
new Vector3f(0, 0, -18) };
|
||||
|
||||
private static final Vector3f[] TRIANGLE = { new Vector3f(0, 0, 0),
|
||||
new Vector3f(-6, 0, -6), new Vector3f(6, 0, -6),
|
||||
new Vector3f(-12, 0, -12), new Vector3f(0, 0, -12),
|
||||
new Vector3f(12, 0, -12), new Vector3f(-18, 0, -18),
|
||||
new Vector3f(-6, 0, -18), new Vector3f(6, 0, -18),
|
||||
new Vector3f(18, 0, -18) };
|
||||
|
||||
private static final Vector3f[] CIRCLE = { new Vector3f(0, 0, 0),
|
||||
new Vector3f(-12, 0, -3), new Vector3f(12, 0, -3),
|
||||
new Vector3f(-18, 0, -12), new Vector3f(18, 0, -12),
|
||||
new Vector3f(-18, 0, -21), new Vector3f(18, 0, -21),
|
||||
new Vector3f(-12, 0, -30), new Vector3f(12, 0, -30),
|
||||
new Vector3f(0, 0, -33) };
|
||||
|
||||
private static final Vector3f[] RANKS = { new Vector3f(0, 0, 0),
|
||||
new Vector3f(0, 0, -6), new Vector3f(-6, 0, 0),
|
||||
new Vector3f(-6, 0, -6), new Vector3f(6, 0, 0),
|
||||
new Vector3f(6, 0, -6), new Vector3f(-12, 0, 0),
|
||||
new Vector3f(-12, 0, -6), new Vector3f(12, 0, 0),
|
||||
new Vector3f(12, 0, -6) };
|
||||
|
||||
private static final Vector3f[] WEDGE = { new Vector3f(0, 0, 0),
|
||||
new Vector3f(6, 0, 0), new Vector3f(-6, 0, -6),
|
||||
new Vector3f(12, 0, -6), new Vector3f(-12, 0, -12),
|
||||
new Vector3f(18, 0, -12), new Vector3f(-18, 0, -18),
|
||||
new Vector3f(24, 0, -18), new Vector3f(-24, 0, -24),
|
||||
new Vector3f(30, 0, -24) };
|
||||
|
||||
private static final Vector3f[] INVERSEWEDGE = { new Vector3f(0, 0, 0),
|
||||
new Vector3f(6, 0, 0), new Vector3f(-6, 0, 6),
|
||||
new Vector3f(12, 0, 6), new Vector3f(-12, 0, 12),
|
||||
new Vector3f(18, 0, 12), new Vector3f(-18, 0, 18),
|
||||
new Vector3f(24, 0, 18), new Vector3f(-24, 0, 24),
|
||||
new Vector3f(30, 0, 24) };
|
||||
|
||||
private static final Vector3f[] T = { new Vector3f(0, 0, 0),
|
||||
new Vector3f(-6, 0, 0), new Vector3f(6, 0, 0),
|
||||
new Vector3f(0, 0, -6), new Vector3f(-12, 0, 0),
|
||||
new Vector3f(12, 0, 0), new Vector3f(0, 0, -12),
|
||||
new Vector3f(-18, 0, 0), new Vector3f(18, 0, 0),
|
||||
new Vector3f(0, 0, -18) };
|
||||
|
||||
public static Vector3f getOffset(int formation, int position) {
|
||||
if (position > 9 || position < 0) {
|
||||
// TODO log error here
|
||||
position = 0;
|
||||
}
|
||||
|
||||
switch (formation) {
|
||||
case 0:
|
||||
return Formation.COLUMN[position];
|
||||
case 1:
|
||||
return Formation.LINE[position];
|
||||
case 2:
|
||||
return Formation.BOX[position];
|
||||
case 3:
|
||||
return Formation.TRIANGLE[position];
|
||||
case 4:
|
||||
return Formation.CIRCLE[position];
|
||||
case 5:
|
||||
return Formation.RANKS[position];
|
||||
case 6:
|
||||
return Formation.WEDGE[position];
|
||||
case 7:
|
||||
return Formation.INVERSEWEDGE[position];
|
||||
case 9:
|
||||
return Formation.T[position];
|
||||
default: // default to box
|
||||
return Formation.BOX[position];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.GroupManager;
|
||||
import engine.job.JobScheduler;
|
||||
import engine.jobs.UpdateGroupJob;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.group.GroupUpdateMsg;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class Group extends AbstractWorldObject {
|
||||
|
||||
private PlayerCharacter groupLead;
|
||||
public final Set<PlayerCharacter> members;
|
||||
|
||||
private boolean splitGold = true;
|
||||
private int formation = 2;
|
||||
|
||||
private UpdateGroupJob updateGroupJob = null;
|
||||
|
||||
/**
|
||||
* No Id Constructor
|
||||
*/
|
||||
public Group( PlayerCharacter pc) {
|
||||
super();
|
||||
this.groupLead = pc;
|
||||
this.members = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public Group( PlayerCharacter pc, int newUUID) {
|
||||
super(newUUID);
|
||||
this.groupLead = pc;
|
||||
this.members = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public PlayerCharacter getGroupLead() {
|
||||
return this.groupLead;
|
||||
}
|
||||
|
||||
public Set<PlayerCharacter> getMembers() {
|
||||
return this.members;
|
||||
}
|
||||
|
||||
public boolean getSplitGold() {
|
||||
return this.splitGold;
|
||||
}
|
||||
|
||||
public int getFormation() {
|
||||
return this.formation;
|
||||
}
|
||||
|
||||
public String getFormationName() {
|
||||
return MBServerStatics.FORMATION_NAMES[this.formation];
|
||||
}
|
||||
|
||||
/*
|
||||
* Setters
|
||||
*/
|
||||
public void setFormation(int value) {
|
||||
if (value < 0 || value > 8)
|
||||
value = 2; // Default Box
|
||||
this.formation = value;
|
||||
}
|
||||
|
||||
public boolean setGroupLead(int ID) {
|
||||
for (PlayerCharacter pc : this.members) {
|
||||
if (pc.getObjectUUID() == ID) {
|
||||
this.groupLead = pc;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setSplitGold(boolean value) {
|
||||
this.splitGold = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utils
|
||||
*/
|
||||
public boolean isGroupLead(int ID) {
|
||||
return (this.groupLead.getObjectUUID() == ID);
|
||||
}
|
||||
|
||||
public boolean isGroupLead(PlayerCharacter pc) {
|
||||
if (pc == null || this.groupLead == null)
|
||||
return false;
|
||||
return (this.groupLead.getObjectUUID() == pc.getObjectUUID());
|
||||
}
|
||||
|
||||
public boolean toggleSplitGold() {
|
||||
this.splitGold = this.splitGold == false;
|
||||
return this.splitGold;
|
||||
}
|
||||
|
||||
public void sendUpdate(GroupUpdateMsg msg) {
|
||||
|
||||
for (PlayerCharacter pc : this.members) {
|
||||
Dispatch dispatch = Dispatch.borrow(pc, msg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, engine.Enum.DispatchChannel.SECONDARY);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addGroupMember(PlayerCharacter pc) {
|
||||
|
||||
if (this.members.size() > 9) // group full
|
||||
return false;
|
||||
|
||||
if (this.members.contains(pc)) // Can't add player twice
|
||||
return false;
|
||||
|
||||
this.members.add(pc);
|
||||
return true;
|
||||
}
|
||||
|
||||
public int removeGroupMember(PlayerCharacter pc) {
|
||||
|
||||
this.members.remove(pc); // remove player
|
||||
return this.members.size();
|
||||
}
|
||||
|
||||
public void clearMembers() {
|
||||
this.members.clear();
|
||||
}
|
||||
|
||||
public static boolean sameGroup(PlayerCharacter a, PlayerCharacter b) {
|
||||
|
||||
if (a == null || b == null)
|
||||
return false;
|
||||
|
||||
Group aG = GroupManager.getGroup(a);
|
||||
Group bG = GroupManager.getGroup(b);
|
||||
|
||||
if (aG == null || bG == null)
|
||||
return false;
|
||||
|
||||
return aG.getObjectUUID() == bG.getObjectUUID();
|
||||
|
||||
}
|
||||
|
||||
public void addUpdateGroupJob() {
|
||||
this.updateGroupJob = new UpdateGroupJob(this);
|
||||
JobScheduler.getInstance().scheduleJob(this.updateGroupJob, MBServerStatics.UPDATE_GROUP_RATE);
|
||||
}
|
||||
|
||||
public void removeUpdateGroupJob() {
|
||||
this.updateGroupJob.cancelJob();
|
||||
this.updateGroupJob = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Database
|
||||
*/
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Create update logic.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runAfterLoad() {}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,102 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.AllianceType;
|
||||
import engine.gameManager.DbManager;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class GuildAlliances {
|
||||
|
||||
private int sourceGuild;
|
||||
private int allianceGuild;
|
||||
private boolean isRecommended;
|
||||
private boolean isAlly;
|
||||
private String recommender;
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public GuildAlliances(ResultSet rs) throws SQLException {
|
||||
this.sourceGuild = rs.getInt("GuildID");
|
||||
this.allianceGuild = rs.getInt("OtherGuildID");
|
||||
this.isRecommended = rs.getBoolean("isRecommended");
|
||||
this.isAlly = rs.getBoolean("isAlliance");
|
||||
this.recommender =rs.getString("recommender");
|
||||
}
|
||||
|
||||
public GuildAlliances(int sourceGuild, int allianceGuild, boolean isRecommended, boolean isAlly,
|
||||
String recommender) {
|
||||
super();
|
||||
this.sourceGuild = sourceGuild;
|
||||
this.allianceGuild = allianceGuild;
|
||||
this.isRecommended = isRecommended;
|
||||
this.isAlly = isAlly;
|
||||
this.recommender = recommender;
|
||||
}
|
||||
|
||||
public int getSourceGuild() {
|
||||
return sourceGuild;
|
||||
}
|
||||
|
||||
public int getAllianceGuild() {
|
||||
return allianceGuild;
|
||||
}
|
||||
|
||||
public boolean isRecommended() {
|
||||
return isRecommended;
|
||||
}
|
||||
|
||||
public boolean isAlly() {
|
||||
return isAlly;
|
||||
}
|
||||
|
||||
public String getRecommender() {
|
||||
return recommender;
|
||||
}
|
||||
|
||||
public synchronized boolean UpdateAlliance(final AllianceType allianceType, boolean updateRecommended){
|
||||
switch (allianceType){
|
||||
case Ally:
|
||||
if (updateRecommended){
|
||||
if (!DbManager.GuildQueries.UPDATE_ALLIANCE_AND_RECOMMENDED(this.sourceGuild, this.allianceGuild, true))
|
||||
return false;
|
||||
this.isAlly = true;
|
||||
this.isRecommended = false;
|
||||
}else{
|
||||
if (!DbManager.GuildQueries.UPDATE_ALLIANCE(this.sourceGuild, this.allianceGuild, true))
|
||||
return false;
|
||||
this.isAlly = true;
|
||||
this.isRecommended = false;
|
||||
}
|
||||
break;
|
||||
case Enemy:
|
||||
|
||||
if (updateRecommended){
|
||||
if (!DbManager.GuildQueries.UPDATE_ALLIANCE_AND_RECOMMENDED(this.sourceGuild, this.allianceGuild, false))
|
||||
return false;
|
||||
this.isAlly = false;
|
||||
this.isRecommended = false;
|
||||
}else{
|
||||
if (!DbManager.GuildQueries.UPDATE_ALLIANCE(this.sourceGuild, this.allianceGuild, false))
|
||||
return false;
|
||||
this.isAlly = false;
|
||||
this.isRecommended = false;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
|
||||
|
||||
public class GuildCondemn {
|
||||
|
||||
private int ID;
|
||||
private int playerUID;
|
||||
private int parentGuildUID;
|
||||
private int guildUID;
|
||||
private int friendType;
|
||||
public static HashMap<Integer,ArrayList<GuildCondemn>> GetCondemnedFromGuildID = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public GuildCondemn(ResultSet rs) throws SQLException {
|
||||
this.playerUID = rs.getInt("playerUID");
|
||||
this.parentGuildUID = rs.getInt("buildingUID");
|
||||
this.guildUID = rs.getInt("guildUID");
|
||||
this.friendType = rs.getInt("friendType");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public GuildCondemn(int playerUID, int parentGuildUID, int guildUID, int friendType) {
|
||||
super();
|
||||
this.playerUID = playerUID;
|
||||
this.parentGuildUID = parentGuildUID;
|
||||
this.guildUID = guildUID;
|
||||
this.friendType = friendType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public int getPlayerUID() {
|
||||
return playerUID;
|
||||
}
|
||||
|
||||
|
||||
public int getParentGuildUID() {
|
||||
return parentGuildUID;
|
||||
}
|
||||
|
||||
|
||||
public int getGuildUID() {
|
||||
return guildUID;
|
||||
}
|
||||
|
||||
|
||||
public int getFriendType() {
|
||||
return friendType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
|
||||
import engine.Enum.GameObjectType;
|
||||
import engine.Enum.GuildHistoryType;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
public class GuildHistory {
|
||||
|
||||
|
||||
private int guildID;
|
||||
private String guildName;
|
||||
private DateTime time;
|
||||
private GuildHistoryType historyType;
|
||||
|
||||
|
||||
|
||||
|
||||
public GuildHistory( int guildID, String guildName,
|
||||
DateTime dateTime, GuildHistoryType historyType ) {
|
||||
super();
|
||||
this.guildID = guildID;
|
||||
this.guildName = guildName;
|
||||
this.time = dateTime;
|
||||
this.historyType = historyType;
|
||||
|
||||
}
|
||||
|
||||
public GuildHistoryType getHistoryType() {
|
||||
return historyType;
|
||||
}
|
||||
|
||||
public GuildHistory(ResultSet rs) throws SQLException {
|
||||
java.util.Date sqlDateTime;
|
||||
this.guildID = rs.getInt("guildID");
|
||||
Guild guild = Guild.getGuild(this.guildID);
|
||||
if (guild != null)
|
||||
this.guildName = guild.getName();
|
||||
else
|
||||
this.guildName = "Guild Not Found";
|
||||
|
||||
sqlDateTime = rs.getTimestamp("historyDate");
|
||||
if (sqlDateTime != null)
|
||||
this.time = new DateTime(sqlDateTime);
|
||||
else
|
||||
this.time = DateTime.now().minusYears(1);
|
||||
this.historyType = GuildHistoryType.valueOf(rs.getString("historyType"));
|
||||
}
|
||||
|
||||
|
||||
public long getGuildID() {
|
||||
return guildID;
|
||||
}
|
||||
|
||||
public String getGuildName() {
|
||||
return guildName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void _serialize(ByteBufferWriter writer) {
|
||||
writer.putInt(this.historyType.getType());
|
||||
writer.putInt(GameObjectType.Guild.ordinal());
|
||||
writer.putInt(this.guildID);
|
||||
writer.putString(guildName);
|
||||
writer.putInt(0); //Pad
|
||||
writer.putDateTime(this.time);
|
||||
}
|
||||
|
||||
public DateTime getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(DateTime time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class GuildStatusController {
|
||||
|
||||
/*
|
||||
* Status is stored in a single integer contained within the Character Table
|
||||
*
|
||||
* This class is responsible for maintaining and interpreting that value.
|
||||
*
|
||||
* Byte 1 - All : Title [0x000000FF]
|
||||
* Byte 2 - Low : isFullMember [0x00000F00]
|
||||
* Byte 2 - High : isTaxCollector [0x0000F000]
|
||||
* Byte 3 - Low : isRecruiter [0x000F0000]
|
||||
* Byte 3 - High : isInnerCouncil [0x00F00000]
|
||||
* Byte 4 - Low : isGuildLeader [0x0F000000]
|
||||
* Byte 4 - High : Empty [0xF0000000]
|
||||
*/
|
||||
|
||||
//Getters
|
||||
public static boolean isGuildLeader(AtomicInteger status) {
|
||||
return ((status.get() & GUILDLEADER) > 0);
|
||||
}
|
||||
|
||||
public static boolean isInnerCouncil(AtomicInteger status) {
|
||||
return ((status.get() & INNERCOUNCIL) > 0);
|
||||
}
|
||||
|
||||
public static boolean isRecruiter(AtomicInteger status) {
|
||||
return ((status.get() & RECRUITER) > 0);
|
||||
}
|
||||
|
||||
public static boolean isTaxCollector(AtomicInteger status) {
|
||||
return ((status.get() & TAXCOLLECTOR) > 0);
|
||||
}
|
||||
|
||||
public static boolean isFullMember(AtomicInteger status) {
|
||||
return ((status.get() & FULLMEMBER) > 0);
|
||||
}
|
||||
|
||||
public static int getTitle(AtomicInteger status) {
|
||||
return status.get() & TITLE;
|
||||
}
|
||||
|
||||
public static int getRank(AtomicInteger status) {
|
||||
int value = status.get();
|
||||
|
||||
//Guild Leader
|
||||
if(value > 0x00FFFFFF) {
|
||||
return 10;
|
||||
}
|
||||
|
||||
//Inner Council
|
||||
if(value > 0x000FFFFF) {
|
||||
return 9;
|
||||
}
|
||||
|
||||
//Recruiter
|
||||
if(value > 0x0000FFFF) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
//Tax Collector
|
||||
if(value > 0x00000FFF) {
|
||||
return 7;
|
||||
}
|
||||
|
||||
//Full Member
|
||||
if(value > 0x000000FF) {
|
||||
return 6;
|
||||
}
|
||||
|
||||
//Petitioner
|
||||
return 5;
|
||||
}
|
||||
|
||||
//Setters
|
||||
public static void setTitle(AtomicInteger current, int i) {
|
||||
int value;
|
||||
i &= TITLE;
|
||||
do {
|
||||
value = current.get();
|
||||
}while(!current.compareAndSet(value, (value & ~TITLE) | i));
|
||||
}
|
||||
|
||||
|
||||
public static void setFullMember(AtomicInteger status, boolean newValue) {
|
||||
setNibble(status, newValue, FULLMEMBER);
|
||||
}
|
||||
|
||||
public static void setTaxCollector(AtomicInteger status, boolean newValue) {
|
||||
setNibble(status, newValue, TAXCOLLECTOR);
|
||||
}
|
||||
|
||||
public static void setRecruiter(AtomicInteger status, boolean newValue) {
|
||||
setNibble(status, newValue, RECRUITER);
|
||||
}
|
||||
|
||||
public static void setInnerCouncil(AtomicInteger status, boolean newValue) {
|
||||
setNibble(status, newValue, INNERCOUNCIL);
|
||||
}
|
||||
|
||||
public static void setGuildLeader (AtomicInteger status, boolean newValue) {
|
||||
setNibble(status, newValue, GUILDLEADER);
|
||||
}
|
||||
|
||||
private static void setNibble(AtomicInteger current, boolean newValue, int mask) {
|
||||
int value, i = ((newValue)?mask & -1:0);
|
||||
do {
|
||||
value = current.get();
|
||||
}while(!current.compareAndSet(value, (value & ~mask) | i));
|
||||
}
|
||||
|
||||
//Constants
|
||||
private static final int TITLE = 0x000000FF; // 00, F0 and 0F had no effect
|
||||
private static final int FULLMEMBER = 0x00000F00;
|
||||
private static final int TAXCOLLECTOR = 0x0000F000;
|
||||
private static final int RECRUITER = 0x000F0000;
|
||||
private static final int INNERCOUNCIL = 0x00F00000;
|
||||
private static final int GUILDLEADER = 0x0F000000;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.net.ByteBufferReader;
|
||||
import engine.net.ByteBufferWriter;
|
||||
|
||||
public class GuildTag {
|
||||
public final int backgroundColor01;
|
||||
public final int backgroundColor02;
|
||||
public final int symbolColor;
|
||||
public final int symbol;
|
||||
public final int backgroundDesign;
|
||||
public static final GuildTag ERRANT = new GuildTag(16,16,16,0,0);
|
||||
|
||||
public GuildTag(int backgroundColor01, int backgroundColor02,
|
||||
int symbolColor, int symbol, int backgroundDesign) {
|
||||
super();
|
||||
this.backgroundColor01 = backgroundColor01;
|
||||
this.backgroundColor02 = backgroundColor02;
|
||||
this.symbolColor = symbolColor;
|
||||
this.symbol = symbol;
|
||||
this.backgroundDesign = backgroundDesign;
|
||||
}
|
||||
|
||||
public GuildTag(ByteBufferReader reader, boolean forCreation) {
|
||||
this.backgroundColor01 = reader.getInt();
|
||||
this.backgroundColor02 = reader.getInt();
|
||||
this.symbolColor = reader.getInt();
|
||||
if(forCreation) {
|
||||
this.symbol = reader.getInt();
|
||||
this.backgroundDesign = reader.getInt();
|
||||
} else {
|
||||
this.backgroundDesign = reader.getInt();
|
||||
this.symbol = reader.getInt();
|
||||
}
|
||||
}
|
||||
|
||||
public GuildTag(ByteBufferReader reader) {
|
||||
this(reader, false);
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
if(this.backgroundColor01 < 0 || this.backgroundColor01 > 18)
|
||||
return false;
|
||||
if(this.backgroundColor02 < 0 || this.backgroundColor02 > 18)
|
||||
return false;
|
||||
if(this.symbolColor < 0 || this.symbolColor > 18)
|
||||
return false;
|
||||
if(this.symbol < 0 || this.symbol > 183)
|
||||
return false;
|
||||
return this.backgroundDesign >= 0 && this.backgroundDesign <= 14;
|
||||
}
|
||||
|
||||
|
||||
public static void _serializeForGuildCreation(GuildTag guildTag, ByteBufferWriter writer) {
|
||||
writer.putInt(guildTag.backgroundColor01);
|
||||
writer.putInt(guildTag.backgroundColor02);
|
||||
writer.putInt(guildTag.symbolColor);
|
||||
writer.putInt(guildTag.symbol);
|
||||
writer.putInt(guildTag.backgroundDesign);
|
||||
}
|
||||
|
||||
public static void _serializeForDisplay(GuildTag guildTag, ByteBufferWriter writer) {
|
||||
writer.putInt(guildTag.backgroundColor01);
|
||||
writer.putInt(guildTag.backgroundColor02);
|
||||
writer.putInt(guildTag.symbolColor);
|
||||
writer.putInt(guildTag.backgroundDesign);
|
||||
writer.putInt(guildTag.symbol);
|
||||
}
|
||||
|
||||
public void serializeObject(ByteBufferWriter writer) {
|
||||
writer.put((byte)this.backgroundColor01);
|
||||
writer.put((byte)this.backgroundColor02);
|
||||
writer.put((byte)this.symbolColor);
|
||||
writer.put((byte)this.backgroundDesign);
|
||||
writer.put((byte)this.symbol);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String summarySentence() {
|
||||
return "Bkgrnd: " + this.backgroundDesign + '(' + this.backgroundColor01 + '-' + this.backgroundColor02 + ')' +
|
||||
"; Symbol: " + this.symbol + '(' + this.symbolColor + ')';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.GameObjectType;
|
||||
import engine.gameManager.DbManager;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Heraldry {
|
||||
|
||||
public int playerUID;
|
||||
public int characterUUID;
|
||||
public int characterType;
|
||||
|
||||
public static HashMap <Integer,HashMap<Integer,Integer>> HeraldyMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public Heraldry(ResultSet rs) throws SQLException {
|
||||
this.playerUID = rs.getInt("playerUID");
|
||||
this.characterUUID = rs.getInt("characterUID");
|
||||
this.characterType = rs.getInt("characterType");
|
||||
|
||||
//cache player friends.
|
||||
//hashset already created, just add to set.
|
||||
if (HeraldyMap.containsKey(playerUID)){
|
||||
HashMap<Integer,Integer> playerHeraldySet = HeraldyMap.get(playerUID);
|
||||
playerHeraldySet.put(characterUUID,characterType);
|
||||
//hashset not yet created, create new set, and add to map.
|
||||
}else{
|
||||
HashMap<Integer,Integer> playerHeraldySet = new HashMap<>();
|
||||
playerHeraldySet.put(characterUUID,characterType);
|
||||
HeraldyMap.put(this.playerUID, playerHeraldySet);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Heraldry(int playerUID, int friendUID) {
|
||||
super();
|
||||
this.playerUID = playerUID;
|
||||
this.characterUUID = friendUID;
|
||||
}
|
||||
|
||||
public int getPlayerUID() {
|
||||
return playerUID;
|
||||
}
|
||||
|
||||
public static boolean AddToHeraldy(int playerID, AbstractWorldObject character){
|
||||
HashMap<Integer,Integer> characters = HeraldyMap.get(playerID);
|
||||
|
||||
if (characters != null){
|
||||
//already in friends list, don't do anything.
|
||||
if (characters.containsKey(character.getObjectUUID()))
|
||||
return false;
|
||||
|
||||
DbManager.PlayerCharacterQueries.ADD_HERALDY(playerID, character);
|
||||
characters.put(character.getObjectUUID(),character.getObjectType().ordinal());
|
||||
}else{
|
||||
characters = new HashMap<>();
|
||||
DbManager.PlayerCharacterQueries.ADD_HERALDY(playerID, character);
|
||||
characters.put(character.getObjectUUID(),character.getObjectType().ordinal());
|
||||
HeraldyMap.put(playerID, characters);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean RemoveFromHeraldy(int playerID, int characterID){
|
||||
|
||||
if (!CanRemove(playerID, characterID))
|
||||
return false;
|
||||
|
||||
HashMap<Integer,Integer> characters = HeraldyMap.get(playerID);
|
||||
|
||||
if (characters != null){
|
||||
DbManager.PlayerCharacterQueries.REMOVE_HERALDY(playerID, characterID);
|
||||
characters.remove(characterID);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean CanRemove(int playerID, int toRemove){
|
||||
if (HeraldyMap.get(playerID) == null)
|
||||
return false;
|
||||
|
||||
if (HeraldyMap.get(playerID).isEmpty())
|
||||
return false;
|
||||
|
||||
if (!HeraldyMap.get(playerID).containsKey(toRemove))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void AuditHeraldry() {
|
||||
|
||||
HashMap<Integer, Integer> characterMap;
|
||||
ArrayList<Integer> purgeList = new ArrayList<>();
|
||||
|
||||
for (int playerID : Heraldry.HeraldyMap.keySet()) {
|
||||
|
||||
characterMap = Heraldry.HeraldyMap.get(playerID);
|
||||
|
||||
if (characterMap == null || characterMap.isEmpty())
|
||||
continue;
|
||||
|
||||
// Loop through map adding deleted characters to our purge map
|
||||
|
||||
purgeList.clear();
|
||||
|
||||
for (int characterID : characterMap.keySet()) {
|
||||
|
||||
int characterType = characterMap.get(characterID);
|
||||
|
||||
if (characterType != GameObjectType.PlayerCharacter.ordinal())
|
||||
continue;
|
||||
|
||||
// Player is deleted, add to purge list
|
||||
|
||||
if (PlayerCharacter.getFromCache(characterID) == null)
|
||||
purgeList.add(characterID);
|
||||
|
||||
}
|
||||
|
||||
// Run purge
|
||||
|
||||
for (int uuid : purgeList) {
|
||||
|
||||
if (!Heraldry.RemoveFromHeraldy(playerID, uuid))
|
||||
continue;
|
||||
|
||||
Logger.info("Removed Deleted Character ID " + uuid + " from PlayerID " + playerID + " heraldry.");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ValidateHeraldry(int playerUUID) {
|
||||
|
||||
HashMap<Integer,Integer> heraldryMap = Heraldry.HeraldyMap.get(playerUUID);
|
||||
|
||||
if (heraldryMap == null || heraldryMap.isEmpty())
|
||||
return;
|
||||
|
||||
for (int characterID : heraldryMap.keySet()){
|
||||
int characterType = heraldryMap.get(characterID);
|
||||
|
||||
GameObjectType objectType = GameObjectType.values()[characterType];
|
||||
|
||||
AbstractGameObject ago = DbManager.getFromCache(objectType, characterID);
|
||||
|
||||
if (ago == null)
|
||||
heraldryMap.remove(characterID);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,918 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.DamageType;
|
||||
import engine.Enum.GameObjectType;
|
||||
import engine.Enum.ItemType;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.server.MBServerStatics;
|
||||
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;
|
||||
|
||||
public class ItemBase {
|
||||
|
||||
public static final byte GOLD_BASE_TYPE = 4;
|
||||
public static ItemBase GOLD_ITEM_BASE = null;
|
||||
public static int GOLD_BASE_ID = 7;
|
||||
public static ArrayList<Integer> AnniverseryGifts = new ArrayList<>();
|
||||
// Internal cache
|
||||
private static HashMap<Integer, Integer> itemHashIDMap = new HashMap<>();
|
||||
private static HashMap<String, Integer> _IDsByNames = new HashMap<>();
|
||||
public static HashMap<Integer, ItemBase> _itemBaseByUUID = new HashMap<>();
|
||||
private static ArrayList<ItemBase> _resourceList = new ArrayList<>();
|
||||
private final int uuid;
|
||||
private final String name;
|
||||
private float durability;
|
||||
private int value;
|
||||
private short weight;
|
||||
private short color;
|
||||
private ItemType type;
|
||||
private int vendorType;
|
||||
private int modTable;
|
||||
private int useID;
|
||||
private int hashID;
|
||||
private byte useAmount;
|
||||
// Armor and weapon related values
|
||||
private int equipFlag;
|
||||
private int restrictFlag;
|
||||
private String skillRequired;
|
||||
private short percentRequired;
|
||||
private float slashResist;
|
||||
private float crushResist;
|
||||
private float pierceResist;
|
||||
private float blockMod;
|
||||
private short defense;
|
||||
private float dexPenalty;
|
||||
private float speed;
|
||||
private float range;
|
||||
private short minDamage;
|
||||
private short maxDamage;
|
||||
private String mastery;
|
||||
private engine.Enum.DamageType damageType;
|
||||
private boolean twoHanded;
|
||||
private boolean isConsumable;
|
||||
private boolean isStackable;
|
||||
private int numCharges;
|
||||
// Item stat modifiers
|
||||
private HashMap<Integer, Integer> bakedInStats = new HashMap<>();
|
||||
private HashMap<Integer, Integer> usedStats = new HashMap<>();
|
||||
private float parryBonus;
|
||||
private boolean isStrBased;
|
||||
private ArrayList<Integer> animations = new ArrayList<>();
|
||||
private ArrayList<Integer> offHandAnimations = new ArrayList<>();
|
||||
private boolean autoID = false;
|
||||
public static HashMap<engine.Enum.ItemType, HashSet<ItemBase>> ItemBaseTypeMap = new HashMap<>();
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public ItemBase(ResultSet rs) throws SQLException {
|
||||
|
||||
this.uuid = rs.getInt("ID");
|
||||
this.name = rs.getString("name");
|
||||
this.durability = rs.getInt("durability");
|
||||
this.value = rs.getInt("value");
|
||||
this.weight = rs.getShort("weight");
|
||||
this.color = rs.getShort("color");
|
||||
this.type = ItemType.valueOf(rs.getString("Type"));
|
||||
this.useID = rs.getInt("useID");
|
||||
this.vendorType = rs.getInt("vendorType");
|
||||
this.useAmount = rs.getByte("useAmount");
|
||||
this.modTable = rs.getInt("modTable");
|
||||
this.hashID = rs.getInt("itemHashID");
|
||||
|
||||
this.isConsumable = false;
|
||||
this.isStackable = false;
|
||||
this.numCharges = rs.getShort("numCharges");
|
||||
|
||||
this.equipFlag = rs.getInt("equipFlag");
|
||||
this.restrictFlag = rs.getInt("restrictFlag");
|
||||
this.skillRequired = rs.getString("skillRequired");
|
||||
this.percentRequired = rs.getShort("percentRequired");
|
||||
this.slashResist = rs.getFloat("slashResist");
|
||||
this.crushResist = rs.getFloat("crushResist");
|
||||
this.pierceResist = rs.getFloat("pierceResist");
|
||||
this.blockMod = rs.getFloat("blockMod");
|
||||
this.defense = rs.getShort("defense");
|
||||
this.dexPenalty = rs.getFloat("dexPenalty");
|
||||
this.parryBonus = rs.getFloat("parryBonus");
|
||||
this.isStrBased = (rs.getInt("isStrBased") == 1);
|
||||
this.speed = rs.getFloat("speed");
|
||||
this.range = rs.getFloat("range");
|
||||
this.minDamage = rs.getShort("minDamage");
|
||||
this.maxDamage = rs.getShort("maxDamage");
|
||||
|
||||
this.mastery = rs.getString("mastery");
|
||||
damageType = DamageType.valueOf(rs.getString("damageType"));
|
||||
|
||||
this.twoHanded = (rs.getInt("twoHanded") == 1);
|
||||
|
||||
switch (this.type) {
|
||||
case RUNE:
|
||||
case SCROLL:
|
||||
case COMMANDROD:
|
||||
case POTION:
|
||||
case TEARS:
|
||||
case GUILDCHARTER:
|
||||
case DEED:
|
||||
case CONTRACT:
|
||||
case WATERBUCKET:
|
||||
case REALMCHARTER:
|
||||
case GIFT:
|
||||
this.isConsumable = true;
|
||||
break;
|
||||
case OFFERING:
|
||||
this.isConsumable = true;
|
||||
Boon.HandleBoonListsForItemBase(uuid);
|
||||
break;
|
||||
case RESOURCE:
|
||||
this.isStackable = true;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
this.autoIDItemsCheck();
|
||||
|
||||
try{
|
||||
DbManager.ItemBaseQueries.LOAD_ANIMATIONS(this);
|
||||
}catch(Exception e){
|
||||
Logger.error( e.getMessage());
|
||||
}
|
||||
initBakedInStats();
|
||||
initializeHashes();
|
||||
|
||||
}
|
||||
|
||||
public static void addToCache(ItemBase itemBase) {
|
||||
|
||||
_itemBaseByUUID.put(itemBase.uuid, itemBase);
|
||||
|
||||
if (itemBase.type.equals(ItemType.RESOURCE))
|
||||
_resourceList.add(itemBase);
|
||||
|
||||
_IDsByNames.put(itemBase.name.toLowerCase().replace(" ", "_"), itemBase.uuid);
|
||||
}
|
||||
|
||||
public static HashMap<Integer, Integer> getItemHashIDMap() {
|
||||
return itemHashIDMap;
|
||||
}
|
||||
|
||||
/*
|
||||
* Database
|
||||
*/
|
||||
public static ItemBase getItemBase(int uuid) {
|
||||
|
||||
return _itemBaseByUUID.get(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ItemBase instance for Gold.
|
||||
*
|
||||
* @return ItemBase for Gold
|
||||
*/
|
||||
public static ItemBase getGoldItemBase() {
|
||||
if (ItemBase.GOLD_ITEM_BASE == null)
|
||||
ItemBase.GOLD_ITEM_BASE = getItemBase(7);
|
||||
return ItemBase.GOLD_ITEM_BASE;
|
||||
}
|
||||
|
||||
public static int getIDByName(String name) {
|
||||
if (ItemBase._IDsByNames.containsKey(name))
|
||||
return ItemBase._IDsByNames.get(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _itemBaseByUUID
|
||||
*/
|
||||
public static HashMap<Integer, ItemBase> getUUIDCache() {
|
||||
return _itemBaseByUUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _resourceList
|
||||
*/
|
||||
public static ArrayList<ItemBase> getResourceList() {
|
||||
return _resourceList;
|
||||
}
|
||||
|
||||
public static void loadAllItemBases() {
|
||||
DbManager.ItemBaseQueries.LOAD_ALL_ITEMBASES();
|
||||
AnniverseryGifts.add(971000);
|
||||
AnniverseryGifts.add(971001);
|
||||
AnniverseryGifts.add(971002);
|
||||
AnniverseryGifts.add(971003);
|
||||
AnniverseryGifts.add(971004);
|
||||
AnniverseryGifts.add(971005);
|
||||
AnniverseryGifts.add(971006);
|
||||
AnniverseryGifts.add(971007);
|
||||
AnniverseryGifts.add(971008);
|
||||
AnniverseryGifts.add(971009);
|
||||
AnniverseryGifts.add(971010);
|
||||
AnniverseryGifts.add(5101000);
|
||||
AnniverseryGifts.add(5101020);
|
||||
AnniverseryGifts.add(5101100);
|
||||
AnniverseryGifts.add(5101120);
|
||||
AnniverseryGifts.add(5101040);
|
||||
AnniverseryGifts.add(5101140);
|
||||
AnniverseryGifts.add(5101060);
|
||||
AnniverseryGifts.add(5101080);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public float getDurability() {
|
||||
return this.durability;
|
||||
}
|
||||
|
||||
private void initBakedInStats() {
|
||||
DbManager.ItemBaseQueries.LOAD_BAKEDINSTATS(this);
|
||||
}
|
||||
|
||||
//TODO fix this later. Shouldn't be gotten from item base
|
||||
public int getMagicValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public int getBaseValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public short getWeight() {
|
||||
return this.weight;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
public boolean isConsumable() {
|
||||
return this.isConsumable;
|
||||
}
|
||||
|
||||
public boolean isStackable() {
|
||||
return this.isStackable;
|
||||
}
|
||||
|
||||
public int getNumCharges() {
|
||||
|
||||
return this.numCharges;
|
||||
|
||||
}
|
||||
|
||||
public int getEquipFlag() {
|
||||
|
||||
if ((this.type == ItemType.ARMOR)
|
||||
|| (this.type == ItemType.WEAPON)
|
||||
|| (this.type == ItemType.JEWELRY))
|
||||
return this.equipFlag;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean isRune() {
|
||||
int ID = uuid;
|
||||
if (ID > 2499 && ID < 3050) //class, discipline runes
|
||||
return true;
|
||||
else return ID > 249999 && ID < 252137;
|
||||
}
|
||||
|
||||
public boolean isStatRune() {
|
||||
int ID = uuid;
|
||||
return ID > 249999 && ID < 250045;
|
||||
}
|
||||
|
||||
public boolean isGlass() {
|
||||
int ID = uuid;
|
||||
return ID > 7000099 && ID < 7000281;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMasteryRune() {
|
||||
int ID = uuid;
|
||||
if (ID > 250114 && ID < 252128)
|
||||
switch (ID) {
|
||||
case 250115:
|
||||
case 250118:
|
||||
case 250119:
|
||||
case 250120:
|
||||
case 250121:
|
||||
case 250122:
|
||||
case 252123:
|
||||
case 252124:
|
||||
case 252125:
|
||||
case 252126:
|
||||
case 252127:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//returns powers tokens baked in to item
|
||||
public HashMap<Integer, Integer> getBakedInStats() {
|
||||
return this.bakedInStats;
|
||||
}
|
||||
|
||||
//returns power tokens granted when using item, such as scrolls and potions
|
||||
public HashMap<Integer, Integer> getUsedStats() {
|
||||
return this.usedStats;
|
||||
}
|
||||
|
||||
public final void initializeHashes() {
|
||||
itemHashIDMap.put(this.hashID, uuid);
|
||||
|
||||
}
|
||||
|
||||
public ItemType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public int getUseID() {
|
||||
return this.useID;
|
||||
}
|
||||
|
||||
public byte getUseAmount() {
|
||||
return this.useAmount;
|
||||
}
|
||||
|
||||
public int getModTable() {
|
||||
return modTable;
|
||||
}
|
||||
|
||||
public int getVendorType() {
|
||||
return vendorType;
|
||||
}
|
||||
|
||||
public void setVendorType(int vendorType) {
|
||||
this.vendorType = vendorType;
|
||||
}
|
||||
|
||||
public int getHashID() {
|
||||
return hashID;
|
||||
}
|
||||
|
||||
public void setHashID(int hashID) {
|
||||
this.hashID = hashID;
|
||||
}
|
||||
|
||||
private void autoIDItemsCheck(){
|
||||
//AUto ID Vorg and Glass
|
||||
switch (uuid){
|
||||
|
||||
case 27550:
|
||||
case 27560:
|
||||
case 27580:
|
||||
case 27590:
|
||||
case 188500:
|
||||
case 188510:
|
||||
case 188520:
|
||||
case 188530:
|
||||
case 188540:
|
||||
case 188550:
|
||||
case 189100:
|
||||
case 189110:
|
||||
case 189120:
|
||||
case 189130:
|
||||
case 189140:
|
||||
case 189150:
|
||||
case 189510:
|
||||
case 27600:
|
||||
case 181840:
|
||||
case 188700:
|
||||
case 188720:
|
||||
case 189550:
|
||||
case 189560:
|
||||
case 7000100:
|
||||
case 7000110:
|
||||
case 7000120:
|
||||
case 7000130:
|
||||
case 7000140:
|
||||
case 7000150:
|
||||
case 7000160:
|
||||
case 7000170:
|
||||
case 7000180:
|
||||
case 7000190:
|
||||
case 7000200:
|
||||
case 7000210:
|
||||
case 7000220:
|
||||
case 7000230:
|
||||
case 7000240:
|
||||
case 7000250:
|
||||
case 7000270:
|
||||
case 7000280:
|
||||
this.autoID = true;
|
||||
break;
|
||||
default:
|
||||
this.autoID = false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean validForSkills(ConcurrentHashMap<String, CharacterSkill> skills) {
|
||||
|
||||
CharacterSkill characterSkill;
|
||||
|
||||
if (this.skillRequired.isEmpty())
|
||||
return true;
|
||||
|
||||
characterSkill = skills.get(this.skillRequired);
|
||||
|
||||
if (characterSkill == null)
|
||||
return false;
|
||||
|
||||
return !(this.percentRequired > characterSkill.getModifiedAmountBeforeMods());
|
||||
}
|
||||
|
||||
public boolean canEquip(int slot, CharacterItemManager itemManager, AbstractCharacter abstractCharacter, Item item) {
|
||||
|
||||
if (itemManager == null || abstractCharacter == null)
|
||||
return false;
|
||||
|
||||
if (abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter)) {
|
||||
|
||||
if (!validForSlot(slot, itemManager.getEquipped(), item))
|
||||
return false;
|
||||
|
||||
if (!validForSkills(abstractCharacter.getSkills()))
|
||||
return false;
|
||||
|
||||
return item.getItemBase().value != 0 || Kit.IsNoobGear(item.getItemBase().uuid);
|
||||
//players can't wear 0 value items.
|
||||
|
||||
}
|
||||
|
||||
return true; //Mobiles and NPC's don't need to check equip
|
||||
}
|
||||
|
||||
public int getValidSlot() {
|
||||
int slotValue = 0;
|
||||
|
||||
switch (this.type) {
|
||||
case WEAPON:
|
||||
if ((this.equipFlag & 1) != 0)
|
||||
slotValue = MBServerStatics.SLOT_MAINHAND;
|
||||
else if ((this.equipFlag & 2) != 0)
|
||||
slotValue = MBServerStatics.SLOT_OFFHAND;
|
||||
break;
|
||||
case ARMOR:
|
||||
if ((this.equipFlag & 2) != 0)
|
||||
slotValue = MBServerStatics.SLOT_OFFHAND;
|
||||
else if ((this.equipFlag & 4) != 0)
|
||||
slotValue = MBServerStatics.SLOT_HELMET;
|
||||
else if ((this.equipFlag & 8) != 0)
|
||||
slotValue = MBServerStatics.SLOT_CHEST;
|
||||
else if ((this.equipFlag & 16) != 0)
|
||||
slotValue = MBServerStatics.SLOT_ARMS;
|
||||
else if ((this.equipFlag & 32) != 0)
|
||||
slotValue = MBServerStatics.SLOT_GLOVES;
|
||||
else if ((this.equipFlag & 64) != 0)
|
||||
slotValue = MBServerStatics.SLOT_RING2;
|
||||
else if ((this.equipFlag & 128) != 0)
|
||||
slotValue = MBServerStatics.SLOT_RING1;
|
||||
else if ((this.equipFlag & 256) != 0)
|
||||
slotValue = MBServerStatics.SLOT_NECKLACE;
|
||||
else if ((this.equipFlag & 512) != 0)
|
||||
slotValue = MBServerStatics.SLOT_LEGGINGS;
|
||||
else if ((this.equipFlag & 1024) != 0)
|
||||
slotValue = MBServerStatics.SLOT_FEET;
|
||||
break;
|
||||
|
||||
case HAIR:
|
||||
if (this.equipFlag == 131072)
|
||||
slotValue = MBServerStatics.SLOT_HAIRSTYLE;
|
||||
else if(this.equipFlag == 65536)
|
||||
slotValue = MBServerStatics.SLOT_BEARDSTYLE;
|
||||
break;
|
||||
|
||||
}
|
||||
return slotValue;
|
||||
|
||||
}
|
||||
|
||||
public boolean validSlotFlag(long flags) {
|
||||
|
||||
boolean validSlot = false;
|
||||
|
||||
switch (this.type) {
|
||||
case WEAPON:
|
||||
if (this.isMelee())
|
||||
validSlot = ((flags & 1) != 0);
|
||||
else if (this.isThrowing())
|
||||
validSlot = ((flags & 2) != 0);
|
||||
else if (this.isArchery())
|
||||
validSlot = ((flags & 4) != 0);
|
||||
else if (this.isScepter())
|
||||
validSlot = ((flags & 8) != 0);
|
||||
else if (this.isStaff())
|
||||
validSlot = ((flags & 16) != 0);
|
||||
break;
|
||||
case JEWELRY:
|
||||
if (this.isNecklace())
|
||||
validSlot = ((flags & 2147483648L) != 0L);
|
||||
else
|
||||
validSlot = ((flags & 4294967296L) != 0L);
|
||||
break;
|
||||
case ARMOR:
|
||||
|
||||
if (this.isShield()) {
|
||||
validSlot = ((flags & 32) != 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.isClothArmor()) {
|
||||
|
||||
if (this.getEquipFlag() == 4) //hood
|
||||
validSlot = ((flags & 64) != 0);
|
||||
else if (this.getEquipFlag() == 8) {
|
||||
if ((restrictFlag & 512) != 0) //Robe
|
||||
validSlot = ((flags & 128) != 0);
|
||||
else
|
||||
validSlot = ((flags & 1024) != 0); //Tunic/Shirt
|
||||
|
||||
break;
|
||||
} else if (this.getEquipFlag() == 16) //Sleeves
|
||||
validSlot = ((flags & 2048) != 0);
|
||||
else if (this.getEquipFlag() == 32) //Gloves
|
||||
validSlot = ((flags & 512) != 0);
|
||||
else if (this.getEquipFlag() == 512) //Pants
|
||||
validSlot = ((flags & 4096) != 0);
|
||||
else if (this.getEquipFlag() == 1024) //Boots
|
||||
validSlot = ((flags & 256) != 0);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.isLightArmor()) {
|
||||
if (this.getEquipFlag() == 4) //helm
|
||||
validSlot = ((flags & 8192) != 0);
|
||||
else if (this.getEquipFlag() == 8) //Chest
|
||||
validSlot = ((flags & 16384) != 0);
|
||||
else if (this.getEquipFlag() == 16) //Sleeves
|
||||
validSlot = ((flags & 32768) != 0);
|
||||
else if (this.getEquipFlag() == 32) //Gloves
|
||||
validSlot = ((flags & 65536) != 0);
|
||||
else if (this.getEquipFlag() == 512) //Pants
|
||||
validSlot = ((flags & 131072) != 0);
|
||||
else if (this.getEquipFlag() == 1024) //Boots
|
||||
validSlot = ((flags & 262144) != 0);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.isMediumArmor()) {
|
||||
if (this.getEquipFlag() == 4) //helm
|
||||
validSlot = ((flags & 524288) != 0);
|
||||
else if (this.getEquipFlag() == 8) //Chest
|
||||
validSlot = ((flags & 1048576) != 0);
|
||||
else if (this.getEquipFlag() == 16) //Sleeves
|
||||
validSlot = ((flags & 2097152) != 0);
|
||||
else if (this.getEquipFlag() == 32) //Gloves
|
||||
validSlot = ((flags & 4194304) != 0);
|
||||
else if (this.getEquipFlag() == 512) //Pants
|
||||
validSlot = ((flags & 8388608) != 0);
|
||||
else if (this.getEquipFlag() == 1024) //Boots
|
||||
validSlot = ((flags & 16777216) != 0);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.isHeavyArmor())
|
||||
if (this.getEquipFlag() == 4) //helm
|
||||
validSlot = ((flags & 33554432) != 0);
|
||||
else if (this.getEquipFlag() == 8) //Chest
|
||||
validSlot = ((flags & 67108864) != 0);
|
||||
else if (this.getEquipFlag() == 16) //Sleeves
|
||||
validSlot = ((flags & 134217728) != 0);
|
||||
else if (this.getEquipFlag() == 32) //Gloves
|
||||
validSlot = ((flags & 268435456) != 0);
|
||||
else if (this.getEquipFlag() == 512) //Pants
|
||||
validSlot = ((flags & 536870912) != 0);
|
||||
else if (this.getEquipFlag() == 1024) //Boots
|
||||
validSlot = ((flags & 1073741824) != 0);
|
||||
break;
|
||||
}
|
||||
return validSlot;
|
||||
}
|
||||
|
||||
public boolean validForSlot(int slot, ConcurrentHashMap<Integer, Item> equipped, Item item) {
|
||||
|
||||
boolean validSlot = false;
|
||||
|
||||
if (equipped == null)
|
||||
return validSlot;
|
||||
|
||||
// Cannot equip an item in a slot already taken
|
||||
if (equipped.get(slot) != null && equipped.get(slot).equals(item) == false)
|
||||
return validSlot;
|
||||
|
||||
switch (item.getItemBase().type) {
|
||||
case WEAPON:
|
||||
|
||||
// Only two slots available for weapons
|
||||
if ((slot != MBServerStatics.SLOT_MAINHAND) && (slot != MBServerStatics.SLOT_OFFHAND))
|
||||
break;
|
||||
|
||||
//make sure weapon is valid for slot
|
||||
if ((slot & this.equipFlag) == 0)
|
||||
break;
|
||||
|
||||
// Two handed weapons take up two slots
|
||||
if ((this.twoHanded == true) &&
|
||||
((slot == MBServerStatics.SLOT_OFFHAND && equipped.get(MBServerStatics.SLOT_MAINHAND) != null) ||
|
||||
(slot == MBServerStatics.SLOT_MAINHAND && equipped.get(MBServerStatics.SLOT_OFFHAND) != null)))
|
||||
break;
|
||||
|
||||
// Validation passed, must be a valid weapon
|
||||
|
||||
validSlot = true;
|
||||
break;
|
||||
case JEWELRY:
|
||||
// Not a valid slot for ring
|
||||
|
||||
if (this.isRing() &&
|
||||
((slot != MBServerStatics.SLOT_RING1) && (slot != MBServerStatics.SLOT_RING2)))
|
||||
break;
|
||||
|
||||
// Not a valid slot for necklace
|
||||
|
||||
if (this.isNecklace() && slot != MBServerStatics.SLOT_NECKLACE)
|
||||
break;
|
||||
|
||||
// Passed validation, must be valid bling bling
|
||||
|
||||
validSlot = true;
|
||||
break;
|
||||
case ARMOR:
|
||||
|
||||
// Invalid slot for armor?
|
||||
if (slot == MBServerStatics.SLOT_OFFHAND && ((2 & this.equipFlag) == 0))
|
||||
break;
|
||||
if (slot == MBServerStatics.SLOT_HELMET && ((4 & this.equipFlag) == 0))
|
||||
break;
|
||||
if (slot == MBServerStatics.SLOT_CHEST && ((8 & this.equipFlag) == 0))
|
||||
break;
|
||||
if (slot == MBServerStatics.SLOT_ARMS && ((16 & this.equipFlag) == 0))
|
||||
break;
|
||||
if (slot == MBServerStatics.SLOT_GLOVES && ((32 & this.equipFlag) == 0))
|
||||
break;
|
||||
if (slot == MBServerStatics.SLOT_LEGGINGS && ((512 & this.equipFlag) == 0))
|
||||
break;
|
||||
if (slot == MBServerStatics.SLOT_FEET && ((1024 & this.equipFlag) == 0))
|
||||
break;
|
||||
|
||||
// Is slot for this piece already taken?
|
||||
if (((this.restrictFlag & 2) != 0) && (equipped.get(MBServerStatics.SLOT_OFFHAND) != null) && slot != MBServerStatics.SLOT_OFFHAND)
|
||||
break;
|
||||
if (((this.restrictFlag & 4) != 0) && (equipped.get(MBServerStatics.SLOT_HELMET) != null) && slot != MBServerStatics.SLOT_HELMET)
|
||||
break;
|
||||
if (((this.restrictFlag & 8) != 0) && (equipped.get(MBServerStatics.SLOT_CHEST) != null) && slot != MBServerStatics.SLOT_CHEST)
|
||||
break;
|
||||
if (((this.restrictFlag & 16) != 0) && (equipped.get(MBServerStatics.SLOT_ARMS) != null) && slot != MBServerStatics.SLOT_ARMS)
|
||||
break;
|
||||
if (((this.restrictFlag & 32) != 0) && (equipped.get(MBServerStatics.SLOT_GLOVES) != null) && slot != MBServerStatics.SLOT_GLOVES)
|
||||
break;
|
||||
if (((this.restrictFlag & 512) != 0) && (equipped.get(MBServerStatics.SLOT_LEGGINGS) != null) && slot != MBServerStatics.SLOT_LEGGINGS)
|
||||
break;
|
||||
if (((this.restrictFlag & 1024) != 0) && (equipped.get(MBServerStatics.SLOT_FEET) != null) && slot != MBServerStatics.SLOT_FEET)
|
||||
break;
|
||||
|
||||
// Passed validation. Is a valid armor piece
|
||||
|
||||
validSlot = true;
|
||||
break;
|
||||
}
|
||||
return validSlot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the uuid
|
||||
*/
|
||||
public final int getUUID() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public boolean isRing() {
|
||||
return ((this.equipFlag & (64 | 128 | 192)) != 0);
|
||||
}
|
||||
|
||||
public boolean isNecklace() {
|
||||
return (this.equipFlag == 256);
|
||||
}
|
||||
|
||||
public boolean isShield() {
|
||||
return this.type.equals(ItemType.ARMOR) && this.equipFlag == 2;
|
||||
}
|
||||
|
||||
public boolean isLightArmor() {
|
||||
return this.skillRequired.equals("Wear Armor, Light");
|
||||
}
|
||||
|
||||
public boolean isMediumArmor() {
|
||||
return this.skillRequired.equals("Wear Armor, Medium");
|
||||
}
|
||||
|
||||
public boolean isHeavyArmor() {
|
||||
return this.skillRequired.equals("Wear Armor, Heavy");
|
||||
}
|
||||
|
||||
public boolean isClothArmor() {
|
||||
return this.skillRequired.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isThrowing() {
|
||||
return this.mastery.equals("Throwing") ? true : false;
|
||||
}
|
||||
|
||||
public boolean isStaff() {
|
||||
return this.mastery.equals("Staff") ? true : false;
|
||||
}
|
||||
|
||||
public boolean isScepter() {
|
||||
return this.mastery.equals("Benediction") ? true : false;
|
||||
}
|
||||
|
||||
public boolean isArchery() {
|
||||
return this.mastery.equals("Archery") ? true : false;
|
||||
}
|
||||
|
||||
public boolean isMelee() {
|
||||
return (this.isThrowing() == false && this.isStaff() == false && this.isScepter() == false && this.isArchery() == false);
|
||||
}
|
||||
|
||||
public boolean isTwoHanded() {
|
||||
return this.twoHanded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the restrictFlag
|
||||
*/
|
||||
public int getRestrictFlag() {
|
||||
return restrictFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the slashResist
|
||||
*/
|
||||
public float getSlashResist() {
|
||||
return slashResist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the crushResist
|
||||
*/
|
||||
public float getCrushResist() {
|
||||
return crushResist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pierceResist
|
||||
*/
|
||||
public float getPierceResist() {
|
||||
return pierceResist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the skillRequired
|
||||
*/
|
||||
public String getSkillRequired() {
|
||||
return skillRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the mastery
|
||||
*/
|
||||
public String getMastery() {
|
||||
return mastery;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the blockMod
|
||||
*/
|
||||
public float getBlockMod() {
|
||||
return blockMod;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the defense
|
||||
*/
|
||||
public short getDefense() {
|
||||
return defense;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the dexPenalty
|
||||
*/
|
||||
public float getDexPenalty() {
|
||||
return dexPenalty;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the speed
|
||||
*/
|
||||
public float getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the range
|
||||
*/
|
||||
public float getRange() {
|
||||
return range;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the isStrBased
|
||||
*/
|
||||
public boolean isStrBased() {
|
||||
return isStrBased;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the parryBonus
|
||||
*/
|
||||
public float getParryBonus() {
|
||||
return parryBonus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maxDamage
|
||||
*/
|
||||
public short getMaxDamage() {
|
||||
return maxDamage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the minDamage
|
||||
*/
|
||||
public short getMinDamage() {
|
||||
return minDamage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the damageType
|
||||
*/
|
||||
public engine.Enum.DamageType getDamageType() {
|
||||
return damageType;
|
||||
}
|
||||
|
||||
public short getPercentRequired() {
|
||||
return percentRequired;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getAnimations() {
|
||||
return animations;
|
||||
}
|
||||
|
||||
public void setAnimations(ArrayList<Integer> animations) {
|
||||
this.animations = animations;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getOffHandAnimations() {
|
||||
return offHandAnimations;
|
||||
}
|
||||
|
||||
public void setOffHandAnimations(ArrayList<Integer> offHandAnimations) {
|
||||
this.offHandAnimations = offHandAnimations;
|
||||
}
|
||||
|
||||
public boolean isAutoID() {
|
||||
return autoID;
|
||||
}
|
||||
|
||||
public void setAutoID(boolean autoID) {
|
||||
this.autoID = autoID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.ContainerType;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class ItemContainer extends AbstractGameObject {
|
||||
|
||||
private AbstractWorldObject owner;
|
||||
private ConcurrentHashMap<Long, Item>itemMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
private ContainerType containerType;
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public ItemContainer(AbstractWorldObject owner, ContainerType containerType) {
|
||||
super();
|
||||
this.owner = owner;
|
||||
this.containerType = containerType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public ItemContainer(AbstractWorldObject owner, ContainerType containerType, int newUUID) {
|
||||
super(newUUID);
|
||||
this.owner = owner;
|
||||
this.containerType = containerType;
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public ItemContainer(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
//get owner
|
||||
long ownerID = rs.getLong("parent");
|
||||
this.owner = (AbstractWorldObject)AbstractGameObject.getFromTypeAndID(ownerID);
|
||||
|
||||
//get ContainerType
|
||||
String ct = rs.getString("container_type");
|
||||
try {
|
||||
this.containerType = ContainerType.valueOf(ct.toUpperCase());
|
||||
} catch (Exception e) {
|
||||
this.containerType = ContainerType.INVENTORY;
|
||||
Logger.error( "invalid containerType");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public AbstractWorldObject getOwner() {
|
||||
return this.owner;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<Long, Item> getItemMap() {
|
||||
return this.itemMap;
|
||||
}
|
||||
|
||||
public ContainerType getContainerType() {
|
||||
return this.containerType;
|
||||
}
|
||||
|
||||
public boolean isBank() {
|
||||
return (this.containerType == ContainerType.BANK);
|
||||
}
|
||||
|
||||
public boolean isInventory() {
|
||||
return (this.containerType == ContainerType.INVENTORY);
|
||||
}
|
||||
|
||||
public boolean isVault() {
|
||||
return (this.containerType == ContainerType.VAULT);
|
||||
}
|
||||
|
||||
public boolean containsItem(long itemID) {
|
||||
return this.itemMap.containsKey(itemID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Create update logic.
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,429 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.ItemContainerType;
|
||||
import engine.Enum.OwnerType;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class Kit extends AbstractGameObject {
|
||||
|
||||
private final int raceBaseClassID;
|
||||
private final byte kitNumber;
|
||||
private final int legs;
|
||||
private final int chest;
|
||||
private final int feet;
|
||||
private final int offhand;
|
||||
private final int weapon;
|
||||
public static HashMap<Integer,Boolean> NoobGearIDS = new HashMap<>();
|
||||
public static HashMap<Integer, ArrayList<Kit>> RaceClassIDMap = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public Kit(int raceBaseClassID, byte kitNumber, int legs, int chest,
|
||||
int feet, int offhand, int weapon) {
|
||||
super();
|
||||
this.raceBaseClassID = raceBaseClassID;
|
||||
this.kitNumber = kitNumber;
|
||||
this.legs = legs;
|
||||
this.chest = chest;
|
||||
this.feet = feet;
|
||||
this.offhand = offhand;
|
||||
this.weapon = weapon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public Kit(int raceBaseClassID, byte kitNumber, int legs, int chest,
|
||||
int feet, int offhand, int weapon, int newUUID) {
|
||||
super(newUUID);
|
||||
this.raceBaseClassID = raceBaseClassID;
|
||||
this.kitNumber = kitNumber;
|
||||
this.legs = legs;
|
||||
this.chest = chest;
|
||||
this.feet = feet;
|
||||
this.offhand = offhand;
|
||||
this.weapon = weapon;
|
||||
}
|
||||
|
||||
/**
|
||||
* RecordSet Constructor
|
||||
*/
|
||||
public Kit(ResultSet rs) throws SQLException, UnknownHostException {
|
||||
super(rs);
|
||||
|
||||
this.raceBaseClassID = rs.getInt("RaceBaseClassesID");
|
||||
this.kitNumber = rs.getByte("kitNumber");
|
||||
|
||||
this.legs = rs.getInt("legs");
|
||||
this.chest = rs.getInt("chest");
|
||||
this.feet = rs.getInt("feet");
|
||||
this.offhand = rs.getInt("offhand");
|
||||
this.weapon = rs.getInt("weapon");
|
||||
if (Kit.RaceClassIDMap.containsKey(this.raceBaseClassID)){
|
||||
Kit.RaceClassIDMap.get(this.raceBaseClassID).add(this);
|
||||
}else{
|
||||
ArrayList<Kit> tempList = new ArrayList<>();
|
||||
tempList.add(this);
|
||||
Kit.RaceClassIDMap.put(this.raceBaseClassID, tempList);
|
||||
|
||||
}
|
||||
|
||||
if (this.legs != 0)
|
||||
Kit.NoobGearIDS.put(this.legs, true);
|
||||
if (this.chest != 0)
|
||||
Kit.NoobGearIDS.put(this.chest, true);
|
||||
if (this.feet != 0)
|
||||
Kit.NoobGearIDS.put(this.feet, true);
|
||||
if (this.offhand != 0)
|
||||
Kit.NoobGearIDS.put(this.offhand, true);
|
||||
if (this.weapon != 0)
|
||||
Kit.NoobGearIDS.put(this.weapon, true);
|
||||
|
||||
}
|
||||
|
||||
public static boolean IsNoobGear(int itemID){
|
||||
|
||||
return Kit.NoobGearIDS.containsKey(itemID);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
|
||||
public int getRaceBaseClassID() {
|
||||
return raceBaseClassID;
|
||||
}
|
||||
|
||||
public byte getKitNumber() {
|
||||
return kitNumber;
|
||||
}
|
||||
|
||||
public int getLegs() {
|
||||
return legs;
|
||||
}
|
||||
|
||||
public int getChest() {
|
||||
return chest;
|
||||
}
|
||||
|
||||
public int getFeet() {
|
||||
return feet;
|
||||
}
|
||||
|
||||
public int getOffhand() {
|
||||
return offhand;
|
||||
}
|
||||
|
||||
public int getWeapon() {
|
||||
return weapon;
|
||||
}
|
||||
|
||||
public void equipPCwithKit(PlayerCharacter pc) {
|
||||
if (weapon != 0)
|
||||
kitItemCreator(pc, weapon, MBServerStatics.SLOT_MAINHAND);
|
||||
if (offhand != 0)
|
||||
kitItemCreator(pc, offhand, MBServerStatics.SLOT_OFFHAND);
|
||||
if (chest != 0)
|
||||
kitItemCreator(pc, chest, MBServerStatics.SLOT_CHEST);
|
||||
if (legs != 0)
|
||||
kitItemCreator(pc, legs, MBServerStatics.SLOT_LEGGINGS);
|
||||
if (feet != 0)
|
||||
kitItemCreator(pc, feet, MBServerStatics.SLOT_FEET);
|
||||
}
|
||||
|
||||
private static boolean kitItemCreator(PlayerCharacter pc, int itemBase, int slot)
|
||||
{
|
||||
ItemBase i = ItemBase.getItemBase(itemBase);
|
||||
|
||||
Item temp = new Item( i, pc.getObjectUUID(),
|
||||
OwnerType.PlayerCharacter, (byte) 0, (byte) 0, (short) 0, (short) 0,
|
||||
false, false,ItemContainerType.EQUIPPED, (byte) slot,
|
||||
new ArrayList<>(),"");
|
||||
|
||||
try {
|
||||
temp = DbManager.ItemQueries.ADD_ITEM(temp);
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
if (temp == null) {
|
||||
Logger.info("Ungoof this goof, something is wrong with our kit.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int GetKitIDByRaceClass(final int raceID, final int classID){
|
||||
switch (raceID){
|
||||
case 2000:
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 2;
|
||||
case 2501:
|
||||
return 3;
|
||||
case 2502:
|
||||
return 4;
|
||||
case 2503:
|
||||
return 5;
|
||||
}
|
||||
case 2001:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 6;
|
||||
case 2501:
|
||||
return 7;
|
||||
case 2502:
|
||||
return 8;
|
||||
case 2503:
|
||||
return 9;
|
||||
}
|
||||
case 2002:
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 10;
|
||||
case 2501:
|
||||
return 11;
|
||||
case 2502:
|
||||
return 12;
|
||||
|
||||
}
|
||||
case 2003:
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 13;
|
||||
case 2501:
|
||||
return 14;
|
||||
case 2502:
|
||||
return 15;
|
||||
}
|
||||
case 2004:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 16;
|
||||
case 2501:
|
||||
return 17;
|
||||
}
|
||||
case 2005:
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 18;
|
||||
case 2501:
|
||||
return 19;
|
||||
}
|
||||
case 2006:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 20;
|
||||
case 2501:
|
||||
return 21;
|
||||
|
||||
}
|
||||
case 2008:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 22;
|
||||
case 2501:
|
||||
return 23;
|
||||
case 2502:
|
||||
return 24;
|
||||
case 2503:
|
||||
return 25;
|
||||
}
|
||||
|
||||
case 2009:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 26;
|
||||
case 2501:
|
||||
return 27;
|
||||
case 2502:
|
||||
return 28;
|
||||
case 2503:
|
||||
return 29;
|
||||
}
|
||||
case 2010:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 30;
|
||||
}
|
||||
|
||||
case 2011:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 31;
|
||||
case 2501:
|
||||
return 32;
|
||||
case 2502:
|
||||
return 33;
|
||||
case 2503:
|
||||
return 34;
|
||||
}
|
||||
|
||||
case 2012:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 35;
|
||||
case 2501:
|
||||
return 36;
|
||||
case 2502:
|
||||
return 37;
|
||||
case 2503:
|
||||
return 38;
|
||||
}
|
||||
|
||||
case 2013:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 39;
|
||||
case 2501:
|
||||
return 40;
|
||||
case 2502:
|
||||
return 41;
|
||||
case 2503:
|
||||
return 42;
|
||||
}
|
||||
|
||||
case 2014:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 43;
|
||||
case 2501:
|
||||
return 44;
|
||||
case 2502:
|
||||
return 45;
|
||||
case 2503:
|
||||
return 46;
|
||||
}
|
||||
|
||||
case 2015:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 47;
|
||||
case 2502:
|
||||
return 48;
|
||||
case 2503:
|
||||
return 49;
|
||||
|
||||
}
|
||||
|
||||
case 2016:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 50;
|
||||
case 2502:
|
||||
return 51;
|
||||
case 2503:
|
||||
return 52;
|
||||
|
||||
}
|
||||
|
||||
case 2017:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 53;
|
||||
case 2501:
|
||||
return 54;
|
||||
|
||||
}
|
||||
|
||||
case 2025:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 55;
|
||||
case 2501:
|
||||
return 56;
|
||||
case 2502:
|
||||
return 57;
|
||||
case 2503:
|
||||
return 58;
|
||||
}
|
||||
|
||||
case 2026:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 59;
|
||||
case 2501:
|
||||
return 60;
|
||||
case 2502:
|
||||
return 61;
|
||||
case 2503:
|
||||
return 62;
|
||||
}
|
||||
|
||||
case 2027:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 63;
|
||||
}
|
||||
|
||||
case 2028:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 64;
|
||||
|
||||
case 2502:
|
||||
return 65;
|
||||
case 2503:
|
||||
return 66;
|
||||
}
|
||||
|
||||
case 2029:
|
||||
|
||||
switch(classID){
|
||||
case 2500:
|
||||
return 67;
|
||||
|
||||
case 2502:
|
||||
return 68;
|
||||
case 2503:
|
||||
return 69;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Create update logic.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class LevelDefault {
|
||||
|
||||
public final int level;
|
||||
public final float health;
|
||||
public final float mana;
|
||||
public final float stamina;
|
||||
public final float atr;
|
||||
public final float def;
|
||||
public final float minDamage;
|
||||
public final float maxDamage;
|
||||
public final int goldMin;
|
||||
public final int goldMax;
|
||||
|
||||
public static ConcurrentHashMap<Byte, LevelDefault> defaults = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public LevelDefault(ResultSet rs) throws SQLException {
|
||||
super();
|
||||
this.level = rs.getInt("level");
|
||||
this.health = rs.getFloat("health");
|
||||
this.mana = (float)rs.getInt("mana");
|
||||
this.stamina = (float)rs.getInt("stamina");
|
||||
this.atr = (float)rs.getInt("atr");
|
||||
this.def = (float)rs.getInt("def");
|
||||
this.minDamage = (float)rs.getInt("minDamage");
|
||||
this.maxDamage = (float)rs.getInt("maxDamage");
|
||||
this.goldMin = rs.getInt("goldMin");
|
||||
this.goldMax = rs.getInt("goldMax");
|
||||
}
|
||||
|
||||
public static LevelDefault getLevelDefault(byte level) {
|
||||
LevelDefault ret = null;
|
||||
if (LevelDefault.defaults.containsKey(level))
|
||||
return LevelDefault.defaults.get(level);
|
||||
|
||||
PreparedStatementShared ps = null;
|
||||
try {
|
||||
ps = new PreparedStatementShared("SELECT * FROM `static_npc_level_defaults` WHERE level = ?;");
|
||||
ps.setInt(1, (int)level);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
if (rs.next()) {
|
||||
ret = new LevelDefault(rs);
|
||||
LevelDefault.defaults.put(level, ret);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error("SQL Error number: " + e.getErrorCode() + ' ' + e.getMessage());
|
||||
} finally {
|
||||
ps.release();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
public class LootRow {
|
||||
|
||||
private int valueOne;
|
||||
private int valueTwo;
|
||||
private int valueThree;
|
||||
private String action;
|
||||
|
||||
|
||||
/**
|
||||
* Generic Constructor
|
||||
*/
|
||||
public LootRow(int valueOne, int valueTwo, int valueThree, String action) {
|
||||
this.valueOne = valueOne;
|
||||
this.valueTwo = valueTwo;
|
||||
this.valueThree = valueThree;
|
||||
this.action = action;
|
||||
|
||||
}
|
||||
|
||||
public int getValueOne() {
|
||||
return this.valueOne;
|
||||
}
|
||||
|
||||
public int getValueTwo() {
|
||||
return this.valueTwo;
|
||||
}
|
||||
|
||||
public int getValueThree() {
|
||||
return this.valueThree;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return this.action;
|
||||
}
|
||||
|
||||
public void setValueOne(int value) {
|
||||
this.valueOne = value;
|
||||
}
|
||||
|
||||
public void setValueTwo(int value) {
|
||||
this.valueTwo = value;
|
||||
}
|
||||
|
||||
public void setValueThree(int value) {
|
||||
this.valueThree = value;
|
||||
}
|
||||
|
||||
public void setAction(String value) {
|
||||
this.action = value;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,79 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class MaxSkills {
|
||||
|
||||
private int runeID;
|
||||
private int skillToken;
|
||||
private int skillLevel;
|
||||
private int maxSkillPercent;
|
||||
|
||||
|
||||
|
||||
public static HashMap<Integer, ArrayList<MaxSkills>> MaxSkillsSet = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public MaxSkills(ResultSet rs) throws SQLException {
|
||||
this.runeID = rs.getInt("runeID");
|
||||
this.skillToken =rs.getInt("skillToken");
|
||||
this.skillLevel = rs.getInt("skillLevel");
|
||||
this.maxSkillPercent = rs.getInt("maxSkillPercent");
|
||||
}
|
||||
|
||||
public MaxSkills(int runeID, int skillToken, int skillLevel, int maxSkillPercent) {
|
||||
super();
|
||||
this.runeID = runeID;
|
||||
this.skillToken = skillToken;
|
||||
this.skillLevel = skillLevel;
|
||||
this.maxSkillPercent = maxSkillPercent;
|
||||
}
|
||||
|
||||
public int getRuneID() {
|
||||
return runeID;
|
||||
}
|
||||
|
||||
public void setRuneID(int runeID) {
|
||||
this.runeID = runeID;
|
||||
}
|
||||
|
||||
public int getSkillLevel() {
|
||||
return skillLevel;
|
||||
}
|
||||
|
||||
public void setSkillLevel(int skillLevel) {
|
||||
this.skillLevel = skillLevel;
|
||||
}
|
||||
|
||||
public int getSkillToken() {
|
||||
return skillToken;
|
||||
}
|
||||
|
||||
public void setSkillToken(int skillToken) {
|
||||
this.skillToken = skillToken;
|
||||
}
|
||||
|
||||
public int getMaxSkillPercent() {
|
||||
return maxSkillPercent;
|
||||
}
|
||||
|
||||
public void setMaxSkillPercent(int maxSkillPercent) {
|
||||
this.maxSkillPercent = maxSkillPercent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
public class MenuOption extends AbstractGameObject {
|
||||
|
||||
private final int menuID;
|
||||
private final String message;
|
||||
private final int optionID;
|
||||
private final int prereq;
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public MenuOption(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
this.menuID = rs.getInt("menuID");
|
||||
this.message = rs.getString("message");
|
||||
this.optionID = rs.getInt("optionID");
|
||||
this.prereq = rs.getInt("prereq");
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public int getMenuID() {
|
||||
return this.menuID;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public int getOptionID() {
|
||||
return this.optionID;
|
||||
}
|
||||
|
||||
public int getPrereq() {
|
||||
return this.prereq;
|
||||
}
|
||||
|
||||
/*
|
||||
* Database
|
||||
*/
|
||||
@Override
|
||||
public void updateDatabase() {}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.math.Bounds;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class MeshBounds {
|
||||
|
||||
public int meshID;
|
||||
public final float minX;
|
||||
public final float minY;
|
||||
public final float minZ;
|
||||
public final float maxX;
|
||||
public final float maxY;
|
||||
public final float maxZ;
|
||||
public final float radius;
|
||||
|
||||
public MeshBounds(ResultSet rs) throws SQLException {
|
||||
|
||||
meshID = rs.getInt("meshID");
|
||||
minX = rs.getFloat("minX");
|
||||
minY = rs.getFloat("minY");
|
||||
minZ = rs.getFloat("minZ");
|
||||
maxX = rs.getFloat("maxX");
|
||||
maxY = rs.getFloat("maxY");
|
||||
maxZ = rs.getFloat("maxZ");
|
||||
float radiusX = (int) maxX;
|
||||
float radiusZ = (int) maxZ;
|
||||
|
||||
radius = Math.max(radiusX,radiusZ);
|
||||
}
|
||||
|
||||
public static void InitializeBuildingBounds(){
|
||||
Bounds.meshBoundsCache = DbManager.BuildingQueries.LOAD_MESH_BOUNDS();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,791 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.db.archive.DataWarehouse;
|
||||
import engine.db.archive.MineRecord;
|
||||
import engine.gameManager.*;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.session.SessionID;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static engine.gameManager.DbManager.MineQueries;
|
||||
import static engine.gameManager.DbManager.getObject;
|
||||
import static engine.math.FastMath.sqr;
|
||||
|
||||
public class Mine extends AbstractGameObject {
|
||||
|
||||
private String zoneName;
|
||||
private Resource production;
|
||||
private boolean isActive = false;
|
||||
private float latitude;
|
||||
private float longitude;
|
||||
private float altitude;
|
||||
private Guild owningGuild;
|
||||
private int lastClaimerID;
|
||||
private SessionID lastClaimerSessionID;
|
||||
private int flags;
|
||||
private int buildingID;
|
||||
private Zone parentZone;
|
||||
private MineProduction mineType;
|
||||
public LocalDateTime openDate;
|
||||
|
||||
public boolean dirtyMine = false;
|
||||
//flags 1: never been claimed (make active).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Not persisted to DB
|
||||
private String guildName;
|
||||
private GuildTag guildTag;
|
||||
private String nationName;
|
||||
private GuildTag nationTag;
|
||||
public static ConcurrentHashMap<Mine, Integer> mineMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
public static ConcurrentHashMap<Integer, Mine> towerMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
private static long lastChange = System.currentTimeMillis();
|
||||
public static LocalDateTime effectiveMineDate;
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public Mine(ResultSet rs) throws SQLException, UnknownHostException {
|
||||
super(rs);
|
||||
|
||||
this.mineType = MineProduction.getByName(rs.getString("mine_type"));
|
||||
|
||||
float offsetX = rs.getFloat("mine_offsetX");
|
||||
float offsetZ = rs.getFloat("mine_offsetZ");
|
||||
int ownerUID = rs.getInt("mine_ownerUID");
|
||||
this.buildingID = rs.getInt("mine_buildingUID");
|
||||
this.flags = rs.getInt("flags");
|
||||
int parent = rs.getInt("parent");
|
||||
this.parentZone = ZoneManager.getZoneByUUID(parent);
|
||||
if (parentZone != null) {
|
||||
this.latitude = parentZone.getLoc().x + offsetX;
|
||||
this.longitude = parentZone.getLoc().z + offsetZ;
|
||||
this.altitude = parentZone.getLoc().y;
|
||||
if (this.parentZone.getParent() != null)
|
||||
this.zoneName = this.parentZone.getParent().getName();
|
||||
else
|
||||
this.zoneName = this.parentZone.getName();
|
||||
} else {
|
||||
Logger.error( "Missing parentZone of ID " + parent);
|
||||
this.latitude = -1000;
|
||||
this.longitude = 1000;
|
||||
this.altitude = 0;
|
||||
this.zoneName = "Unknown Mine";
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.owningGuild = Guild.getGuild(ownerUID);
|
||||
Guild nation = null;
|
||||
if (this.owningGuild != null && !this.owningGuild.isErrant()) {
|
||||
this.guildName = this.owningGuild.getName();
|
||||
this.guildTag = this.owningGuild.getGuildTag();
|
||||
nation = this.owningGuild.getNation();
|
||||
} else {
|
||||
this.guildName = "";
|
||||
this.guildTag = GuildTag.ERRANT;
|
||||
nation = Guild.getErrantGuild();
|
||||
this.owningGuild = Guild.getErrantGuild();
|
||||
}
|
||||
|
||||
int mineTime = this.owningGuild.getMineTime();
|
||||
|
||||
if(!nation.isErrant()) {
|
||||
this.nationName = nation.getName();
|
||||
this.nationTag = nation.getGuildTag();
|
||||
mineTime = nation.getMineTime();
|
||||
} else {
|
||||
this.nationName = "";
|
||||
this.nationTag = GuildTag.ERRANT;
|
||||
|
||||
}
|
||||
this.setActive(false);
|
||||
this.production = Resource.valueOf(rs.getString("mine_resource"));
|
||||
|
||||
this.lastClaimerID = 0;
|
||||
this.lastClaimerSessionID = null;
|
||||
|
||||
java.sql.Timestamp mineTimeStamp = rs.getTimestamp("mine_openDate");
|
||||
|
||||
|
||||
Building building = BuildingManager.getBuildingFromCache(this.buildingID);
|
||||
|
||||
|
||||
if (mineTimeStamp == null && (this.owningGuild == null || this.owningGuild.isErrant() || building.getRank() < 1)){
|
||||
if (building != null){
|
||||
String zoneName = building.getParentZone().getName();
|
||||
String parentZoneName = building.getParentZone().getParent().getName();
|
||||
Logger.info(zoneName + " in " + parentZoneName + " has a dirty mine, setting active.");
|
||||
}
|
||||
this.dirtyMine = true;
|
||||
openDate = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0);
|
||||
return;
|
||||
}else if (this.owningGuild.isErrant() || nation.isErrant()){
|
||||
openDate = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0);
|
||||
return;
|
||||
}else if (mineTimeStamp == null){
|
||||
|
||||
this.openDate = LocalDateTime.now().withHour(mineTime).withMinute(0).withSecond(0).withNano(0);
|
||||
|
||||
if (LocalDateTime.now().isAfter(this.openDate.plusHours(1)))
|
||||
this.openDate = this.openDate.plusDays(1);
|
||||
return;
|
||||
}else{
|
||||
this.openDate = mineTimeStamp.toLocalDateTime().withHour(mineTime);
|
||||
|
||||
if (LocalDateTime.now().isAfter(this.openDate.plusHours(1))){
|
||||
this.openDate = this.openDate.plusDays(1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//after 1 day...
|
||||
if(this.openDate.getDayOfYear() - LocalDateTime.now().getDayOfYear() > 1){
|
||||
this.openDate = this.openDate.withDayOfYear(LocalDateTime.now().getDayOfYear());
|
||||
if (LocalDateTime.now().isAfter(this.openDate.plusHours(1)))
|
||||
this.openDate = this.openDate.plusDays(1);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void SendMineAttackMessage(Building mine){
|
||||
|
||||
if (mine.getBlueprint() == null)
|
||||
return;
|
||||
|
||||
if (mine.getBlueprint().getBuildingGroup() != Enum.BuildingGroup.MINE)
|
||||
return;
|
||||
|
||||
|
||||
if (mine.getGuild().isErrant())
|
||||
return;
|
||||
|
||||
if (mine.getGuild().getNation().isErrant())
|
||||
return;
|
||||
|
||||
if (mine.getTimeStamp("MineAttack") > System.currentTimeMillis())
|
||||
return;
|
||||
|
||||
mine.getTimestamps().put("MineAttack", System.currentTimeMillis() + MBServerStatics.ONE_MINUTE);
|
||||
|
||||
ChatManager.chatNationInfo(mine.getGuild().getNation(), mine.getName() + " in " + mine.getParentZone().getParent().getName() + " is Under attack!");
|
||||
}
|
||||
|
||||
private void setNextMineWindow() {
|
||||
|
||||
//default time, 9 pm est
|
||||
int mineHour = 21;
|
||||
|
||||
if (this.owningGuild != null || this.owningGuild.isErrant() == false)
|
||||
mineHour = this.owningGuild.getNation().getMineTime();
|
||||
int days = 1;
|
||||
|
||||
//midnight hours
|
||||
if (this.openDate.getHour() != 0 && this.openDate.getHour() != 24 && (this.openDate.getDayOfMonth() == LocalDateTime.now().getDayOfMonth()))
|
||||
if (mineHour == 0 || mineHour == 24)
|
||||
days = 2;
|
||||
|
||||
LocalDateTime newTime = this.openDate.plusDays(days).withHour(mineHour).withMinute(0).withSecond(0).withNano(0);
|
||||
|
||||
DbManager.MineQueries.CHANGE_MINE_TIME(this, newTime);
|
||||
this.openDate = newTime;
|
||||
}
|
||||
|
||||
public static void loadAllMines() {
|
||||
|
||||
// Set current mine effective date
|
||||
try{
|
||||
|
||||
|
||||
effectiveMineDate = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
|
||||
|
||||
//Load mine resources
|
||||
MineProduction.addResources();
|
||||
|
||||
//pre-load all building sets
|
||||
ArrayList<Mine> serverMines = MineQueries.GET_ALL_MINES_FOR_SERVER();
|
||||
|
||||
for (Mine mine : serverMines) {
|
||||
Mine.mineMap.put(mine, mine.buildingID);
|
||||
Mine.towerMap.put(mine.buildingID, mine);
|
||||
mine.initializeMineTime();
|
||||
}
|
||||
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
private void initializeMineTime(){
|
||||
|
||||
//Mine time has already been set at loading from the database. skip.
|
||||
|
||||
if (this.openDate != null)
|
||||
return;
|
||||
|
||||
Guild nation = null;
|
||||
|
||||
if (this.owningGuild != null)
|
||||
nation = this.owningGuild.getNation();
|
||||
|
||||
int mineTime = (nation != null && !nation.isErrant()) ? nation.getMineTime() : MBServerStatics.MINE_EARLY_WINDOW;
|
||||
|
||||
LocalDateTime openDate = LocalDateTime.now().withHour(mineTime).withMinute(0).withSecond(0).withNano(0);
|
||||
|
||||
//Failed to Update Database, default mine time.
|
||||
|
||||
if (!MineQueries.CHANGE_MINE_TIME(this, openDate)){
|
||||
Logger.info("Mine with UUID " + this.getObjectUUID() + " failed to set Mine Window. Defaulting to Earliest.");
|
||||
openDate = openDate.withHour(MBServerStatics.MINE_EARLY_WINDOW).withMinute(0).withSecond(0).withNano(0);
|
||||
this.openDate = openDate;
|
||||
return;
|
||||
}
|
||||
|
||||
this.openDate = openDate;
|
||||
|
||||
}
|
||||
|
||||
public boolean changeProductionType(Resource resource){
|
||||
if (!this.validForMine(resource))
|
||||
return false;
|
||||
//update resource in database;
|
||||
if(!MineQueries.CHANGE_RESOURCE(this, resource))
|
||||
return false;
|
||||
|
||||
this.production = resource;
|
||||
return true;
|
||||
}
|
||||
|
||||
public MineProduction getMineType() {
|
||||
return this.mineType;
|
||||
}
|
||||
|
||||
public String getZoneName() {
|
||||
return this.zoneName;
|
||||
}
|
||||
|
||||
public Resource getProduction() {
|
||||
return this.production;
|
||||
}
|
||||
|
||||
public boolean getIsActive() {
|
||||
return this.isActive;
|
||||
}
|
||||
|
||||
public float getAltitude() {
|
||||
return this.altitude;
|
||||
}
|
||||
|
||||
public Guild getOwningGuild() {
|
||||
return this.owningGuild;
|
||||
}
|
||||
|
||||
public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public void setFlags(int flags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
public Zone getParentZone() {
|
||||
return parentZone;
|
||||
}
|
||||
|
||||
public GuildTag getGuildTag() {
|
||||
return guildTag;
|
||||
}
|
||||
|
||||
public void setMineType(String type) {
|
||||
this.mineType = MineProduction.getByName(type);
|
||||
}
|
||||
|
||||
public void setActive(boolean isAc) {
|
||||
|
||||
this.isActive = isAc;
|
||||
Building building = BuildingManager.getBuildingFromCache(this.buildingID);
|
||||
if (building != null && !this.isActive)
|
||||
building.isDeranking.compareAndSet(true, false);
|
||||
}
|
||||
|
||||
public void setOwningGuild(Guild owningGuild) {
|
||||
this.owningGuild = owningGuild;
|
||||
}
|
||||
|
||||
public static Mine getMineFromTower(int towerID) {
|
||||
return Mine.towerMap.get(towerID);
|
||||
}
|
||||
|
||||
public boolean validForMine(Resource r) {
|
||||
if (this.mineType == null)
|
||||
return false;
|
||||
return this.mineType.validForMine(r, this.isExpansion());
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialization
|
||||
*/
|
||||
|
||||
public static void serializeForClientMsg(Mine mine,ByteBufferWriter writer) {
|
||||
writer.putInt(mine.getObjectType().ordinal());
|
||||
writer.putInt(mine.getObjectUUID());
|
||||
writer.putInt(mine.getObjectUUID()); //actually a hash of mine
|
||||
// writer.putInt(0x215C92BB); //this.unknown1);
|
||||
writer.putString(mine.mineType.name);
|
||||
writer.putString(mine.zoneName);
|
||||
writer.putInt(mine.production.hash);
|
||||
writer.putInt(mine.production.baseProduction);
|
||||
writer.putInt(mine.getModifiedProductionAmount()); //TODO calculate range penalty here
|
||||
writer.putInt(3600); //window in seconds
|
||||
|
||||
LocalDateTime mw = mine.openDate;
|
||||
|
||||
writer.putLocalDateTime(mw);
|
||||
mw = mw.plusHours(1);
|
||||
writer.putLocalDateTime(mw);
|
||||
writer.put(mine.isActive ? (byte) 0x01 : (byte) 0x00);
|
||||
|
||||
writer.putFloat(mine.latitude);
|
||||
writer.putFloat(mine.altitude);
|
||||
writer.putFloat(mine.longitude);
|
||||
writer.putInt(mine.isExpansion() ? mine.mineType.xpacHash : mine.mineType.hash);
|
||||
|
||||
writer.putString(mine.guildName);
|
||||
GuildTag._serializeForDisplay(mine.guildTag,writer);
|
||||
writer.putString(mine.nationName);
|
||||
GuildTag._serializeForDisplay(mine.nationTag,writer);
|
||||
}
|
||||
|
||||
public void serializeForMineProduction(ByteBufferWriter writer) {
|
||||
writer.putInt(this.getObjectType().ordinal());
|
||||
writer.putInt(this.getObjectUUID());
|
||||
writer.putInt(this.getObjectUUID()); //actually a hash of mine
|
||||
// writer.putInt(0x215C92BB); //this.unknown1);
|
||||
writer.putString(this.mineType.name);
|
||||
writer.putString(this.zoneName);
|
||||
writer.putInt(this.production.hash);
|
||||
writer.putInt(this.production.baseProduction);
|
||||
writer.putInt(this.getModifiedProductionAmount()); //TODO calculate range penalty here
|
||||
writer.putInt(3600); //window in seconds
|
||||
writer.putInt(this.isExpansion() ? this.mineType.xpacHash : this.mineType.hash);
|
||||
}
|
||||
|
||||
public static ArrayList<Mine> getMinesForGuild(int guildID) {
|
||||
ArrayList<Mine> mineList = new ArrayList<>();
|
||||
for (Mine mine : Mine.mineMap.keySet()) {
|
||||
if (mine.owningGuild != null && mine.owningGuild.getObjectUUID() == guildID)
|
||||
mineList.add(mine);
|
||||
}
|
||||
return mineList;
|
||||
}
|
||||
|
||||
public static long getLastChange() {
|
||||
return lastChange;
|
||||
}
|
||||
|
||||
public static void setLastChange(long lastChange) {
|
||||
Mine.lastChange = lastChange;
|
||||
}
|
||||
|
||||
/*
|
||||
* Database
|
||||
*/
|
||||
public static Mine getMine(int UID){
|
||||
return MineQueries.GET_MINE(UID);
|
||||
|
||||
}
|
||||
|
||||
public static ArrayList<Mine> getMines() {
|
||||
return new ArrayList<>(mineMap.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Create update logic.
|
||||
}
|
||||
|
||||
public int getBuildingID() {
|
||||
return buildingID;
|
||||
}
|
||||
|
||||
public void setBuildingID(int buildingID) {
|
||||
this.buildingID = buildingID;
|
||||
}
|
||||
|
||||
public void handleStartMineWindow() {
|
||||
|
||||
// Do not open errant mines until after woo
|
||||
|
||||
// if ((this.getOwningGuild() == null) &&
|
||||
// (this.getOpenDate().isAfter(DateTime.now())))
|
||||
// return;
|
||||
|
||||
this.lastClaimerID = 0;
|
||||
this.setActive(true);
|
||||
ChatManager.chatSystemChannel(this.zoneName + "'s Mine is now Active!");
|
||||
Logger.info(this.zoneName + "'s Mine is now Active!");
|
||||
}
|
||||
|
||||
public static boolean validClaimer(PlayerCharacter pc) {
|
||||
//verify the player exists
|
||||
if (pc == null)
|
||||
return false;
|
||||
|
||||
//verify the player is in valid guild
|
||||
Guild g = pc.getGuild();
|
||||
if (g == null) {
|
||||
ChatManager.chatSystemError(pc, "Mine can only be claimed by a guild.");
|
||||
return false;
|
||||
} else if (g.isErrant()) {
|
||||
ChatManager.chatSystemError(pc, "Guild cannot be Errant to claim..");
|
||||
return false;
|
||||
}
|
||||
|
||||
//verify the player is in nation
|
||||
Guild n = g.getNation();
|
||||
if (n.isErrant()) {
|
||||
ChatManager.chatSystemError(pc, "Must have a Nation");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (SessionManager.getPlayerCharacterByID(pc.getObjectUUID()) == null){
|
||||
return false;
|
||||
}
|
||||
//Get a count of nation mines, can't go over capital tol rank.
|
||||
City capital = n.getOwnedCity();
|
||||
City guildCity = g.getOwnedCity();
|
||||
if (guildCity == null){
|
||||
ChatManager.chatSystemError(pc, "Guild must own city to claim.");
|
||||
return false;
|
||||
}
|
||||
if (capital == null) {
|
||||
ChatManager.chatSystemError(pc, "Guild must own city to claim.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (guildCity.getWarehouse() == null){
|
||||
ChatManager.chatSystemError(pc, "City must own warehouse for to claim.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Building tol = capital.getTOL();
|
||||
|
||||
if (tol == null) {
|
||||
ChatManager.chatSystemError(pc, "Tree of life not found for city.");
|
||||
return false;
|
||||
}
|
||||
|
||||
int rank = tol.getRank();
|
||||
|
||||
if (rank < 1) {
|
||||
ChatManager.chatSystemError(pc, "Tree of life is not yet sprouted.");
|
||||
return false;
|
||||
}
|
||||
|
||||
int mineCnt = 0;
|
||||
|
||||
mineCnt += Mine.getMinesForGuild(n.getObjectUUID()).size();
|
||||
for (Guild guild: n.getSubGuildList()){
|
||||
mineCnt += Mine.getMinesForGuild(guild.getObjectUUID()).size();
|
||||
}
|
||||
|
||||
|
||||
if (mineCnt > rank) {
|
||||
ChatManager.chatSystemError(pc, "Your Nation can only hold " + tol.getRank() + " mines. Your Nation already has" + mineCnt);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public void handleDestroyMine() {
|
||||
|
||||
if (!this.isActive)
|
||||
return;
|
||||
|
||||
//remove tags from mine
|
||||
|
||||
this.guildName = "";
|
||||
this.nationName = "";
|
||||
this.owningGuild = null;
|
||||
Mine.setLastChange(System.currentTimeMillis());
|
||||
|
||||
// remove hirelings
|
||||
|
||||
Building building = (Building) getObject(Enum.GameObjectType.Building, this.buildingID);
|
||||
BuildingManager.cleanupHirelings(building);
|
||||
}
|
||||
|
||||
public boolean handleEndMineWindow(){
|
||||
|
||||
Building mineBuilding = BuildingManager.getBuildingFromCache(this.buildingID);
|
||||
|
||||
if (mineBuilding == null){
|
||||
Logger.debug( "Failed to Activate Mine with UID " + this.getObjectUUID() +". Unable to Load Building with UID " +this.buildingID);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mineBuilding.getRank() > 0) {
|
||||
//never knocked down, let's just move on.
|
||||
//hasn't been claimed since server start.
|
||||
if (this.dirtyMine && this.lastClaimerID == 0 && (this.owningGuild == null || this.owningGuild.isErrant()))
|
||||
return false;
|
||||
this.setActive(false);
|
||||
setNextMineWindow();
|
||||
return true;
|
||||
}
|
||||
|
||||
PlayerCharacter claimer = PlayerCharacter.getFromCache(this.lastClaimerID);
|
||||
|
||||
if (!validClaimer(claimer)){
|
||||
LocalDateTime resetTime = LocalDateTime.now().withDayOfMonth(LocalDateTime.now().getDayOfMonth()).withHour(LocalDateTime.now().getHour()).withMinute(0).withSecond(0).withNano(0);
|
||||
this.openDate = resetTime;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// //verify the player hasn't logged out since claim
|
||||
|
||||
// if (SessionManager.getSession(claimer) == null)
|
||||
// return false;
|
||||
// if (!SessionManager.getSession(claimer).getSessionID().equals(this.lastClaimerSessionID))
|
||||
// return false;
|
||||
|
||||
if (this.owningGuild == null || this.owningGuild.isErrant() || this.owningGuild.getNation().isErrant()){
|
||||
LocalDateTime resetTime = LocalDateTime.now().withDayOfMonth(LocalDateTime.now().getDayOfMonth()).withHour(LocalDateTime.now().getHour()).withMinute(0).withSecond(0).withNano(0);
|
||||
this.openDate = resetTime;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//Update ownership to map
|
||||
|
||||
this.guildName = this.owningGuild.getName();
|
||||
this.guildTag = this.owningGuild.getGuildTag();
|
||||
Guild nation = this.owningGuild.getNation();
|
||||
this.nationName = nation.getName();
|
||||
this.nationTag = nation.getGuildTag();
|
||||
|
||||
LocalDateTime guildDate = LocalDateTime.now().withHour(this.owningGuild.getMineTime()).withMinute(0).withSecond(0).withNano(0);
|
||||
|
||||
if (this.openDate.getDayOfMonth() == LocalDateTime.now().getDayOfMonth())
|
||||
if (this.owningGuild.getMineTime() == 0 || this.owningGuild.getMineTime() == 24)
|
||||
guildDate = guildDate.plusDays(1);
|
||||
|
||||
guildDate = guildDate.withHour(this.owningGuild.getMineTime()).withMinute(0).withSecond(0).withNano(0);
|
||||
this.openDate = guildDate;
|
||||
Mine.setLastChange(System.currentTimeMillis());
|
||||
|
||||
if (mineBuilding.getRank() < 1){
|
||||
|
||||
if (claimer == null){
|
||||
this.lastClaimerID = 0;
|
||||
updateGuildOwner(null);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.dirtyMine = false;
|
||||
|
||||
mineBuilding.rebuildMine();
|
||||
WorldGrid.updateObject(mineBuilding);
|
||||
ChatManager.chatSystemChannel(claimer.getName() + " has claimed the mine in " + this.parentZone.getParent().getName() + " for " + this.owningGuild.getName() + ". The mine is no longer active.");
|
||||
|
||||
// Warehouse this claim event
|
||||
|
||||
MineRecord mineRecord = MineRecord.borrow(this, claimer, Enum.RecordEventType.CAPTURE);
|
||||
DataWarehouse.pushToWarehouse(mineRecord);
|
||||
|
||||
}else{
|
||||
mineBuilding.setRank(mineBuilding.getRank());
|
||||
}
|
||||
|
||||
this.setActive(false);
|
||||
setNextMineWindow();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean claimMine(PlayerCharacter claimer){
|
||||
|
||||
if (claimer == null)
|
||||
return false;
|
||||
|
||||
if (!validClaimer(claimer))
|
||||
return false;
|
||||
|
||||
if (!this.isActive) {
|
||||
ErrorPopupMsg.sendErrorMsg(claimer, "Can not for to claim inactive mine.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!updateGuildOwner(claimer))
|
||||
return false;
|
||||
|
||||
this.lastClaimerID = claimer.getObjectUUID();
|
||||
Mine.setLastChange(System.currentTimeMillis());
|
||||
return true;
|
||||
}
|
||||
public boolean depositMineResources(){
|
||||
|
||||
if (this.owningGuild == null)
|
||||
return false;
|
||||
|
||||
if (this.owningGuild.getOwnedCity() == null)
|
||||
return false;
|
||||
|
||||
if (this.owningGuild.getOwnedCity().getWarehouse() == null)
|
||||
return false;
|
||||
|
||||
ItemBase resourceIB = ItemBase.getItemBase(this.production.UUID);
|
||||
return this.owningGuild.getOwnedCity().getWarehouse().depositFromMine(this,resourceIB, this.getModifiedProductionAmount());
|
||||
}
|
||||
|
||||
public boolean updateGuildOwner(PlayerCharacter pc){
|
||||
|
||||
Building mineBuilding = BuildingManager.getBuildingFromCache(this.buildingID);
|
||||
|
||||
//should never return null, but let's check just in case.
|
||||
|
||||
if (mineBuilding == null){
|
||||
ChatManager.chatSystemError(pc, "Unable to find mine tower.");
|
||||
Logger.debug("Failed to Update Mine with UID " + this.getObjectUUID() +". Unable to Load Building with UID " +this.buildingID );
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pc == null) {
|
||||
this.owningGuild = null;
|
||||
this.guildName = "None";
|
||||
this.guildTag = GuildTag.ERRANT;
|
||||
this.nationName = "None";
|
||||
this.nationTag = GuildTag.ERRANT;
|
||||
//Update Building.
|
||||
mineBuilding.setOwner(null);
|
||||
WorldGrid.updateObject(mineBuilding);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SessionManager.getSession(pc) != null) {
|
||||
this.lastClaimerSessionID = SessionManager.getSession(pc).getSessionID();
|
||||
} else {
|
||||
Logger.error("Failed to find session for player " + pc.getObjectUUID());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Guild guild = pc.getGuild();
|
||||
|
||||
if (guild.getOwnedCity() == null)
|
||||
return false;
|
||||
|
||||
if (!MineQueries.CHANGE_OWNER(this, guild.getObjectUUID())) {
|
||||
Logger.debug("Database failed to Change Ownership of Mine with UID " + this.getObjectUUID());
|
||||
ChatManager.chatSystemError(pc, "Failed to claim Mine.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//All tests passed.
|
||||
|
||||
//update mine.
|
||||
this.owningGuild = guild;
|
||||
// this.guildName = this.owningGuild.getName();
|
||||
// this.guildTag = this.owningGuild.getGuildTag();
|
||||
//
|
||||
// //nation will never return null, read getNation()
|
||||
// Guild nation = this.owningGuild.getNation();
|
||||
// this.nationName = nation.getName();
|
||||
// this.nationTag = nation.getGuildTag();
|
||||
|
||||
//Update Building.
|
||||
PlayerCharacter guildLeader = (PlayerCharacter) Guild.GetGL(this.owningGuild);
|
||||
if (guildLeader != null)
|
||||
mineBuilding.setOwner(guildLeader);
|
||||
WorldGrid.updateObject(mineBuilding);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isExpansion(){
|
||||
return (this.flags & 2) != 0;
|
||||
}
|
||||
|
||||
public int getModifiedProductionAmount(){
|
||||
//TODO Calculate Distance modifications.
|
||||
|
||||
//calculate base values.
|
||||
int baseProduction = this.production.baseProduction;
|
||||
float baseModValue = this.production.baseProduction * .1f;
|
||||
float rankModValue = this.production.baseProduction * .0143f;
|
||||
float totalModded = 0;
|
||||
|
||||
//get Mine Building.
|
||||
Building mineBuilding = BuildingManager.getBuilding(this.buildingID);
|
||||
if (mineBuilding == null)
|
||||
return this.production.baseProduction;
|
||||
for (AbstractCharacter harvester:mineBuilding.getHirelings().keySet()){
|
||||
totalModded += baseModValue;
|
||||
totalModded += rankModValue * harvester.getRank();
|
||||
}
|
||||
//add base production on top;
|
||||
totalModded += baseProduction;
|
||||
//skip distance check for expansion.
|
||||
if (this.isExpansion())
|
||||
return (int) totalModded;
|
||||
|
||||
if (this.owningGuild != null){
|
||||
if(this.owningGuild.getOwnedCity() != null){
|
||||
float distanceSquared = this.owningGuild.getOwnedCity().getLoc().distanceSquared2D(mineBuilding.getLoc());
|
||||
|
||||
if (distanceSquared > sqr(10000 * 3))
|
||||
totalModded *=.25f;
|
||||
else if (distanceSquared > sqr(10000 * 2))
|
||||
totalModded *= .50f;
|
||||
else if (distanceSquared > sqr(10000))
|
||||
totalModded *= .75f;
|
||||
}
|
||||
}
|
||||
return (int) totalModded;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public enum MineProduction {
|
||||
|
||||
LUMBER("Lumber Camp", new HashMap<>(), Resource.WORMWOOD, 1618637196, 1663491950),
|
||||
ORE("Ore Mine", new HashMap<>(), Resource.OBSIDIAN, 518103023, -788976428),
|
||||
GOLD("Gold Mine", new HashMap<>(), Resource.GALVOR, -662193002, -1227205358),
|
||||
MAGIC("Magic Mine", new HashMap<>(), Resource.BLOODSTONE, 504746863, -1753567069);
|
||||
|
||||
public final String name;
|
||||
public final HashMap<Integer, Resource> resources;
|
||||
public final Resource xpac;
|
||||
public final int hash;
|
||||
public final int xpacHash;
|
||||
|
||||
MineProduction(String name, HashMap<Integer, Resource>resources, Resource xpac, int hash, int xpacHash) {
|
||||
this.name = name;
|
||||
this.resources = resources;
|
||||
this.xpac = xpac;
|
||||
this.hash = hash;
|
||||
this.xpacHash = xpacHash;
|
||||
}
|
||||
|
||||
public static void addResources() {
|
||||
if (MineProduction.LUMBER.resources.size() == 0) {
|
||||
MineProduction.LUMBER.resources.put(7, Resource.GOLD);
|
||||
MineProduction.LUMBER.resources.put(1580004, Resource.LUMBER);
|
||||
MineProduction.LUMBER.resources.put(1580005, Resource.OAK);
|
||||
MineProduction.LUMBER.resources.put(1580006, Resource.BRONZEWOOD);
|
||||
MineProduction.LUMBER.resources.put(1580007, Resource.MANDRAKE);
|
||||
}
|
||||
if (MineProduction.ORE.resources.size() == 0) {
|
||||
MineProduction.ORE.resources.put(7, Resource.GOLD);
|
||||
MineProduction.ORE.resources.put(1580000, Resource.STONE);
|
||||
MineProduction.ORE.resources.put(1580001, Resource.TRUESTEEL);
|
||||
MineProduction.ORE.resources.put(1580002, Resource.IRON);
|
||||
MineProduction.ORE.resources.put(1580003, Resource.ADAMANT);
|
||||
}
|
||||
if (MineProduction.GOLD.resources.size() == 0) {
|
||||
MineProduction.GOLD.resources.put(7, Resource.GOLD);
|
||||
MineProduction.GOLD.resources.put(1580000, Resource.STONE);
|
||||
MineProduction.GOLD.resources.put(1580008, Resource.COAL);
|
||||
MineProduction.GOLD.resources.put(1580009, Resource.AGATE);
|
||||
MineProduction.GOLD.resources.put(1580010, Resource.DIAMOND);
|
||||
MineProduction.GOLD.resources.put(1580011, Resource.ONYX);
|
||||
}
|
||||
if (MineProduction.MAGIC.resources.size() == 0) {
|
||||
MineProduction.MAGIC.resources.put(7, Resource.GOLD);
|
||||
MineProduction.MAGIC.resources.put(1580012, Resource.AZOTH);
|
||||
MineProduction.MAGIC.resources.put(1580013, Resource.ORICHALK);
|
||||
MineProduction.MAGIC.resources.put(1580014, Resource.ANTIMONY);
|
||||
MineProduction.MAGIC.resources.put(1580015, Resource.SULFUR);
|
||||
MineProduction.MAGIC.resources.put(1580016, Resource.QUICKSILVER);
|
||||
}
|
||||
}
|
||||
|
||||
public static MineProduction getByName(String name) {
|
||||
if (name.toLowerCase().equals("lumber"))
|
||||
return MineProduction.LUMBER;
|
||||
else if (name.toLowerCase().equals("ore"))
|
||||
return MineProduction.ORE;
|
||||
else if (name.toLowerCase().equals("gold"))
|
||||
return MineProduction.GOLD;
|
||||
else
|
||||
return MineProduction.MAGIC;
|
||||
}
|
||||
|
||||
public boolean validForMine(Resource r, boolean isXpac) {
|
||||
if (r == null)
|
||||
return false;
|
||||
if (this.resources.containsKey(r.UUID))
|
||||
return true;
|
||||
else return isXpac && r.UUID == this.xpac.UUID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Name Xpac Resources
|
||||
//Lumber Camp Wormwood Gold, Lumber, Oak, Bronzewood, Mandrake
|
||||
//Ore Mine Obsidian Gold, Stone, Truesteal, Iron, Adamant
|
||||
//Gold Mine Galvor Gold, Coal, Agate, Diamond, Onyx
|
||||
//Magic Mine Bloodstone Gold, Orichalk, Azoth, Antimony, Quicksilver, Sulfer
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,396 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import ch.claude_martin.enumbitset.EnumBitSet;
|
||||
import engine.Enum;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class MobBase extends AbstractGameObject {
|
||||
|
||||
private final int loadID;
|
||||
private final String firstName;
|
||||
private final byte level;
|
||||
private float healthMax;
|
||||
private int attackRating;
|
||||
private int defenseRating;
|
||||
private float damageMin;
|
||||
private float damageMax;
|
||||
private float hitBoxRadius;
|
||||
private final int lootTable;
|
||||
private final float scale;
|
||||
|
||||
private int minGold;
|
||||
private int maxGold;
|
||||
|
||||
private EnumBitSet<Enum.MobFlagType> flags;
|
||||
private EnumBitSet<Enum.AggroType> noAggro;
|
||||
private int mask;
|
||||
|
||||
private int goldMod;
|
||||
private int seeInvis;
|
||||
private int spawnTime = 0;
|
||||
private int defense = 0;
|
||||
private int atr = 0;
|
||||
private float minDmg = 0;
|
||||
private float maxDmg = 0;
|
||||
private ArrayList<MobBaseEffects> raceEffectsList;
|
||||
private float attackRange;
|
||||
private boolean isNecroPet = false;
|
||||
|
||||
private MobBaseStats mobBaseStats;
|
||||
private ArrayList<RuneBase> runes;
|
||||
private HashMap<Integer, Integer> staticPowers;
|
||||
|
||||
private float walk = 0;
|
||||
private float run = 0;
|
||||
private float walkCombat = 0;
|
||||
private float runCombat = 0;
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public MobBase(ResultSet rs) throws SQLException {
|
||||
super(rs, rs.getInt("ID"));
|
||||
|
||||
this.loadID = rs.getInt("loadID");
|
||||
|
||||
this.firstName = rs.getString("name");
|
||||
this.level = rs.getByte("level");
|
||||
this.lootTable = rs.getInt("lootTableID");
|
||||
|
||||
this.goldMod = rs.getInt("goldMod");
|
||||
this.spawnTime = rs.getInt("spawnTime");
|
||||
|
||||
LevelDefault levelDefault = LevelDefault.getLevelDefault(this.level);
|
||||
this.healthMax = rs.getInt("health");
|
||||
this.damageMin = rs.getFloat("minDmg");
|
||||
this.damageMax = rs.getFloat("maxDmg");
|
||||
|
||||
this.attackRating = rs.getInt("atr");
|
||||
this.defenseRating = rs.getInt("defense");
|
||||
this.attackRange = rs.getFloat("attackRange");
|
||||
|
||||
if (MobbaseGoldEntry.MobbaseGoldMap.containsKey(this.loadID)){
|
||||
MobbaseGoldEntry goldEntry = MobbaseGoldEntry.MobbaseGoldMap.get(this.loadID);
|
||||
|
||||
if (goldEntry != null){
|
||||
this.minGold = goldEntry.getMin();
|
||||
this.maxGold = goldEntry.getMax();
|
||||
}
|
||||
}
|
||||
else
|
||||
if (levelDefault != null) {
|
||||
this.minGold = (levelDefault.goldMin * this.goldMod / 100);
|
||||
this.maxGold = (levelDefault.goldMax * this.goldMod / 100);
|
||||
} else {
|
||||
this.minGold = 10;
|
||||
this.maxGold = 30;
|
||||
}
|
||||
|
||||
this.flags = EnumBitSet.asEnumBitSet(rs.getLong("flags"), Enum.MobFlagType.class);
|
||||
this.noAggro = EnumBitSet.asEnumBitSet(rs.getLong("noaggro"), Enum.AggroType.class);
|
||||
|
||||
this.seeInvis = rs.getInt("seeInvis");
|
||||
this.scale = rs.getFloat("scale");
|
||||
this.hitBoxRadius = 5f;
|
||||
this.mask = 0;
|
||||
|
||||
if (this.getObjectUUID() == 12021 || this.getObjectUUID() == 12022) {
|
||||
this.isNecroPet = true;
|
||||
}
|
||||
|
||||
if (Enum.MobFlagType.HUMANOID.elementOf(this.flags))
|
||||
this.mask += MBServerStatics.MASK_HUMANOID;
|
||||
|
||||
if (Enum.MobFlagType.UNDEAD.elementOf(this.flags))
|
||||
this.mask += MBServerStatics.MASK_UNDEAD;
|
||||
|
||||
if (Enum.MobFlagType.BEAST.elementOf(this.flags))
|
||||
this.mask += MBServerStatics.MASK_BEAST;
|
||||
|
||||
if (Enum.MobFlagType.DRAGON.elementOf(this.flags))
|
||||
this.mask += MBServerStatics.MASK_DRAGON;
|
||||
|
||||
if (Enum.MobFlagType.RAT.elementOf(this.flags))
|
||||
this.mask += MBServerStatics.MASK_RAT;
|
||||
|
||||
this.runes = DbManager.MobBaseQueries.LOAD_RUNES_FOR_MOBBASE(this.loadID);
|
||||
this.raceEffectsList = DbManager.MobBaseQueries.LOAD_STATIC_EFFECTS(this.loadID);
|
||||
this.mobBaseStats = DbManager.MobBaseQueries.LOAD_STATS(this.loadID);
|
||||
DbManager.MobBaseQueries.LOAD_ALL_MOBBASE_LOOT(this.loadID);
|
||||
DbManager.MobBaseQueries.LOAD_ALL_MOBBASE_SPEEDS(this);
|
||||
|
||||
}
|
||||
|
||||
public static HashMap<Integer, MobEquipment> loadEquipmentSet(int equipmentSetID){
|
||||
|
||||
ArrayList<EquipmentSetEntry> equipList;
|
||||
HashMap<Integer, MobEquipment> equip = new HashMap<>();
|
||||
|
||||
if (equipmentSetID == 0)
|
||||
return equip;
|
||||
|
||||
equipList = EquipmentSetEntry.EquipmentSetMap.get(equipmentSetID);
|
||||
|
||||
if (equipList == null)
|
||||
return equip;
|
||||
|
||||
for (EquipmentSetEntry equipmentSetEntry : equipList) {
|
||||
|
||||
MobEquipment mobEquipment = new MobEquipment(equipmentSetEntry.getItemID(), equipmentSetEntry.getDropChance());
|
||||
ItemBase itemBase = mobEquipment.getItemBase();
|
||||
|
||||
if (itemBase != null) {
|
||||
if (itemBase.getType().equals(Enum.ItemType.WEAPON))
|
||||
if (mobEquipment.getSlot() == 1 && itemBase.getEquipFlag() == 2)
|
||||
mobEquipment.setSlot(2);
|
||||
|
||||
equip.put(mobEquipment.getSlot(), mobEquipment);
|
||||
}
|
||||
}
|
||||
|
||||
return equip;
|
||||
}
|
||||
|
||||
public HashMap<Integer, Integer> getStaticPowers() {
|
||||
return staticPowers;
|
||||
}
|
||||
|
||||
public void updateStaticEffects() {
|
||||
this.raceEffectsList = DbManager.MobBaseQueries.LOAD_STATIC_EFFECTS(this.getObjectUUID());
|
||||
}
|
||||
|
||||
public void updateRunes() {
|
||||
this.runes = DbManager.MobBaseQueries.LOAD_RUNES_FOR_MOBBASE(this.getObjectUUID());
|
||||
}
|
||||
|
||||
public void updatePowers() {
|
||||
this.staticPowers = DbManager.MobBaseQueries.LOAD_STATIC_POWERS(this.getObjectUUID());
|
||||
}
|
||||
|
||||
public void updateSpeeds(float walk, float walkCombat,float run, float runCombat){
|
||||
this.walk = walk;
|
||||
this.walkCombat = walkCombat;
|
||||
this.run = run;
|
||||
this.runCombat = runCombat;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public String getFirstName() {
|
||||
return this.firstName;
|
||||
}
|
||||
|
||||
public int getLoadID() {
|
||||
return this.loadID;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public int getLootTable() {
|
||||
return this.lootTable;
|
||||
}
|
||||
|
||||
public float getHealthMax() {
|
||||
return this.healthMax;
|
||||
}
|
||||
|
||||
public float getDamageMin() {
|
||||
return this.damageMin;
|
||||
}
|
||||
|
||||
public float getDamageMax() {
|
||||
return this.damageMax;
|
||||
}
|
||||
|
||||
public int getAttackRating() {
|
||||
return this.attackRating;
|
||||
}
|
||||
|
||||
public int getDefenseRating() {
|
||||
return this.defenseRating;
|
||||
}
|
||||
|
||||
public int getMinGold() {
|
||||
return this.minGold;
|
||||
}
|
||||
|
||||
public int getMaxGold() {
|
||||
return this.maxGold;
|
||||
}
|
||||
|
||||
public EnumBitSet<Enum.MobFlagType> getFlags() {
|
||||
return this.flags;
|
||||
}
|
||||
|
||||
public EnumBitSet getNoAggro() {
|
||||
return this.noAggro;
|
||||
}
|
||||
|
||||
public int getGoldMod() {
|
||||
return this.goldMod;
|
||||
}
|
||||
|
||||
public float getScale() {
|
||||
return this.scale;
|
||||
}
|
||||
|
||||
public int getTypeMasks() {
|
||||
return this.mask;
|
||||
}
|
||||
|
||||
public int getSeeInvis() {
|
||||
return this.seeInvis;
|
||||
}
|
||||
|
||||
public int getSpawnTime() {
|
||||
return this.spawnTime;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Database
|
||||
*/
|
||||
public static MobBase getMobBase(int id) {
|
||||
return MobBase.getMobBase(id, false);
|
||||
}
|
||||
|
||||
public static MobBase getMobBase(int id, boolean forceDB) {
|
||||
return DbManager.MobBaseQueries.GET_MOBBASE(id, forceDB);
|
||||
}
|
||||
|
||||
public static MobBase copyMobBase(MobBase mobbase, String name) {
|
||||
return DbManager.MobBaseQueries.COPY_MOBBASE(mobbase, name);
|
||||
}
|
||||
|
||||
public static boolean renameMobBase(int ID, String newName) {
|
||||
return DbManager.MobBaseQueries.RENAME_MOBBASE(ID, newName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Create update logic.
|
||||
}
|
||||
|
||||
public float getHitBoxRadius() {
|
||||
if (this.hitBoxRadius < 0f) {
|
||||
return 0f;
|
||||
} else {
|
||||
return this.hitBoxRadius;
|
||||
}
|
||||
}
|
||||
|
||||
public MobBaseStats getMobBaseStats() {
|
||||
return mobBaseStats;
|
||||
}
|
||||
|
||||
public float getMaxDmg() {
|
||||
return maxDmg;
|
||||
}
|
||||
|
||||
public float getMinDmg() {
|
||||
return minDmg;
|
||||
}
|
||||
|
||||
public int getAtr() {
|
||||
return atr;
|
||||
}
|
||||
|
||||
public void setAtr(int atr) {
|
||||
this.atr = atr;
|
||||
}
|
||||
|
||||
public int getDefense() {
|
||||
return defense;
|
||||
}
|
||||
|
||||
public void setDefense(int defense) {
|
||||
this.defense = defense;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the raceEffectsList
|
||||
*/
|
||||
public ArrayList<MobBaseEffects> getRaceEffectsList() {
|
||||
return raceEffectsList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the runes
|
||||
*/
|
||||
public ArrayList<RuneBase> getRunes() {
|
||||
return runes;
|
||||
}
|
||||
|
||||
public float getAttackRange() {
|
||||
return attackRange;
|
||||
}
|
||||
|
||||
public boolean isNecroPet() {
|
||||
return isNecroPet;
|
||||
}
|
||||
|
||||
public static int GetClassType(int mobbaseID){
|
||||
|
||||
switch (mobbaseID){
|
||||
case 17235:
|
||||
case 17233:
|
||||
case 17256:
|
||||
case 17259:
|
||||
case 17260:
|
||||
case 17261:
|
||||
return 2518;
|
||||
case 17258:
|
||||
case 17257:
|
||||
case 17237:
|
||||
case 17234:
|
||||
return 2521;
|
||||
default:
|
||||
return 2518;
|
||||
}
|
||||
}
|
||||
|
||||
public float getWalk() {
|
||||
return walk;
|
||||
}
|
||||
|
||||
public void setWalk(float walk) {
|
||||
this.walk = walk;
|
||||
}
|
||||
|
||||
public float getRun() {
|
||||
return run;
|
||||
}
|
||||
|
||||
public void setRun(float run) {
|
||||
this.run = run;
|
||||
}
|
||||
|
||||
public float getWalkCombat() {
|
||||
return walkCombat;
|
||||
}
|
||||
|
||||
public float getRunCombat() {
|
||||
return runCombat;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
public class MobBaseEffects {
|
||||
|
||||
private int mobBaseID;
|
||||
private int token;
|
||||
private int rank;
|
||||
private int reqLvl;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public MobBaseEffects(ResultSet rs) throws SQLException {
|
||||
this.token = rs.getInt("token");
|
||||
this.rank = rs.getInt("rank");
|
||||
this.reqLvl = rs.getInt("reqLvl");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the mobBaseID
|
||||
*/
|
||||
public int getMobBaseID() {
|
||||
return mobBaseID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setMobBaseID(int mobBaseID) {
|
||||
this.mobBaseID = mobBaseID;
|
||||
}
|
||||
|
||||
|
||||
public int getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
public int getRank() {
|
||||
return rank;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getReqLvl() {
|
||||
return reqLvl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
|
||||
public class MobBaseStats {
|
||||
|
||||
private final int baseStr;
|
||||
private final int baseInt;
|
||||
private final int baseCon;
|
||||
private final int baseSpi;
|
||||
private final int baseDex;
|
||||
private final long skillSet;
|
||||
private final int skillValue;
|
||||
public static MobBaseStats mbs = null;
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public MobBaseStats(ResultSet rs) throws SQLException {
|
||||
this.baseStr = rs.getInt("Strength");
|
||||
this.baseInt = rs.getInt("Intelligence");
|
||||
this.baseCon = rs.getInt("Constitution");
|
||||
this.baseSpi = rs.getInt("Spirit");
|
||||
this.baseDex = rs.getInt("Dexterity");
|
||||
this.skillSet = rs.getLong("baseSkills");
|
||||
this.skillValue = rs.getInt("skillAmount");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic Constructor
|
||||
*/
|
||||
|
||||
public MobBaseStats() {
|
||||
this.baseStr = 0;
|
||||
this.baseInt = 0;
|
||||
this.baseCon = 0;
|
||||
this.baseSpi = 0;
|
||||
this.baseDex = 0;
|
||||
this.skillSet = 0;
|
||||
this.skillValue = 0;
|
||||
}
|
||||
public int getBaseStr() {
|
||||
return baseStr;
|
||||
}
|
||||
|
||||
|
||||
public int getBaseInt() {
|
||||
return baseInt;
|
||||
}
|
||||
|
||||
|
||||
public int getBaseCon() {
|
||||
return baseCon;
|
||||
}
|
||||
|
||||
|
||||
public int getBaseSpi() {
|
||||
return baseSpi;
|
||||
}
|
||||
|
||||
|
||||
public int getBaseDex() {
|
||||
return baseDex;
|
||||
}
|
||||
|
||||
public long getSkillSet() {
|
||||
return skillSet;
|
||||
}
|
||||
|
||||
public int getSkillValue() {
|
||||
return skillValue;
|
||||
}
|
||||
|
||||
public static MobBaseStats GetGenericStats(){
|
||||
if (mbs != null)
|
||||
return mbs;
|
||||
mbs = new MobBaseStats();
|
||||
return mbs;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.exception.SerializationException;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.poweractions.AbstractPowerAction;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class MobEquipment extends AbstractGameObject {
|
||||
|
||||
private static AtomicInteger equipCounter = new AtomicInteger(0);
|
||||
private final ItemBase itemBase;
|
||||
private int slot;
|
||||
private int parentID;
|
||||
|
||||
//effects
|
||||
private boolean enchanted;
|
||||
private boolean isID = false;
|
||||
private AbstractPowerAction prefix;
|
||||
private AbstractPowerAction suffix;
|
||||
private int pValue;
|
||||
private int sValue;
|
||||
private int magicValue;
|
||||
|
||||
private float dropChance = 0;
|
||||
|
||||
/**
|
||||
* No Id Constructor
|
||||
*/
|
||||
public MobEquipment(ItemBase itemBase, int slot, int parentID) {
|
||||
super(MobEquipment.getNewID());
|
||||
this.itemBase = itemBase;
|
||||
this.slot = slot;
|
||||
this.parentID = parentID;
|
||||
this.enchanted = false;
|
||||
this.prefix = null;
|
||||
this.suffix = null;
|
||||
this.pValue = 0;
|
||||
this.sValue = 0;
|
||||
setMagicValue();
|
||||
}
|
||||
|
||||
public MobEquipment(ItemBase itemBase, int slot, int parentID, String pIDString, String sIDString, int pValue, int sValue) {
|
||||
super(MobEquipment.getNewID());
|
||||
this.itemBase = itemBase;
|
||||
this.slot = slot;
|
||||
this.parentID = parentID;
|
||||
|
||||
//add effects
|
||||
this.prefix = PowersManager.getPowerActionByIDString(pIDString);
|
||||
this.suffix = PowersManager.getPowerActionByIDString(sIDString);
|
||||
|
||||
this.pValue = pValue;
|
||||
this.sValue = sValue;
|
||||
this.enchanted = this.prefix == null || this.suffix == null;
|
||||
setMagicValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public MobEquipment(ResultSet rs) throws SQLException {
|
||||
super(MobEquipment.getNewID());
|
||||
int itemBaseID = rs.getInt("ItemID");
|
||||
this.itemBase = ItemBase.getItemBase(itemBaseID);
|
||||
this.slot = rs.getInt("slot");
|
||||
this.parentID = rs.getInt("mobID");
|
||||
setMagicValue();
|
||||
}
|
||||
|
||||
|
||||
public MobEquipment(int itemBaseID,float dropChance) {
|
||||
super(MobEquipment.getNewID());
|
||||
this.itemBase = ItemBase.getItemBase(itemBaseID);
|
||||
|
||||
if (this.itemBase != null)
|
||||
this.slot = this.itemBase.getValidSlot();
|
||||
else{
|
||||
Logger.error("Failed to find Itembase for ID : " + itemBaseID);
|
||||
this.slot = 0;
|
||||
}
|
||||
|
||||
this.dropChance = dropChance;
|
||||
|
||||
this.parentID = 0;
|
||||
setMagicValue();
|
||||
}
|
||||
|
||||
public ItemBase getItemBase() {
|
||||
return itemBase;
|
||||
}
|
||||
|
||||
public int getSlot() {
|
||||
return this.slot;
|
||||
}
|
||||
|
||||
public void setSlot(int value) {
|
||||
this.slot = value;
|
||||
}
|
||||
|
||||
public static int getNewID() {
|
||||
return MobEquipment.equipCounter.incrementAndGet();
|
||||
}
|
||||
|
||||
public static void serializeForVendor(MobEquipment mobEquipment,ByteBufferWriter writer, float percent) throws SerializationException {
|
||||
_serializeForClientMsg(mobEquipment,writer, false);
|
||||
int baseValue = mobEquipment.itemBase.getBaseValue() + mobEquipment.itemBase.getMagicValue();
|
||||
writer.putInt(mobEquipment.magicValue);
|
||||
writer.putInt(mobEquipment.magicValue);
|
||||
}
|
||||
|
||||
|
||||
public static void serializeForClientMsg(MobEquipment mobEquipment,ByteBufferWriter writer) throws SerializationException {
|
||||
_serializeForClientMsg(mobEquipment,writer, true);
|
||||
}
|
||||
|
||||
public static void _serializeForClientMsg(MobEquipment mobEquipment,ByteBufferWriter writer, boolean useSlot) throws SerializationException {
|
||||
|
||||
if (useSlot)
|
||||
writer.putInt(mobEquipment.slot);
|
||||
writer.putInt(0); // Pad
|
||||
writer.putInt(mobEquipment.itemBase.getUUID());
|
||||
writer.putInt(mobEquipment.getObjectType().ordinal());
|
||||
writer.putInt(mobEquipment.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
|
||||
}
|
||||
|
||||
writer.putInt(0);
|
||||
|
||||
writer.put((byte) 1); // End Datablock byte
|
||||
writer.putInt(0); // Unknown. pad?
|
||||
writer.put((byte) 1); // End Datablock byte
|
||||
|
||||
writer.putFloat(mobEquipment.itemBase.getDurability());
|
||||
writer.putFloat(mobEquipment.itemBase.getDurability());
|
||||
|
||||
writer.put((byte) 1); // End Datablock byte
|
||||
|
||||
writer.putInt(0); // Pad
|
||||
writer.putInt(0); // Pad
|
||||
|
||||
writer.putInt(mobEquipment.itemBase.getBaseValue());
|
||||
writer.putInt(mobEquipment.magicValue);
|
||||
|
||||
serializeEffects(mobEquipment,writer);
|
||||
|
||||
writer.putInt(0x00000000);
|
||||
|
||||
//name color, think mobEquipment is where mobEquipment goes
|
||||
if (mobEquipment.enchanted)
|
||||
if (mobEquipment.isID)
|
||||
writer.putInt(36);
|
||||
else
|
||||
writer.putInt(40);
|
||||
else
|
||||
writer.putInt(4);
|
||||
|
||||
writer.putInt(0);
|
||||
writer.putInt(0); // Pad
|
||||
writer.putInt(1);
|
||||
writer.putShort((short) 0);
|
||||
writer.put((byte) 0);
|
||||
}
|
||||
|
||||
public final void setMagicValue() {
|
||||
float value = 1;
|
||||
if (itemBase != null)
|
||||
value = itemBase.getBaseValue();
|
||||
if (this.prefix != null) {
|
||||
if (this.prefix.getEffectsBase() != null)
|
||||
value += this.prefix.getEffectsBase().getValue();
|
||||
if (this.prefix.getEffectsBase2() != null)
|
||||
value += this.prefix.getEffectsBase2().getValue();
|
||||
}
|
||||
if (this.suffix != null) {
|
||||
if (this.suffix.getEffectsBase() != null)
|
||||
value += this.suffix.getEffectsBase().getValue();
|
||||
if (this.suffix.getEffectsBase2() != null)
|
||||
value += this.suffix.getEffectsBase2().getValue();
|
||||
}
|
||||
|
||||
if (itemBase != null)
|
||||
|
||||
for (Integer token : itemBase.getBakedInStats().keySet()) {
|
||||
|
||||
EffectsBase effect = PowersManager.getEffectByToken(token);
|
||||
|
||||
AbstractPowerAction apa = PowersManager.getPowerActionByIDString(effect.getIDString());
|
||||
if (apa.getEffectsBase() != null)
|
||||
if (apa.getEffectsBase().getValue() > 0){
|
||||
//System.out.println(apa.getEffectsBase().getValue());
|
||||
value += apa.getEffectsBase().getValue();
|
||||
}
|
||||
|
||||
|
||||
if (apa.getEffectsBase2() != null)
|
||||
value += apa.getEffectsBase2().getValue();
|
||||
}
|
||||
|
||||
this.magicValue = (int) value;
|
||||
}
|
||||
|
||||
public int getMagicValue() {
|
||||
|
||||
if (!this.isID) {
|
||||
return itemBase.getBaseValue();
|
||||
}
|
||||
return this.magicValue;
|
||||
}
|
||||
|
||||
|
||||
public static void serializeEffects(MobEquipment mobEquipment,ByteBufferWriter writer) {
|
||||
|
||||
//skip sending effects if not IDed
|
||||
if (!mobEquipment.isID) {
|
||||
writer.putInt(0);
|
||||
return;
|
||||
}
|
||||
|
||||
//handle effect count
|
||||
int cnt = 0;
|
||||
EffectsBase pre = null;
|
||||
EffectsBase suf = null;
|
||||
if (mobEquipment.prefix != null) {
|
||||
pre = PowersManager.getEffectByIDString(mobEquipment.prefix.getIDString());
|
||||
if (pre != null)
|
||||
cnt++;
|
||||
}
|
||||
if (mobEquipment.suffix != null) {
|
||||
suf = PowersManager.getEffectByIDString(mobEquipment.suffix.getIDString());
|
||||
if (suf != null)
|
||||
cnt++;
|
||||
}
|
||||
|
||||
writer.putInt(cnt);
|
||||
|
||||
//serialize prefix
|
||||
if (pre != null)
|
||||
serializeEffect(mobEquipment,writer, pre, mobEquipment.pValue);
|
||||
|
||||
//serialize suffix
|
||||
if (suf != null)
|
||||
serializeEffect(mobEquipment,writer, suf, mobEquipment.sValue);
|
||||
}
|
||||
|
||||
public static void serializeEffect(MobEquipment mobEquipment,ByteBufferWriter writer, EffectsBase eb, int rank) {
|
||||
String name;
|
||||
if (eb.isPrefix()) {
|
||||
if (mobEquipment.itemBase == null)
|
||||
name = eb.getName();
|
||||
else
|
||||
name = eb.getName() + ' ' + mobEquipment.itemBase.getName();
|
||||
}
|
||||
else if (eb.isSuffix()) {
|
||||
if (mobEquipment.itemBase == null)
|
||||
name = eb.getName();
|
||||
else
|
||||
name = mobEquipment.itemBase.getName() + ' ' + eb.getName();
|
||||
}
|
||||
else {
|
||||
if (mobEquipment.itemBase == null)
|
||||
name = "";
|
||||
else
|
||||
name = mobEquipment.itemBase.getName();
|
||||
}
|
||||
|
||||
writer.putInt(eb.getToken());
|
||||
writer.putInt(rank);
|
||||
writer.putInt(1);
|
||||
writer.put((byte) 1);
|
||||
writer.putInt(mobEquipment.getObjectType().ordinal());
|
||||
writer.putInt(mobEquipment.getObjectUUID());
|
||||
writer.putString(name);
|
||||
writer.putFloat(-1000f);
|
||||
}
|
||||
|
||||
public void setPrefix(String pIDString, int pValue) {
|
||||
AbstractPowerAction apa = PowersManager.getPowerActionByIDString(pIDString);
|
||||
if (apa != null) {
|
||||
this.prefix = apa;
|
||||
this.pValue = pValue;
|
||||
} else
|
||||
this.prefix = null;
|
||||
|
||||
this.enchanted = this.prefix != null || this.suffix != null;
|
||||
|
||||
setMagicValue();
|
||||
}
|
||||
|
||||
public void setSuffix(String sIDString, int sValue) {
|
||||
AbstractPowerAction apa = PowersManager.getPowerActionByIDString(sIDString);
|
||||
if (apa != null) {
|
||||
this.suffix = apa;
|
||||
this.sValue = sValue;
|
||||
} else
|
||||
this.suffix = null;
|
||||
|
||||
this.enchanted = this.prefix != null || this.suffix != null;
|
||||
|
||||
setMagicValue();
|
||||
}
|
||||
|
||||
public void setIsID(boolean value) {
|
||||
this.isID = value;
|
||||
}
|
||||
|
||||
public boolean isID() {
|
||||
return this.isID;
|
||||
}
|
||||
|
||||
public void transferEnchants(Item item) {
|
||||
if (this.prefix != null) {
|
||||
String IDString = this.prefix.getIDString();
|
||||
item.addPermanentEnchantment(IDString, this.pValue);
|
||||
}
|
||||
if (this.suffix != null) {
|
||||
String IDString = this.suffix.getIDString();
|
||||
item.addPermanentEnchantment(IDString, this.sValue);
|
||||
}
|
||||
if (this.isID)
|
||||
item.setIsID(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Database
|
||||
*/
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
}
|
||||
|
||||
|
||||
public void persistObject() {
|
||||
PreparedStatementShared ps = null;
|
||||
try {
|
||||
ps = prepareStatement("INSERT INTO static_npc_mobequipment (`mobID`, `slot`, `itemID`) VALUES (?, ?, ?)");
|
||||
ps.setInt(1, this.parentID, true);
|
||||
ps.setInt(2, this.slot);
|
||||
ps.setInt(3, this.itemBase.getUUID(), true);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
Logger.error( e.toString());
|
||||
} finally {
|
||||
ps.release();
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeObject(int UUID, int slot) {
|
||||
PreparedStatementShared ps = null;
|
||||
try {
|
||||
ps = prepareStatement("DELETE FROM `static_npc_mobequipment` WHERE `mobID`=? AND slot=?");
|
||||
ps.setInt(1, UUID);
|
||||
ps.setInt(2, slot);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
Logger.error( e.toString());
|
||||
} finally {
|
||||
ps.release();
|
||||
}
|
||||
}
|
||||
|
||||
public float getDropChance() {
|
||||
return dropChance;
|
||||
}
|
||||
|
||||
public void setDropChance(float dropChance) {
|
||||
this.dropChance = dropChance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.Enum.ItemType;
|
||||
import engine.Enum.OwnerType;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.powers.poweractions.AbstractPowerAction;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* An immutable, non-persistant implementation of Item
|
||||
*
|
||||
* @author Burfo
|
||||
*/
|
||||
public final class MobLoot extends Item {
|
||||
|
||||
private static final AtomicInteger LastUsedId = new AtomicInteger(0);
|
||||
|
||||
private boolean isDeleted = false;
|
||||
private boolean noSteal;
|
||||
private String prefix = "";
|
||||
private String suffix = "";
|
||||
|
||||
private int fidelityEquipID = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new MobLoot.
|
||||
* Do not use this to create Gold.
|
||||
*
|
||||
* @param mob Mob that owns this item
|
||||
* @param ib ItemBase
|
||||
*/
|
||||
public MobLoot(AbstractCharacter mob, ItemBase ib, boolean noSteal) {
|
||||
this(mob, ib, 0, noSteal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MobLoot item to hold Gold for the Mob.
|
||||
*
|
||||
* @param mob Mob that owns this item
|
||||
* @param qtyOfGold Quantity of gold
|
||||
*/
|
||||
public MobLoot(AbstractCharacter mob, int qtyOfGold) {
|
||||
this(mob, ItemBase.getGoldItemBase(), qtyOfGold, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MobLoot.
|
||||
* Primarily used for stackable items that have a quantity.
|
||||
*
|
||||
* @param mob Mob that owns this item
|
||||
* @param ib ItemBase
|
||||
* @param quantity Quantity of the item
|
||||
*/
|
||||
public MobLoot(AbstractCharacter mob, ItemBase ib, int quantity, boolean noSteal) {
|
||||
super( ib, mob.getObjectUUID(),
|
||||
OwnerType.Mob, (byte) 0, (byte) 0, (short) 0,
|
||||
(short) 0, true, false, false, false, true,
|
||||
false, (byte) 0, new ArrayList<>(), generateId());
|
||||
|
||||
if (quantity == 0 && ib.getType() == ItemType.RESOURCE)
|
||||
quantity = 1;
|
||||
|
||||
|
||||
if (quantity > 0)
|
||||
this.setNumOfItems(quantity);
|
||||
|
||||
this.noSteal = noSteal;
|
||||
this.setIsID(this.getItemBase().isAutoID());
|
||||
|
||||
// Class is 'final'; passing 'this' should be okay at the end of the constructor
|
||||
|
||||
DbManager.addToCache(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this MotLoot to a persistable Item. Used when a MotLoot is
|
||||
* looted
|
||||
* from a Mob to a Player. Do not call for a Gold item.
|
||||
*
|
||||
* @return An orphaned Item, ready to be moved to the Player's inventory.
|
||||
*/
|
||||
public synchronized Item promoteToItem(PlayerCharacter looter) {
|
||||
|
||||
if (looter == null)
|
||||
return null;
|
||||
|
||||
if (isDeleted)
|
||||
return null;
|
||||
|
||||
if (this.getItemBase().getType().equals(ItemType.GOLD))
|
||||
return null;
|
||||
|
||||
|
||||
Item item = this;
|
||||
|
||||
item.setOwner(looter);
|
||||
//item.setIsID(false);
|
||||
|
||||
item.containerType = Enum.ItemContainerType.INVENTORY;
|
||||
item.setValue(0);
|
||||
item.setName(this.getCustomName());
|
||||
item.setIsID(this.isID());
|
||||
|
||||
if (this.getNumOfItems() > 1)
|
||||
item.setNumOfItems(this.getNumOfItems());
|
||||
|
||||
try {
|
||||
item = DbManager.ItemQueries.ADD_ITEM(item);
|
||||
} catch (Exception e) {
|
||||
Logger.error("e");
|
||||
return null;
|
||||
}
|
||||
|
||||
// for (String effectName : this.effectNames)
|
||||
// item.addPermanentEnchantment(effectName, 0);
|
||||
//transfer enchantments to item
|
||||
if (this.prefix.length() != 0)
|
||||
item.addPermanentEnchantment(this.prefix, 0);
|
||||
if (this.suffix.length() != 0)
|
||||
item.addPermanentEnchantment(this.suffix, 0);
|
||||
|
||||
this.junk();
|
||||
return item;
|
||||
}
|
||||
|
||||
public synchronized Item promoteToItemForNPC(NPC looter) {
|
||||
|
||||
if (looter == null)
|
||||
return null;
|
||||
|
||||
if (isDeleted)
|
||||
return null;
|
||||
|
||||
if (this.getItemBase().getType().equals(ItemType.GOLD))
|
||||
return null;
|
||||
|
||||
Item item = this;
|
||||
item.setOwner(looter);
|
||||
item.containerType = Enum.ItemContainerType.INVENTORY;
|
||||
item.setIsID(true);
|
||||
|
||||
if (this.getNumOfItems() > 1)
|
||||
item.setNumOfItems(this.getNumOfItems());
|
||||
|
||||
try {
|
||||
item = DbManager.ItemQueries.ADD_ITEM(item);
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
return null;
|
||||
}
|
||||
item.containerType = Enum.ItemContainerType.INVENTORY;
|
||||
|
||||
// for (String effectName : this.effectNames)
|
||||
// item.addPermanentEnchantment(effectName, 0);
|
||||
//transfer enchantments to item
|
||||
try{
|
||||
for (String enchant:this.getEffectNames()){
|
||||
item.addPermanentEnchantment(enchant, 0);
|
||||
}
|
||||
}catch(Exception e){
|
||||
Logger.error(e.getMessage());
|
||||
}
|
||||
|
||||
DbManager.NPCQueries.REMOVE_FROM_PRODUCTION_LIST(this.getObjectUUID(),looter.getObjectUUID());
|
||||
looter.removeItemFromForge(this);
|
||||
this.junk();
|
||||
return item;
|
||||
}
|
||||
|
||||
public synchronized void recycle(NPC vendor){
|
||||
|
||||
//remove from production list for npc in db
|
||||
|
||||
DbManager.NPCQueries.REMOVE_FROM_PRODUCTION_LIST(this.getObjectUUID(),vendor.getObjectUUID());
|
||||
this.removeFromCache();
|
||||
isDeleted = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Junks the item and marks it as deleted
|
||||
*/
|
||||
@Override
|
||||
protected synchronized void junk() {
|
||||
this.removeFromCache();
|
||||
isDeleted = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the MobLoot object from its Id number
|
||||
*
|
||||
* @param id Id Number
|
||||
* @return MobLoot object
|
||||
*/
|
||||
public static MobLoot getFromCache(int id) {
|
||||
return (MobLoot) DbManager.getFromCache(Enum.GameObjectType.MobLoot, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this object has been marked as deleted.
|
||||
*
|
||||
* @return True if deleted.
|
||||
*/
|
||||
public boolean isDeleted() {
|
||||
return this.isDeleted;
|
||||
}
|
||||
|
||||
public boolean noSteal() {
|
||||
return this.noSteal;
|
||||
}
|
||||
|
||||
public void addPermanentEnchantment(String enchantID, int rank, int value, boolean prefix) {
|
||||
AbstractPowerAction apa = PowersManager.getPowerActionByIDString(enchantID);
|
||||
if (apa == null)
|
||||
return;
|
||||
apa.applyEffectForItem(this, rank);
|
||||
|
||||
//limit to 2 effects
|
||||
// if (this.effectNames.size() < 2)
|
||||
// this.effectNames.add(enchantID);
|
||||
if (prefix)
|
||||
this.prefix = enchantID;
|
||||
else
|
||||
this.suffix = enchantID;
|
||||
|
||||
this.getEffectNames().add(enchantID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next available Id number.
|
||||
*
|
||||
* @return Id number
|
||||
*/
|
||||
private static int generateId() {
|
||||
int id = LastUsedId.decrementAndGet();
|
||||
|
||||
//TODO Add a way to reclaim disposed IDs if this becomes a problem
|
||||
if (id == (-10000))
|
||||
Logger.warn("Only 10,000 Id numbers remain useable. Server restart suggested.");
|
||||
else if (id < Integer.MIN_VALUE + 1000)
|
||||
Logger.warn("Only " + (Integer.MIN_VALUE + id)
|
||||
+ " Id numbers remain useable! Server restart suggested.");
|
||||
else if (id == Integer.MIN_VALUE)
|
||||
throw new UnsupportedOperationException("MobLoot has no remaining Id numbers! Restart server immediately!");
|
||||
else if ((id % 10000) == 0)
|
||||
Logger.info( id + " of " + Integer.MIN_VALUE + " Id numbers consumed.");
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/* *****
|
||||
* All of the following methods are overridden from
|
||||
* the superclass and intentionally not implemented.
|
||||
* *****
|
||||
*/
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void setOwnerID(int id) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public synchronized void decrementChargesRemaining() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected boolean equipItem(NPC npc, byte slot) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected boolean equipItem(PlayerCharacter pc, byte slot) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected boolean moveItemToBank(NPC npc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected boolean moveItemToBank(PlayerCharacter pc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected boolean moveItemToInventory(Corpse corpse) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected boolean moveItemToInventory(NPC npc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected boolean moveItemToInventory(PlayerCharacter pc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected boolean moveItemToVault(Account a) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void setLastOwner(AbstractWorldObject value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void updateDatabase() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected void validateItemContainer() {
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public String getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
public void setSuffix(String suffix) {
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public int getFidelityEquipID() {
|
||||
return fidelityEquipID;
|
||||
}
|
||||
|
||||
public void setFidelityEquipID(int fidelityEquipID) {
|
||||
this.fidelityEquipID = fidelityEquipID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class MobLootBase {
|
||||
|
||||
private int mobBaseID;
|
||||
private int lootTableID;
|
||||
private float chance;
|
||||
|
||||
public static HashMap<Integer, ArrayList<MobLootBase>> MobLootSet = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public MobLootBase(ResultSet rs) throws SQLException {
|
||||
this.mobBaseID = rs.getInt("mobBaseID");
|
||||
this.lootTableID = rs.getInt("lootTable");
|
||||
this.chance = rs.getFloat("chance");
|
||||
}
|
||||
|
||||
public MobLootBase(int mobBaseID, int lootTableID, int chance) {
|
||||
super();
|
||||
this.mobBaseID = mobBaseID;
|
||||
this.lootTableID = lootTableID;
|
||||
this.chance = chance;
|
||||
|
||||
}
|
||||
|
||||
public int getMobBaseID() {
|
||||
return mobBaseID;
|
||||
}
|
||||
public float getChance() {
|
||||
return chance;
|
||||
}
|
||||
|
||||
public int getLootTableID() {
|
||||
return lootTableID;
|
||||
}
|
||||
|
||||
public void setLootTableID(int lootTableID) {
|
||||
this.lootTableID = lootTableID;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class MobbaseGoldEntry {
|
||||
|
||||
private float chance;
|
||||
private int min;
|
||||
private int max;
|
||||
|
||||
public static HashMap<Integer, MobbaseGoldEntry> MobbaseGoldMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public MobbaseGoldEntry(ResultSet rs) throws SQLException {
|
||||
|
||||
this.chance = rs.getFloat("chance");
|
||||
this.min = rs.getInt("min");
|
||||
this.max = (rs.getInt("max"));
|
||||
}
|
||||
|
||||
public static void LoadMobbaseGold() {
|
||||
MobbaseGoldMap = DbManager.MobBaseQueries.LOAD_GOLD_FOR_MOBBASE();
|
||||
}
|
||||
|
||||
public float getChance() {
|
||||
return chance;
|
||||
}
|
||||
|
||||
public int getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
public int getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,106 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.ProfitType;
|
||||
import engine.gameManager.DbManager;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class NPCProfits {
|
||||
|
||||
|
||||
public int npcUID;
|
||||
public float buyNormal;
|
||||
public float buyGuild;
|
||||
public float buyNation;
|
||||
public float sellNormal;
|
||||
public float sellGuild;
|
||||
public float sellNation;
|
||||
|
||||
public static NPCProfits defaultProfits = new NPCProfits(0,.33f,.33f,.33f,1,1,1);
|
||||
|
||||
|
||||
|
||||
|
||||
public static HashMap <Integer,NPCProfits> ProfitCache = new HashMap<>();
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public NPCProfits(ResultSet rs) throws SQLException {
|
||||
|
||||
npcUID = rs.getInt("npcUID");
|
||||
buyNormal = rs.getFloat("buy_normal");
|
||||
buyGuild = rs.getFloat("buy_guild");
|
||||
buyNation = rs.getFloat("buy_nation");
|
||||
sellNormal = rs.getFloat("sell_normal");
|
||||
sellGuild = rs.getFloat("sell_guild");
|
||||
sellNation = rs.getFloat("sell_nation");
|
||||
|
||||
}
|
||||
|
||||
public NPCProfits(int npcUID, float buyNormal, float buyGuild, float buyNation, float sellNormal,
|
||||
float sellGuild, float sellNation) {
|
||||
super();
|
||||
this.npcUID = npcUID;
|
||||
this.buyNormal = buyNormal;
|
||||
this.buyGuild = buyGuild;
|
||||
this.buyNation = buyNation;
|
||||
this.sellNormal = sellNormal;
|
||||
this.sellGuild = sellGuild;
|
||||
this.sellNation = sellNation;
|
||||
}
|
||||
|
||||
public static boolean UpdateProfits(NPC npc, NPCProfits profit, ProfitType profitType, float value){
|
||||
|
||||
try {
|
||||
if (!DbManager.NPCQueries.UPDATE_PROFITS(npc, profitType, value))
|
||||
return false;
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
switch (profitType){
|
||||
case BuyNormal:
|
||||
profit.buyNormal = value;
|
||||
break;
|
||||
case BuyGuild:
|
||||
profit.buyGuild = value;
|
||||
break;
|
||||
case BuyNation:
|
||||
profit.buyNation = value;
|
||||
break;
|
||||
case SellNormal:
|
||||
profit.sellNormal = value;
|
||||
break;
|
||||
case SellGuild:
|
||||
profit.sellGuild = value;
|
||||
break;
|
||||
case SellNation:
|
||||
profit.sellNation = value;
|
||||
break;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static boolean CreateProfits(NPC npc){
|
||||
DbManager.NPCQueries.CREATE_PROFITS(npc);
|
||||
NPCProfits profits = new NPCProfits(npc.getObjectUUID(),.33f,.33f,.33f,1,1,1);
|
||||
NPCProfits.ProfitCache.put(npc.getObjectUUID(), profits);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class NPCRune extends AbstractGameObject {
|
||||
|
||||
private final RuneBase runeBase;
|
||||
private final int player;
|
||||
private final ArrayList<SkillReq> skillsGranted;
|
||||
private final ArrayList<RuneBaseEffect> effectsGranted;
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public NPCRune(RuneBase runeBase, int characterID) {
|
||||
super();
|
||||
this.runeBase = runeBase;
|
||||
this.player = characterID;
|
||||
if (this.runeBase != null)
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
else
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public NPCRune(RuneBase runeBase, int characterID, int newUUID) {
|
||||
super(newUUID);
|
||||
this.runeBase = runeBase;
|
||||
this.player = characterID;
|
||||
if (this.runeBase == null)
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
else
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
}
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public NPCRune(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
this.runeBase = RuneBase.getRuneBase(rs.getInt("RuneBaseID"));
|
||||
this.player = rs.getInt("NpcID");
|
||||
if (this.runeBase != null) {
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
||||
} else {
|
||||
Logger.error("Failed to find RuneBase for NPCRune " + this.getObjectUUID());
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public RuneBase getRuneBase() {
|
||||
return this.runeBase;
|
||||
}
|
||||
|
||||
public int getRuneBaseID() {
|
||||
if (this.runeBase != null)
|
||||
return this.runeBase.getObjectUUID();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getPlayerID() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public ArrayList<SkillReq> getSkillsGranted() {
|
||||
return this.skillsGranted;
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
||||
return this.effectsGranted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Serializing
|
||||
*/
|
||||
|
||||
public static void serializeForClientMsg(NPCRune npcRune,ByteBufferWriter writer) {
|
||||
if (npcRune.runeBase != null) {
|
||||
writer.putInt(npcRune.runeBase.getType());
|
||||
writer.putInt(0);
|
||||
writer.putInt(npcRune.runeBase.getObjectUUID());
|
||||
writer.putInt(npcRune.getObjectType().ordinal());
|
||||
writer.putInt(npcRune.getObjectUUID());
|
||||
} else {
|
||||
for (int i = 0; i < 5; i++)
|
||||
writer.putInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.net.ByteBufferWriter;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
public class Nation extends AbstractWorldObject {
|
||||
|
||||
private final String name;
|
||||
private GuildTag gt;
|
||||
private String motd = "";
|
||||
private int primaryGuildID = 0;
|
||||
|
||||
/**
|
||||
* No Id Constructor
|
||||
*/
|
||||
public Nation( String name, GuildTag gt) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.gt = gt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public Nation(String name, GuildTag gt, int newUUID) {
|
||||
super(newUUID);
|
||||
this.name = name;
|
||||
this.gt = gt;
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public Nation(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
this.name = rs.getString("name");
|
||||
|
||||
this.gt = new GuildTag( rs.getInt("backgroundColor01"),
|
||||
rs.getInt("backgroundColor02"),
|
||||
rs.getInt("symbolColor"),
|
||||
rs.getInt("symbol"),
|
||||
rs.getInt("backgroundDesign"));
|
||||
this.motd = rs.getString("motd");
|
||||
this.primaryGuildID = rs.getInt("primaryGuild");
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public GuildTag getGuildTag() {
|
||||
return this.gt;
|
||||
}
|
||||
|
||||
public String getMOTD() {
|
||||
return this.motd;
|
||||
}
|
||||
|
||||
public void setMOTD(String value) {
|
||||
this.motd = value;
|
||||
}
|
||||
|
||||
public int getPrimaryGuildID() {
|
||||
return this.primaryGuildID;
|
||||
}
|
||||
|
||||
public void setPrimaryGuildID(int value) {
|
||||
this.primaryGuildID = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utils
|
||||
*/
|
||||
private static Nation n;
|
||||
|
||||
public static Nation getErrantNation() {
|
||||
if (n == null) {
|
||||
n = new Nation("None", GuildTag.ERRANT, 0);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Serialization
|
||||
*/
|
||||
|
||||
public static void serializeForTrack(Nation nation,ByteBufferWriter writer) {
|
||||
writer.putInt(nation.getObjectType().ordinal());
|
||||
writer.putInt(nation.getObjectUUID());
|
||||
writer.put((byte)1);
|
||||
GuildTag._serializeForDisplay(nation.gt,writer);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runAfterLoad() {}
|
||||
}
|
||||
@@ -0,0 +1,500 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.Enum.ModType;
|
||||
import engine.Enum.SourceType;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.ConfigManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.powers.DamageShield;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class PlayerBonuses {
|
||||
|
||||
//First bonus set
|
||||
private ConcurrentHashMap<AbstractEffectModifier, Float> bonusFloats = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<AbstractEffectModifier, DamageShield> bonusDamageShields = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<AbstractEffectModifier, String> bonusStrings = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<ModType, HashSet<SourceType>> bonusLists = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<ModType, HashMap<SourceType, Boolean>> bonusBools = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<SourceType, Float> skillBonuses = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<ModType, Float> regens = new ConcurrentHashMap<>();
|
||||
|
||||
//If active == 0 then all gets come from the A list and all puts go to the B list
|
||||
//If active == 1 then all gets come from the B list and all puts go to the A list
|
||||
//They alternate each time bonuses are calculated so the one being updated isn't read from.
|
||||
|
||||
|
||||
/**
|
||||
* Generic Constructor
|
||||
*/
|
||||
public PlayerBonuses(PlayerCharacter pc) {
|
||||
}
|
||||
|
||||
public static void InitializeBonuses(PlayerCharacter player){
|
||||
if (player.bonuses == null)
|
||||
return;
|
||||
if (ConfigManager.serverType.equals(Enum.ServerType.LOGINSERVER))
|
||||
return;
|
||||
|
||||
player.bonuses.calculateRuneBaseEffects(player);
|
||||
}
|
||||
|
||||
public PlayerBonuses(Mob mob) {
|
||||
clearRuneBaseEffects();
|
||||
}
|
||||
|
||||
public static PlayerBonuses grantBonuses(AbstractCharacter ac) {
|
||||
|
||||
if (ac.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
|
||||
return new PlayerBonuses((PlayerCharacter)ac);
|
||||
else if (ac.getObjectType().equals(Enum.GameObjectType.Mob))
|
||||
return new PlayerBonuses((Mob)ac);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public void clearRuneBaseEffects() {
|
||||
|
||||
this.bonusBools.clear();
|
||||
this.bonusFloats.clear();
|
||||
this.bonusStrings.clear();
|
||||
this.bonusDamageShields.clear();
|
||||
this.bonusLists.clear();
|
||||
this.skillBonuses.clear();
|
||||
this.regens.put(ModType.HealthRecoverRate, (float) 1);
|
||||
this.regens.put(ModType.ManaRecoverRate, (float) 1);
|
||||
this.regens.put(ModType.StaminaRecoverRate, (float) 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void calculateRuneBaseEffects(PlayerCharacter pc) {
|
||||
//Clear everything
|
||||
clearRuneBaseEffects();
|
||||
|
||||
//recalculate race
|
||||
|
||||
|
||||
if (pc.getRace() != null){
|
||||
|
||||
|
||||
if (pc.getRace().getEffectsList() != null)
|
||||
for (MobBaseEffects raceEffect: pc.getRace().getEffectsList()){
|
||||
EffectsBase eb = PowersManager.getEffectByToken(raceEffect.getToken());
|
||||
|
||||
if (eb == null)
|
||||
continue;
|
||||
if (pc.getLevel() < raceEffect.getReqLvl())
|
||||
continue;
|
||||
for (AbstractEffectModifier modifier: eb.getModifiers()){
|
||||
modifier.applyBonus(pc, raceEffect.getRank());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (SkillsBase.runeSkillsCache.containsKey(pc.getRaceID())){
|
||||
for (int skillToken : SkillsBase.runeSkillsCache.get(pc.getRaceID()).keySet()){
|
||||
float amount = SkillsBase.runeSkillsCache.get(pc.getRaceID()).get(skillToken);
|
||||
|
||||
SkillsBase sb = SkillsBase.tokenCache.get(skillToken);
|
||||
|
||||
if (sb == null)
|
||||
continue;
|
||||
if (this.skillBonuses.containsKey(sb.sourceType) == false)
|
||||
this.skillBonuses.put(sb.sourceType, amount);
|
||||
else
|
||||
this.skillBonuses.put(sb.sourceType, this.skillBonuses.get(sb.sourceType) + amount);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//calculate baseclass effects
|
||||
if (pc.getBaseClass() != null){
|
||||
|
||||
if (pc.getBaseClass().getEffectsList() != null)
|
||||
for (MobBaseEffects classEffect: pc.getBaseClass().getEffectsList()){
|
||||
EffectsBase eb = PowersManager.getEffectByToken(classEffect.getToken());
|
||||
|
||||
if (eb == null)
|
||||
continue;
|
||||
if (pc.getLevel() < classEffect.getReqLvl())
|
||||
continue;
|
||||
for (AbstractEffectModifier modifier: eb.getModifiers()){
|
||||
modifier.applyBonus(pc, classEffect.getRank());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (SkillsBase.runeSkillsCache.containsKey(pc.getBaseClassID())){
|
||||
for (int skillToken : SkillsBase.runeSkillsCache.get(pc.getBaseClassID()).keySet()){
|
||||
float amount = SkillsBase.runeSkillsCache.get(pc.getBaseClassID()).get(skillToken);
|
||||
|
||||
SkillsBase sb = SkillsBase.tokenCache.get(skillToken);
|
||||
|
||||
if (sb == null)
|
||||
continue;
|
||||
if (this.skillBonuses.containsKey(sb.sourceType) == false)
|
||||
this.skillBonuses.put(sb.sourceType, amount);
|
||||
else
|
||||
this.skillBonuses.put(sb.sourceType, this.skillBonuses.get(sb.sourceType) + amount);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//calculate promotionClass Effects
|
||||
if (pc.getPromotionClass() != null){
|
||||
if (pc.getPromotionClass().getEffectsList() != null)
|
||||
for (MobBaseEffects promoEffect: pc.getPromotionClass().getEffectsList()){
|
||||
EffectsBase eb = PowersManager.getEffectByToken(promoEffect.getToken());
|
||||
|
||||
if (eb == null)
|
||||
continue;
|
||||
if (pc.getLevel() < promoEffect.getReqLvl())
|
||||
continue;
|
||||
for (AbstractEffectModifier modifier: eb.getModifiers()){
|
||||
modifier.applyBonus(pc, promoEffect.getRank());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (SkillsBase.runeSkillsCache.containsKey(pc.getPromotionClassID())){
|
||||
for (int skillToken : SkillsBase.runeSkillsCache.get(pc.getPromotionClassID()).keySet()){
|
||||
float amount = SkillsBase.runeSkillsCache.get(pc.getPromotionClassID()).get(skillToken);
|
||||
|
||||
SkillsBase sb = SkillsBase.tokenCache.get(skillToken);
|
||||
|
||||
if (sb == null)
|
||||
continue;
|
||||
if (this.skillBonuses.containsKey(sb.sourceType) == false)
|
||||
this.skillBonuses.put(sb.sourceType, amount);
|
||||
else
|
||||
this.skillBonuses.put(sb.sourceType, this.skillBonuses.get(sb.sourceType) + amount);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(CharacterRune runes : pc.getRunes()){
|
||||
RuneBase characterRune = RuneBase.getRuneBase(runes.getRuneBaseID());
|
||||
|
||||
if (characterRune.getEffectsList() != null)
|
||||
for (MobBaseEffects runeEffect: characterRune.getEffectsList()){
|
||||
EffectsBase eb = PowersManager.getEffectByToken(runeEffect.getToken());
|
||||
|
||||
if (eb == null)
|
||||
continue;
|
||||
if (pc.getLevel() < runeEffect.getReqLvl())
|
||||
continue;
|
||||
for (AbstractEffectModifier modifier: eb.getModifiers()){
|
||||
modifier.applyBonus(pc, runeEffect.getRank());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (SkillsBase.runeSkillsCache.containsKey(runes.getRuneBaseID())){
|
||||
for (int skillToken : SkillsBase.runeSkillsCache.get(runes.getRuneBaseID()).keySet()){
|
||||
float amount = SkillsBase.runeSkillsCache.get(runes.getRuneBaseID()).get(skillToken);
|
||||
|
||||
SkillsBase sb = SkillsBase.tokenCache.get(skillToken);
|
||||
|
||||
if (sb == null)
|
||||
continue;
|
||||
if (this.skillBonuses.containsKey(sb.sourceType) == false)
|
||||
this.skillBonuses.put(sb.sourceType, amount);
|
||||
else
|
||||
this.skillBonuses.put(sb.sourceType, this.skillBonuses.get(sb.sourceType) + amount);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Update seeInvis if needed
|
||||
|
||||
float seeInvis = this.getFloat(ModType.SeeInvisible, SourceType.None);
|
||||
if (pc.getSeeInvis() < seeInvis)
|
||||
pc.setSeeInvis((short)seeInvis);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void grantEffect(RuneBaseEffect rbe) {
|
||||
}
|
||||
|
||||
|
||||
public void setFloat(AbstractEffectModifier mod, float val) {
|
||||
if (val != 0)
|
||||
this.bonusFloats.put(mod, val);
|
||||
else
|
||||
this.bonusFloats.remove(mod);
|
||||
}
|
||||
|
||||
public void setString(AbstractEffectModifier mod, String val) {
|
||||
if (!val.isEmpty())
|
||||
this.bonusStrings.put(mod, val);
|
||||
else
|
||||
this.bonusStrings.remove(mod);
|
||||
}
|
||||
|
||||
public void setList(ModType mod, HashSet<SourceType> val) {
|
||||
if (!val.equals(null))
|
||||
this.bonusLists.put(mod, val);
|
||||
else
|
||||
this.bonusLists.remove(mod);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void addFloat(AbstractEffectModifier mod, Float val) {
|
||||
if (this.bonusFloats.containsKey(mod) == false)
|
||||
this.bonusFloats.put(mod, val);
|
||||
else
|
||||
this.bonusFloats.put(mod, this.bonusFloats.get(mod) + val);
|
||||
}
|
||||
|
||||
public void multFloat(AbstractEffectModifier mod, Float val) {
|
||||
if (this.bonusFloats.containsKey(mod) == false)
|
||||
this.bonusFloats.put(mod, val);
|
||||
else
|
||||
this.bonusFloats.put(mod,this.bonusFloats.get(mod) + (val * ( this.bonusFloats.get(mod) + val)));
|
||||
}
|
||||
|
||||
public void multRegen(ModType mod, Float val) {
|
||||
this.regens.put(mod,this.regens.get(mod) + (this.regens.get(mod) * val));
|
||||
}
|
||||
|
||||
|
||||
public boolean getBool(ModType modType, SourceType sourceType) {
|
||||
|
||||
if (this.bonusBools.containsKey(modType) == false)
|
||||
return false;
|
||||
|
||||
if (this.bonusBools.get(modType).containsKey(sourceType) == false)
|
||||
return false;
|
||||
|
||||
return this.bonusBools.get(modType).get(sourceType);
|
||||
|
||||
}
|
||||
|
||||
public float getSkillBonus(SourceType sourceType) {
|
||||
|
||||
if (this.skillBonuses.containsKey(sourceType) == false)
|
||||
return 0;
|
||||
return this.skillBonuses.get(sourceType);
|
||||
}
|
||||
|
||||
|
||||
public float getFloat(ModType modType, SourceType sourceType) {
|
||||
float amount = 0;
|
||||
for (AbstractEffectModifier mod : this.bonusFloats.keySet()){
|
||||
if (mod.getPercentMod() != 0)
|
||||
continue;
|
||||
if (mod.modType.equals(modType) == false || mod.sourceType.equals(sourceType) == false)
|
||||
continue;
|
||||
|
||||
if (this.bonusFloats.get(mod) == null)
|
||||
continue;
|
||||
|
||||
amount += this.bonusFloats.get(mod);
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
public float getFloatPercentPositive(ModType modType, SourceType sourceType) {
|
||||
float amount = 0;
|
||||
for (AbstractEffectModifier mod : this.bonusFloats.keySet()){
|
||||
|
||||
if (mod.getPercentMod() == 0 && !modType.equals(ModType.AdjustAboveDmgCap))
|
||||
continue;
|
||||
|
||||
|
||||
if (mod.modType.equals(modType) == false || mod.sourceType.equals(sourceType) == false)
|
||||
continue;
|
||||
|
||||
|
||||
if (this.bonusFloats.get(mod) == null)
|
||||
continue;
|
||||
|
||||
if (this.bonusFloats.get(mod) < 0)
|
||||
continue;
|
||||
amount += this.bonusFloats.get(mod);
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
public float getFloatPercentAll(ModType modType, SourceType sourceType) {
|
||||
float amount = 0;
|
||||
for (AbstractEffectModifier mod : this.bonusFloats.keySet()){
|
||||
|
||||
if (mod.getPercentMod() == 0 && !modType.equals(ModType.AdjustAboveDmgCap))
|
||||
continue;
|
||||
|
||||
|
||||
if (mod.modType.equals(modType) == false || mod.sourceType.equals(sourceType) == false)
|
||||
continue;
|
||||
|
||||
if (this.bonusFloats.get(mod) == null)
|
||||
continue;
|
||||
|
||||
amount += this.bonusFloats.get(mod);
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
public float getRegen(ModType modType) {
|
||||
return this.regens.get(modType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float getFloatPercentNullZero(ModType modType, SourceType sourceType) {
|
||||
float amount = 0;
|
||||
for (AbstractEffectModifier mod : this.bonusFloats.keySet()){
|
||||
|
||||
if (mod.getPercentMod() == 0)
|
||||
continue;
|
||||
if (mod.modType.equals(modType) == false || mod.sourceType.equals(sourceType) == false)
|
||||
continue;
|
||||
|
||||
if (this.bonusFloats.get(mod) == null)
|
||||
continue;
|
||||
|
||||
amount += this.bonusFloats.get(mod);
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
public float getFloatPercentNegative(ModType modType, SourceType sourceType) {
|
||||
float amount = 0;
|
||||
for (AbstractEffectModifier mod : this.bonusFloats.keySet()){
|
||||
|
||||
if (mod.getPercentMod() == 0)
|
||||
continue;
|
||||
if (mod.modType.equals(modType) == false || mod.sourceType.equals(sourceType) == false)
|
||||
continue;
|
||||
|
||||
if (this.bonusFloats.get(mod) == null)
|
||||
continue;
|
||||
|
||||
if (this.bonusFloats.get(mod) > 0)
|
||||
continue;
|
||||
|
||||
|
||||
amount += this.bonusFloats.get(mod);
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public HashSet<SourceType> getList(ModType modType) {
|
||||
if (this.bonusLists.containsKey(modType))
|
||||
return this.bonusLists.get(modType);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<AbstractEffectModifier, DamageShield> getDamageShields() {
|
||||
return this.bonusDamageShields;
|
||||
}
|
||||
|
||||
public void addDamageShield(AbstractEffectModifier mod , DamageShield ds) {
|
||||
this.bonusDamageShields.put(mod, ds);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void updateIfHigher(AbstractEffectModifier mod, Float val) {
|
||||
|
||||
if (this.bonusFloats.containsKey(mod) == false){
|
||||
this.bonusFloats.put(mod, val);
|
||||
return;
|
||||
}
|
||||
float oldVal = this.getFloat(mod.modType, mod.sourceType);
|
||||
|
||||
if (oldVal > val)
|
||||
return;
|
||||
|
||||
this.bonusFloats.put(mod,val);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Read maps
|
||||
|
||||
public void printBonusesToClient(PlayerCharacter pc) {
|
||||
|
||||
|
||||
|
||||
for (ModType modType: this.bonusBools.keySet()){
|
||||
for (SourceType sourceType: this.bonusBools.get(modType).keySet()){
|
||||
ChatManager.chatSystemInfo(pc, modType.name() + "-" + sourceType.name() + " = " + this.bonusBools.get(modType).get(sourceType));
|
||||
}
|
||||
}
|
||||
|
||||
for (ModType modType : ModType.values()){
|
||||
|
||||
if (modType.equals(ModType.StaminaRecoverRate) || modType.equals(ModType.HealthRecoverRate) || modType.equals(ModType.ManaRecoverRate))
|
||||
ChatManager.chatSystemInfo(pc, modType.name() + " = " + this.getRegen(modType));
|
||||
else
|
||||
for (SourceType sourceType : SourceType.values()){
|
||||
float amount = this.getFloat(modType, sourceType);
|
||||
float percentAmount = this.getFloatPercentPositive(modType, sourceType);
|
||||
float percentAmountNegative = this.getFloatPercentNegative(modType, sourceType);
|
||||
|
||||
if (amount != 0)
|
||||
ChatManager.chatSystemInfo(pc, modType.name() + "-" + (sourceType.equals(SourceType.None) == false ? sourceType.name() : "") + " = " + amount);
|
||||
|
||||
if (percentAmount != 0)
|
||||
ChatManager.chatSystemInfo(pc, "Percent : " + modType.name() + "-" + (sourceType.equals(SourceType.None) == false ? sourceType.name() : "") + " = " + percentAmount);
|
||||
|
||||
if (percentAmountNegative != 0)
|
||||
ChatManager.chatSystemInfo(pc, "Negative Percent : " + modType.name() + "-" + (sourceType.equals(SourceType.None) == false ? sourceType.name() : "") + " = " + percentAmountNegative);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void setBool(ModType modType, SourceType sourceType , boolean val) {
|
||||
if (val == true){
|
||||
|
||||
if (this.bonusBools.get(modType) == null){
|
||||
HashMap<SourceType, Boolean> sourceMap = new HashMap<>();
|
||||
this.bonusBools.put(modType, sourceMap);
|
||||
}
|
||||
|
||||
this.bonusBools.get(modType).put(sourceType, val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.bonusBools.containsKey(modType))
|
||||
this.bonusBools.get(modType).remove(sourceType);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,122 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.DispatchChannel;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.SessionManager;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.UpdateFriendStatusMessage;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class PlayerFriends {
|
||||
|
||||
public int playerUID;
|
||||
public int friendUID;
|
||||
|
||||
public static HashMap <Integer,HashSet<Integer>> PlayerFriendsMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public PlayerFriends(ResultSet rs) throws SQLException {
|
||||
this.playerUID = rs.getInt("playerUID");
|
||||
this.friendUID = rs.getInt("friendUID");
|
||||
|
||||
//cache player friends.
|
||||
//hashset already created, just add to set.
|
||||
if (PlayerFriendsMap.containsKey(playerUID)){
|
||||
HashSet<Integer> playerFriendSet = PlayerFriendsMap.get(playerUID);
|
||||
playerFriendSet.add(friendUID);
|
||||
//hashset not yet created, create new set, and add to map.
|
||||
}else{
|
||||
HashSet<Integer> playerFriendSet = new HashSet<>();
|
||||
playerFriendSet.add(friendUID);
|
||||
PlayerFriendsMap.put(this.playerUID, playerFriendSet);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public PlayerFriends(int playerUID, int friendUID) {
|
||||
super();
|
||||
this.playerUID = playerUID;
|
||||
this.friendUID = friendUID;
|
||||
}
|
||||
|
||||
public int getPlayerUID() {
|
||||
return playerUID;
|
||||
}
|
||||
|
||||
public static void AddToFriends(int playerID, int friendID){
|
||||
HashSet<Integer> friends = PlayerFriendsMap.get(playerID);
|
||||
|
||||
if (friends != null){
|
||||
//already in friends list, don't do anything.
|
||||
if (friends.contains(friendID))
|
||||
return;
|
||||
|
||||
DbManager.PlayerCharacterQueries.ADD_FRIEND(playerID, friendID);
|
||||
friends.add(friendID);
|
||||
}else{
|
||||
friends = new HashSet<>();
|
||||
DbManager.PlayerCharacterQueries.ADD_FRIEND(playerID, friendID);
|
||||
friends.add(friendID);
|
||||
PlayerFriendsMap.put(playerID, friends);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveFromFriends(int playerID, int friendID){
|
||||
|
||||
if (!CanRemove(playerID, friendID))
|
||||
return;
|
||||
|
||||
HashSet<Integer> friends = PlayerFriendsMap.get(playerID);
|
||||
|
||||
if (friends != null){
|
||||
DbManager.PlayerCharacterQueries.REMOVE_FRIEND(playerID, friendID);
|
||||
friends.remove(friendID);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean CanRemove(int playerID, int toRemove){
|
||||
if (PlayerFriendsMap.get(playerID) == null)
|
||||
return false;
|
||||
|
||||
if (PlayerFriendsMap.get(playerID).isEmpty())
|
||||
return false;
|
||||
|
||||
if (!PlayerFriendsMap.get(playerID).contains(toRemove))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void SendFriendsStatus(PlayerCharacter player, boolean online ){
|
||||
HashSet<Integer> friendsSet = PlayerFriends.PlayerFriendsMap.get(player.getObjectUUID());
|
||||
if (friendsSet != null){
|
||||
for(int friendID: friendsSet){
|
||||
PlayerCharacter friend = SessionManager.getPlayerCharacterByID(friendID);
|
||||
if (friend == null)
|
||||
continue;
|
||||
UpdateFriendStatusMessage outMsg = new UpdateFriendStatusMessage(player);
|
||||
outMsg.online = online;
|
||||
Dispatch dispatch = Dispatch.borrow(friend, outMsg);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.RunegateType;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.gameManager.ConfigManager;
|
||||
import engine.job.JobScheduler;
|
||||
import engine.jobs.CloseGateJob;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/* A Runegate object holds an array of these
|
||||
* portals. This class controls their triggers
|
||||
* and visual effects.
|
||||
*/
|
||||
|
||||
public class Portal {
|
||||
|
||||
private boolean active;
|
||||
private RunegateType sourceGateType;
|
||||
private RunegateType portalType;
|
||||
private RunegateType destinationGateType;
|
||||
private final Vector3fImmutable portalLocation;
|
||||
private long lastActive = 0;
|
||||
|
||||
public Portal(RunegateType gateType, RunegateType portalType, RunegateType destinationGate) {
|
||||
|
||||
Building gateBuilding;
|
||||
|
||||
this.active = false;
|
||||
this.sourceGateType = gateType;
|
||||
this.destinationGateType = destinationGate;
|
||||
this.portalType = portalType;
|
||||
|
||||
gateBuilding = this.sourceGateType.getGateBuilding();
|
||||
|
||||
if (gateBuilding == null) {
|
||||
Logger.error("Gate building " + this.sourceGateType.getGateUUID() + " for " + this.sourceGateType.name() + " missing");
|
||||
}
|
||||
|
||||
this.portalLocation = gateBuilding.getLoc().add(new Vector3fImmutable(portalType.getOffset().x, 6, portalType.getOffset().y));
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
|
||||
return this.active;
|
||||
|
||||
}
|
||||
|
||||
public void deactivate() {
|
||||
|
||||
Building sourceBuilding;
|
||||
|
||||
// Remove effect bit from the runegate building, which turns off this
|
||||
// portal type's particle effect
|
||||
|
||||
sourceBuilding = this.sourceGateType.getGateBuilding();
|
||||
sourceBuilding.removeEffectBit(portalType.getEffectFlag());
|
||||
this.active = false;
|
||||
sourceBuilding.updateEffects();
|
||||
}
|
||||
|
||||
public void activate(boolean autoClose) {
|
||||
|
||||
Building sourceBuilding;
|
||||
|
||||
|
||||
// Apply effect bit to the runegate building, which turns on this
|
||||
// portal type's particle effect
|
||||
|
||||
sourceBuilding = this.sourceGateType.getGateBuilding();
|
||||
sourceBuilding.addEffectBit(portalType.getEffectFlag());
|
||||
this.lastActive = System.currentTimeMillis();
|
||||
this.active = true;
|
||||
|
||||
// Do not update effects at bootstrap as it
|
||||
// tries to send a dispatch.
|
||||
|
||||
if (ConfigManager.worldServer.isRunning == true)
|
||||
sourceBuilding.updateEffects();
|
||||
|
||||
if (autoClose == true) {
|
||||
CloseGateJob cgj = new CloseGateJob(sourceBuilding, portalType);
|
||||
JobScheduler.getInstance().scheduleJob(cgj, MBServerStatics.RUNEGATE_CLOSE_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
public void collide() {
|
||||
|
||||
HashSet<AbstractWorldObject> playerList;
|
||||
|
||||
playerList = WorldGrid.getObjectsInRangePartial(this.portalLocation, 2, MBServerStatics.MASK_PLAYER);
|
||||
|
||||
if (playerList.isEmpty())
|
||||
return;
|
||||
|
||||
for (AbstractWorldObject player : playerList) {
|
||||
|
||||
onEnter((PlayerCharacter) player);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void onEnter(PlayerCharacter player) {
|
||||
|
||||
if (player.getTimeStamp("lastMoveGate") < this.lastActive)
|
||||
return;
|
||||
Building gateBuilding;
|
||||
|
||||
gateBuilding = destinationGateType.getGateBuilding();
|
||||
|
||||
if (gateBuilding != null){
|
||||
player.teleport(gateBuilding.getLoc());
|
||||
player.setSafeMode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the sourceGateType
|
||||
*/
|
||||
public RunegateType getSourceGateType() {
|
||||
return sourceGateType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sourceGateType the sourceGateType to set
|
||||
*/
|
||||
public void setSourceGateType(RunegateType sourceGateType) {
|
||||
this.sourceGateType = sourceGateType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the portalType
|
||||
*/
|
||||
public RunegateType getPortalType() {
|
||||
return portalType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param portalType the portalType to set
|
||||
*/
|
||||
public void setPortalType(RunegateType portalType) {
|
||||
this.portalType = portalType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the destinationGateType
|
||||
*/
|
||||
public RunegateType getDestinationGateType() {
|
||||
return destinationGateType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param destinationGateType the destinationGateType to set
|
||||
*/
|
||||
public void setDestinationGateType(RunegateType destinationGateType) {
|
||||
this.destinationGateType = destinationGateType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the portalLocation
|
||||
*/
|
||||
public Vector3fImmutable getPortalLocation() {
|
||||
return portalLocation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
|
||||
|
||||
public class PowerGrant extends AbstractGameObject {
|
||||
|
||||
private int token;
|
||||
private ConcurrentHashMap<Integer, Short> runeGrants = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private static ConcurrentHashMap<Integer, PowerGrant> grantedPowers = null;
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public PowerGrant(ResultSet rs) throws SQLException {
|
||||
super();
|
||||
this.token = rs.getInt("powerToken");
|
||||
runeGrants.put(rs.getInt("runeID"), rs.getShort("grantAmount"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
|
||||
public ConcurrentHashMap<Integer, Short> getRuneGrants() {
|
||||
return this.runeGrants;
|
||||
}
|
||||
|
||||
public int getToken() {
|
||||
return this.token;
|
||||
}
|
||||
|
||||
private void addRuneGrant(int runeID, short amount) {
|
||||
this.runeGrants.put(runeID, amount);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Database
|
||||
*/
|
||||
|
||||
public static Short getGrantedTrains(int token, PlayerCharacter pc) {
|
||||
if (pc == null)
|
||||
return (short) 0;
|
||||
|
||||
if (PowerGrant.grantedPowers == null)
|
||||
fillGrantedPowers();
|
||||
|
||||
if (PowerGrant.grantedPowers.containsKey(token)) {
|
||||
PowerGrant pg = PowerGrant.grantedPowers.get(token);
|
||||
ConcurrentHashMap<Integer, Short> runeGrants = pg.runeGrants;
|
||||
ArrayList<Integer> toks = new ArrayList<>();
|
||||
|
||||
//get race ID
|
||||
Race race = pc.getRace();
|
||||
if (race != null)
|
||||
toks.add(race.getRaceRuneID());
|
||||
|
||||
//get baseClass ID
|
||||
BaseClass bc = pc.getBaseClass();
|
||||
if (bc != null)
|
||||
toks.add(bc.getObjectUUID());
|
||||
|
||||
//get promoClass ID
|
||||
PromotionClass pcc = pc.getPromotionClass();
|
||||
if (pcc != null)
|
||||
toks.add(pcc.getObjectUUID());
|
||||
|
||||
//get promotion and base class combined ID
|
||||
if (bc != null && pcc != null)
|
||||
toks.add( ((pcc.getObjectUUID() * 10) + bc.getObjectUUID()) );
|
||||
|
||||
//get any other rune IDs
|
||||
ArrayList<CharacterRune> runes = pc.getRunes();
|
||||
for (CharacterRune rune : runes)
|
||||
toks.add(rune.getRuneBaseID());
|
||||
|
||||
//Add any power bonuses granted from runes up
|
||||
short amount = (short) 0;
|
||||
for (Integer tok : toks) {
|
||||
if (runeGrants.containsKey(tok))
|
||||
amount += runeGrants.get(tok);
|
||||
}
|
||||
|
||||
return amount;
|
||||
} else
|
||||
return (short) 0;
|
||||
}
|
||||
|
||||
public static void fillGrantedPowers() {
|
||||
PowerGrant.grantedPowers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
PreparedStatementShared ps = null;
|
||||
try {
|
||||
ps = prepareStatement("SELECT * FROM static_power_powergrant");
|
||||
ResultSet rs = ps.executeQuery();
|
||||
if (PowerGrant.grantedPowers.size() > 0) {
|
||||
rs.close();
|
||||
return;
|
||||
}
|
||||
while (rs.next()) {
|
||||
int token = rs.getInt("powerToken");
|
||||
PowerGrant pg = null;
|
||||
if (PowerGrant.grantedPowers.containsKey(token)) {
|
||||
pg = PowerGrant.grantedPowers.get(token);
|
||||
pg.addRuneGrant(rs.getInt("runeID"), rs.getShort("grantAmount"));
|
||||
} else {
|
||||
pg = new PowerGrant(rs);
|
||||
PowerGrant.grantedPowers.put(token, pg);
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
} catch (SQLException e) {
|
||||
Logger.error( "SQL Error number: " + e.getErrorCode(), e);
|
||||
} finally {
|
||||
ps.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.powers.PowersBase;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class PowerReq extends AbstractGameObject implements Comparable<PowerReq> {
|
||||
|
||||
private PowersBase powersBase;
|
||||
private int token;
|
||||
private short level;
|
||||
private ConcurrentHashMap<Integer, Byte> powerReqs;
|
||||
private ConcurrentHashMap<Integer, Byte> skillReqs;
|
||||
|
||||
private static ConcurrentHashMap<Integer, ArrayList<PowerReq>> runePowers = fillRunePowers();
|
||||
private static ArrayList<PowerReq> powersForAll = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public PowerReq(PowersBase powersBase, short level, ConcurrentHashMap<Integer, Byte> powerReqs, ConcurrentHashMap<Integer, Byte> skillReqs) {
|
||||
super();
|
||||
this.powersBase = powersBase;
|
||||
this.level = level;
|
||||
this.powerReqs = powerReqs;
|
||||
this.skillReqs = skillReqs;
|
||||
if (this.powersBase != null)
|
||||
this.token = this.powersBase.getToken();
|
||||
else
|
||||
this.token = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public PowerReq(PowersBase powersBase, short level, ConcurrentHashMap<Integer, Byte> powerReqs, ConcurrentHashMap<Integer, Byte> skillReqs, int newUUID) {
|
||||
super(newUUID);
|
||||
this.powersBase = powersBase;
|
||||
this.level = level;
|
||||
this.powerReqs = powerReqs;
|
||||
this.skillReqs = skillReqs;
|
||||
if (this.powersBase != null)
|
||||
this.token = this.powersBase.getToken();
|
||||
else
|
||||
this.token = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public PowerReq(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
this.token = rs.getInt("powerToken");
|
||||
this.powersBase = PowersManager.getPowerByToken(this.token);
|
||||
this.level = rs.getShort("level");
|
||||
int type = rs.getInt("type");
|
||||
this.powerReqs = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
this.skillReqs = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
if (type == 1)
|
||||
this.skillReqs.put(rs.getInt("requiredToken"), rs.getByte("requiredAmount"));
|
||||
else if (type == 2)
|
||||
this.powerReqs.put(rs.getInt("requiredToken"), rs.getByte("requiredAmount"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public PowersBase getPowersBase() {
|
||||
if (this.powersBase == null) {
|
||||
this.powersBase = PowersManager.getPowerByToken(this.token);
|
||||
}
|
||||
return this.powersBase;
|
||||
}
|
||||
|
||||
public short getLevel() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<Integer, Byte> getPowerReqs() {
|
||||
return this.powerReqs;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<Integer, Byte> getSkillReqs() {
|
||||
return this.skillReqs;
|
||||
}
|
||||
|
||||
public int getToken() {
|
||||
return this.token;
|
||||
}
|
||||
|
||||
private void addPower(int token, byte amount) {
|
||||
this.powerReqs.put(token, amount);
|
||||
}
|
||||
|
||||
private void addSkill(int token, byte amount) {
|
||||
this.skillReqs.put(token, amount);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compareTo(PowerReq n) throws ClassCastException {
|
||||
if (n.level == this.level)
|
||||
return 0;
|
||||
else if (this.level > n.level)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Database
|
||||
*/
|
||||
|
||||
public static ArrayList<PowerReq> getPowerReqsForRune(int id) {
|
||||
// if (PowerReq.runePowers == null)
|
||||
// fillRunePowers();
|
||||
if (PowerReq.runePowers.containsKey(id))
|
||||
return PowerReq.runePowers.get(id);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public static ConcurrentHashMap<Integer, ArrayList<PowerReq>> fillRunePowers() {
|
||||
PowerReq.runePowers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
PreparedStatementShared ps = null;
|
||||
try {
|
||||
ps = prepareStatement("SELECT * FROM static_power_powerrequirement");
|
||||
ResultSet rs = ps.executeQuery();
|
||||
if (PowerReq.runePowers.size() > 0) {
|
||||
rs.close();
|
||||
return PowerReq.runePowers;
|
||||
}
|
||||
while (rs.next()) {
|
||||
ArrayList<PowerReq> runePR = null;
|
||||
int runeID = rs.getInt("runeID");
|
||||
int token = rs.getInt("powerToken");
|
||||
if (PowerReq.runePowers.containsKey(runeID))
|
||||
runePR = PowerReq.runePowers.get(runeID);
|
||||
else {
|
||||
runePR = new ArrayList<>();
|
||||
PowerReq.runePowers.put(runeID, runePR);
|
||||
}
|
||||
boolean found = false;
|
||||
for (PowerReq pr : runePR) {
|
||||
if (pr.token == token) {
|
||||
int type = rs.getInt("type");
|
||||
if (type == 1)
|
||||
pr.addSkill(rs.getInt("requiredToken"), rs.getByte("requiredAmount"));
|
||||
else
|
||||
pr.addPower(rs.getInt("requiredToken"), rs.getByte("requiredAmount"));
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
PowerReq pr = new PowerReq(rs);
|
||||
runePR.add(pr);
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
|
||||
//order the lists by level so prerequisites are met
|
||||
for (ArrayList<PowerReq> runePR : PowerReq.runePowers.values()) {
|
||||
Collections.sort(runePR);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error( "SQL Error number: " + e.getErrorCode(), e);
|
||||
} finally {
|
||||
ps.release();
|
||||
}
|
||||
return PowerReq.runePowers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
public class PowersBaseAttribute extends AbstractGameObject {
|
||||
|
||||
private final short attributeID;
|
||||
private final short modValue;
|
||||
private final short castTime;
|
||||
private final short duration;
|
||||
private final short recycleTime;
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public PowersBaseAttribute(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
this.attributeID = rs.getShort("attributeID");
|
||||
this.modValue = rs.getShort("modValue");
|
||||
this.castTime = rs.getShort("castTime");
|
||||
this.duration = rs.getShort("duration");
|
||||
this.recycleTime = rs.getShort("recycleTime");
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public short getAttributeID() {
|
||||
return attributeID;
|
||||
}
|
||||
|
||||
public short getModValue() {
|
||||
return modValue;
|
||||
}
|
||||
|
||||
public short getCastTime() {
|
||||
return castTime;
|
||||
}
|
||||
|
||||
public short getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public short getRecycleTime() {
|
||||
return recycleTime;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Create update logic.
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,236 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.DispatchChannel;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.net.DispatchMessage;
|
||||
import engine.net.client.msg.ItemProductionMsg;
|
||||
import engine.powers.EffectsBase;
|
||||
import org.joda.time.DateTime;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
|
||||
public class ProducedItem {
|
||||
|
||||
private int ID;
|
||||
private int npcUID;
|
||||
private int itemBaseID;
|
||||
private DateTime dateToUpgrade;
|
||||
private boolean isRandom;
|
||||
|
||||
private String prefix;
|
||||
private String suffix;
|
||||
private String name;
|
||||
private int amount;
|
||||
private int producedItemID = 0;
|
||||
private boolean inForge;
|
||||
private int value;
|
||||
|
||||
private int playerID;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public ProducedItem(ResultSet rs) throws SQLException {
|
||||
this.ID = rs.getInt("ID");
|
||||
this.npcUID = rs.getInt("npcUID");
|
||||
this.itemBaseID = rs.getInt("itemBaseID");
|
||||
|
||||
Date sqlDateTime = rs.getTimestamp("dateToUpgrade");
|
||||
|
||||
if (sqlDateTime != null)
|
||||
this.dateToUpgrade = new DateTime(sqlDateTime);
|
||||
else
|
||||
dateToUpgrade = null;
|
||||
this.isRandom = rs.getBoolean("isRandom");
|
||||
this.prefix = rs.getString("prefix");
|
||||
this.suffix = rs.getString("suffix");
|
||||
this.name = rs.getString("name");
|
||||
this.inForge = rs.getBoolean("inForge");
|
||||
this.value = rs.getInt("value");
|
||||
this.playerID = rs.getInt("playerID");
|
||||
}
|
||||
|
||||
public ProducedItem(int ID,int npcUID, int itemBaseID, DateTime dateToUpgrade, boolean isRandom, String prefix, String suffix, String name, int playerID) {
|
||||
super();
|
||||
this.ID = ID;
|
||||
this.npcUID = npcUID;
|
||||
this.itemBaseID = itemBaseID;
|
||||
this.dateToUpgrade = dateToUpgrade;
|
||||
this.isRandom = isRandom;
|
||||
this.prefix = prefix;
|
||||
this.suffix = suffix;
|
||||
this.name = name;
|
||||
this.value = 0;
|
||||
this.playerID = playerID;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public int getNpcUID() {
|
||||
return npcUID;
|
||||
}
|
||||
public DateTime getDateToUpgrade() {
|
||||
return dateToUpgrade;
|
||||
}
|
||||
|
||||
public int getItemBaseID() {
|
||||
return itemBaseID;
|
||||
}
|
||||
|
||||
public void setItemBaseID(int itemBaseID) {
|
||||
this.itemBaseID = itemBaseID;
|
||||
}
|
||||
|
||||
public boolean isRandom() {
|
||||
return isRandom;
|
||||
}
|
||||
|
||||
public void setRandom(boolean isRandom) {
|
||||
this.isRandom = isRandom;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public String getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
public void setSuffix(String suffix) {
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getID() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public void setID(int iD) {
|
||||
ID = iD;
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(int amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
|
||||
public int getProducedItemID() {
|
||||
return producedItemID;
|
||||
}
|
||||
|
||||
public void setProducedItemID(int producedItemID) {
|
||||
this.producedItemID = producedItemID;
|
||||
}
|
||||
|
||||
public boolean isInForge() {
|
||||
return inForge;
|
||||
}
|
||||
|
||||
public void setInForge(boolean inForge) {
|
||||
this.inForge = inForge;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean finishProduction(){
|
||||
NPC npc = NPC.getFromCache(this.getNpcUID());
|
||||
|
||||
if (npc == null)
|
||||
return false;
|
||||
|
||||
|
||||
//update the client to ID the item in the window when item finishes rolling.
|
||||
//If there is more than 1 item left to roll, complete the item and throw it in inventory
|
||||
//and reproduce next item.
|
||||
|
||||
try{
|
||||
|
||||
if(this.getAmount() > 1){
|
||||
this.setAmount(this.getAmount() - 1);
|
||||
npc.completeItem(this.getProducedItemID());
|
||||
|
||||
int pToken = 0;
|
||||
int sToken = 0;
|
||||
|
||||
if (!this.isRandom()){
|
||||
EffectsBase eb = PowersManager.getEffectByIDString(this.getPrefix());
|
||||
if (eb != null)
|
||||
pToken = eb.getToken();
|
||||
eb = PowersManager.getEffectByIDString(this.getSuffix());
|
||||
if (eb != null)
|
||||
sToken = eb.getToken();
|
||||
|
||||
}
|
||||
|
||||
Item item = npc.produceItem(0,this.getAmount(),this.isRandom(),pToken,sToken,this.getName(),this.getItemBaseID());
|
||||
|
||||
if (item == null)
|
||||
return false;
|
||||
|
||||
}else{
|
||||
|
||||
//update item to complete
|
||||
MobLoot targetItem = MobLoot.getFromCache(this.getProducedItemID());
|
||||
|
||||
if (targetItem == null)
|
||||
return false;
|
||||
|
||||
ItemProductionMsg outMsg = new ItemProductionMsg(npc.getBuilding(), npc, targetItem, 8, true);
|
||||
|
||||
|
||||
|
||||
DispatchMessage.dispatchMsgToInterestArea(npc, outMsg, DispatchChannel.SECONDARY, 700, false, false);
|
||||
}
|
||||
|
||||
}catch(Exception e){
|
||||
Logger.error(e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getPlayerID() {
|
||||
return playerID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.GameObjectType;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.net.ByteBufferWriter;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class PromotionClass extends AbstractGameObject {
|
||||
|
||||
private final String name;
|
||||
private final String description;
|
||||
private int token = 0;
|
||||
|
||||
private final float healthMod;
|
||||
private final float manaMod;
|
||||
private final float staminaMod;
|
||||
|
||||
private final ArrayList<Integer> allowedRunes;
|
||||
private final ArrayList<SkillReq> skillsGranted;
|
||||
private final ArrayList<PowerReq> powersGranted;
|
||||
private final ArrayList<RuneBaseEffect> effectsGranted;
|
||||
private final ArrayList<RuneBaseEffect> effectsGrantedFighter;
|
||||
private final ArrayList<RuneBaseEffect> effectsGrantedHealer;
|
||||
private final ArrayList<RuneBaseEffect> effectsGrantedRogue;
|
||||
private final ArrayList<RuneBaseEffect> effectsGrantedMage;
|
||||
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public PromotionClass(String name, String description,
|
||||
ArrayList<Integer> allowedRunes, ArrayList<SkillReq> skillsGranted, ArrayList<PowerReq> powersGranted) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.allowedRunes = allowedRunes;
|
||||
this.skillsGranted = skillsGranted;
|
||||
this.powersGranted = powersGranted;
|
||||
this.healthMod = 0f;
|
||||
this.manaMod = 0f;
|
||||
this.staminaMod = 0f;
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
this.effectsGrantedFighter = new ArrayList<>();
|
||||
this.effectsGrantedHealer = new ArrayList<>();
|
||||
this.effectsGrantedRogue = new ArrayList<>();
|
||||
this.effectsGrantedMage = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public PromotionClass(String name, String description,
|
||||
ArrayList<Integer> allowedRunes, ArrayList<SkillReq> skillsGranted, ArrayList<PowerReq> powersGranted, int newUUID) {
|
||||
super(newUUID);
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.allowedRunes = allowedRunes;
|
||||
this.skillsGranted = skillsGranted;
|
||||
this.powersGranted = powersGranted;
|
||||
this.healthMod = 0f;
|
||||
this.manaMod = 0f;
|
||||
this.staminaMod = 0f;
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
this.effectsGrantedFighter = new ArrayList<>();
|
||||
this.effectsGrantedHealer = new ArrayList<>();
|
||||
this.effectsGrantedRogue = new ArrayList<>();
|
||||
this.effectsGrantedMage = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public PromotionClass(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
this.name = rs.getString("name");
|
||||
this.description = rs.getString("description");
|
||||
this.token = rs.getInt("token");
|
||||
this.healthMod = rs.getFloat("healthMod");
|
||||
this.manaMod = rs.getFloat("manaMod");
|
||||
this.staminaMod = rs.getFloat("staminaMod");
|
||||
this.allowedRunes = DbManager.PromotionQueries.GET_ALLOWED_RUNES(this);
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.getObjectUUID());
|
||||
this.effectsGrantedFighter = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2500);
|
||||
this.effectsGrantedHealer = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2501);
|
||||
this.effectsGrantedRogue = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2502);
|
||||
this.effectsGrantedMage = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2503);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID());
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public int getToken() {
|
||||
return this.token;
|
||||
}
|
||||
|
||||
public float getHealthMod() {
|
||||
return this.healthMod;
|
||||
}
|
||||
|
||||
public float getManaMod() {
|
||||
return this.manaMod;
|
||||
}
|
||||
|
||||
public float getStaminaMod() {
|
||||
return this.staminaMod;
|
||||
}
|
||||
|
||||
public boolean isAllowedRune(int token) {
|
||||
for (int b : this.allowedRunes) {
|
||||
if (token == b) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getRuneList() {
|
||||
return this.allowedRunes;
|
||||
}
|
||||
|
||||
public ArrayList<SkillReq> getSkillsGranted() {
|
||||
return this.skillsGranted;
|
||||
}
|
||||
|
||||
public ArrayList<PowerReq> getPowersGranted() {
|
||||
return this.powersGranted;
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
||||
return this.effectsGranted;
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseEffect> getEffectsGranted(int baseClassID) {
|
||||
if (baseClassID == 2500)
|
||||
return this.effectsGrantedFighter;
|
||||
else if (baseClassID == 2501)
|
||||
return this.effectsGrantedHealer;
|
||||
else if (baseClassID == 2502)
|
||||
return this.effectsGrantedRogue;
|
||||
else if (baseClassID == 2503)
|
||||
return this.effectsGrantedMage;
|
||||
else
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/*
|
||||
* Serializing
|
||||
*/
|
||||
|
||||
public static void serializeForClientMsg(PromotionClass promotionClass, ByteBufferWriter writer) {
|
||||
writer.putInt(3); // For BaseClass
|
||||
writer.putInt(0); // Pad
|
||||
writer.putInt(promotionClass.getObjectUUID());
|
||||
writer.putInt(promotionClass.getObjectType().ordinal());
|
||||
writer.putInt(promotionClass.getObjectUUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Create update logic.
|
||||
}
|
||||
|
||||
public static PromotionClass GetPromtionClassFromCache(int runeID){
|
||||
if (runeID == 0)
|
||||
return null;
|
||||
return (PromotionClass) DbManager.getFromCache(GameObjectType.PromotionClass, runeID);
|
||||
}
|
||||
|
||||
public ArrayList<MobBaseEffects> getEffectsList() {
|
||||
return effectsList;
|
||||
}
|
||||
|
||||
public void setEffectsList(ArrayList<MobBaseEffects> effectsList) {
|
||||
this.effectsList = effectsList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,368 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.Enum.RaceType;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class Race {
|
||||
|
||||
// Local class cache
|
||||
|
||||
private static ConcurrentHashMap<Integer, Race> _raceByID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final int raceRuneID;
|
||||
private Enum.RaceType raceType;
|
||||
private final short strStart;
|
||||
private final short strMin;
|
||||
private final short strMax;
|
||||
|
||||
private final short dexStart;
|
||||
private final short dexMin;
|
||||
private final short dexMax;
|
||||
|
||||
private final short conStart;
|
||||
private final short conMin;
|
||||
private final short conMax;
|
||||
|
||||
private final short intStart;
|
||||
private final short intMin;
|
||||
private final short intMax;
|
||||
|
||||
private final short spiStart;
|
||||
private final short spiMin;
|
||||
private final short spiMax;
|
||||
|
||||
private final short healthBonus;
|
||||
private final short manaBonus;
|
||||
private final short staminaBonus;
|
||||
|
||||
private final byte startingPoints;
|
||||
|
||||
private final float minHeight;
|
||||
private final float strHeightMod;
|
||||
|
||||
private int token = 0;
|
||||
|
||||
private HashSet<Integer> hairStyles;
|
||||
private HashSet<Integer> beardStyles;
|
||||
|
||||
private final HashSet<Integer> skinColors;
|
||||
private final HashSet<Integer> beardColors;
|
||||
private final HashSet<Integer> hairColors;
|
||||
|
||||
private final ArrayList<BaseClass> baseClasses;
|
||||
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
||||
|
||||
|
||||
private final ArrayList<SkillReq> skillsGranted;
|
||||
private final ArrayList<PowerReq> powersGranted;
|
||||
|
||||
public static void loadAllRaces() {
|
||||
Race._raceByID = DbManager.RaceQueries.LOAD_ALL_RACES();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
|
||||
if ((object instanceof Race) == false)
|
||||
return false;
|
||||
|
||||
Race race = (Race) object;
|
||||
|
||||
return this.raceRuneID == race.raceRuneID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.raceRuneID;
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public Race(ResultSet rs) throws SQLException {
|
||||
|
||||
this.raceRuneID = rs.getInt("ID");
|
||||
this.raceType = Enum.RaceType.getRaceTypebyRuneID(raceRuneID);
|
||||
this.name = rs.getString("name");
|
||||
this.description = rs.getString("description");
|
||||
this.strStart = rs.getShort("strStart");
|
||||
this.strMin = rs.getShort("strMin");
|
||||
this.strMax = rs.getShort("strMax");
|
||||
this.dexStart = rs.getShort("dexStart");
|
||||
this.dexMin = rs.getShort("dexMin");
|
||||
this.dexMax = rs.getShort("dexMax");
|
||||
this.conStart = rs.getShort("conStart");
|
||||
this.conMin = rs.getShort("conMin");
|
||||
this.conMax = rs.getShort("conMax");
|
||||
this.intStart = rs.getShort("intStart");
|
||||
this.intMin = rs.getShort("intMin");
|
||||
this.intMax = rs.getShort("intMax");
|
||||
this.spiStart = rs.getShort("spiStart");
|
||||
this.spiMin = rs.getShort("spiMin");
|
||||
this.spiMax = rs.getShort("spiMax");
|
||||
this.token = rs.getInt("token");
|
||||
this.healthBonus = rs.getShort("healthBonus");
|
||||
this.manaBonus = rs.getShort("manaBonus");
|
||||
this.staminaBonus = rs.getShort("staminaBonus");
|
||||
this.startingPoints = rs.getByte("startingPoints");
|
||||
this.raceType = RaceType.getRaceTypebyRuneID(this.raceRuneID);
|
||||
this.minHeight = rs.getFloat("minHeight");
|
||||
this.strHeightMod = rs.getFloat("strHeightMod");
|
||||
this.hairStyles = DbManager.RaceQueries.HAIR_STYLES_FOR_RACE(raceRuneID);
|
||||
this.beardStyles = DbManager.RaceQueries.BEARD_STYLES_FOR_RACE(raceRuneID);
|
||||
this.skinColors = DbManager.RaceQueries.SKIN_COLOR_FOR_RACE(raceRuneID);
|
||||
this.beardColors = DbManager.RaceQueries.BEARD_COLORS_FOR_RACE(raceRuneID);
|
||||
this.hairColors = DbManager.RaceQueries.HAIR_COLORS_FOR_RACE(raceRuneID);
|
||||
this.baseClasses = DbManager.BaseClassQueries.GET_BASECLASS_FOR_RACE(raceRuneID);
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(raceRuneID);
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(raceRuneID);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.raceRuneID);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public short getStrStart() {
|
||||
return strStart;
|
||||
}
|
||||
|
||||
public short getStrMin() {
|
||||
return strMin;
|
||||
}
|
||||
|
||||
public short getStrMax() {
|
||||
return strMax;
|
||||
}
|
||||
|
||||
public short getDexStart() {
|
||||
return dexStart;
|
||||
}
|
||||
|
||||
public short getDexMin() {
|
||||
return dexMin;
|
||||
}
|
||||
|
||||
public short getDexMax() {
|
||||
return dexMax;
|
||||
}
|
||||
|
||||
public short getConStart() {
|
||||
return conStart;
|
||||
}
|
||||
|
||||
public short getConMin() {
|
||||
return conMin;
|
||||
}
|
||||
|
||||
public short getConMax() {
|
||||
return conMax;
|
||||
}
|
||||
|
||||
public short getIntStart() {
|
||||
return intStart;
|
||||
}
|
||||
|
||||
public short getIntMin() {
|
||||
return intMin;
|
||||
}
|
||||
|
||||
public short getIntMax() {
|
||||
return intMax;
|
||||
}
|
||||
|
||||
public short getSpiStart() {
|
||||
return spiStart;
|
||||
}
|
||||
|
||||
public short getSpiMin() {
|
||||
return spiMin;
|
||||
}
|
||||
|
||||
public short getSpiMax() {
|
||||
return spiMax;
|
||||
}
|
||||
|
||||
public byte getStartingPoints() {
|
||||
return startingPoints;
|
||||
}
|
||||
|
||||
public int getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public final HashSet<Integer> getHairStyles() {
|
||||
return hairStyles;
|
||||
}
|
||||
|
||||
public final HashSet<Integer> getBeardStyles() {
|
||||
return beardStyles;
|
||||
}
|
||||
|
||||
public final HashSet<Integer> getBeardColors() {
|
||||
return beardColors;
|
||||
}
|
||||
|
||||
public HashSet<Integer> getHairColors() {
|
||||
return hairColors;
|
||||
}
|
||||
|
||||
public HashSet<Integer> getSkinColors() {
|
||||
return skinColors;
|
||||
}
|
||||
|
||||
public int getNumSkinColors() {
|
||||
return this.skinColors.size();
|
||||
}
|
||||
|
||||
public int getNumHairColors() {
|
||||
return this.hairColors.size();
|
||||
}
|
||||
|
||||
public int getNumBeardColors() {
|
||||
return this.beardColors.size();
|
||||
}
|
||||
|
||||
public final ArrayList<BaseClass> getValidBaseClasses() {
|
||||
return baseClasses;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getAllowedRunes() {
|
||||
return RuneBase.AllowedRaceRunesMap.get(raceRuneID);
|
||||
}
|
||||
|
||||
public ArrayList<SkillReq> getSkillsGranted() {
|
||||
return this.skillsGranted;
|
||||
}
|
||||
|
||||
public ArrayList<PowerReq> getPowersGranted() {
|
||||
return this.powersGranted;
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
||||
return RuneBaseEffect.RuneIDBaseEffectMap.get(this.raceRuneID);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validators
|
||||
*/
|
||||
public boolean isValidBeardStyle(int id) {
|
||||
return this.beardStyles.contains(id);
|
||||
}
|
||||
|
||||
public boolean isValidBeardColor(int id) {
|
||||
return this.beardColors.contains(id);
|
||||
}
|
||||
|
||||
public boolean isValidHairStyle(int id) {
|
||||
return this.hairStyles.contains(id);
|
||||
}
|
||||
|
||||
public boolean isValidHairColor(int id) {
|
||||
return this.hairColors.contains(id);
|
||||
}
|
||||
|
||||
public boolean isValidSkinColor(int id) {
|
||||
return this.skinColors.contains(id);
|
||||
}
|
||||
|
||||
public boolean isAllowedRune(RuneBase rb) {
|
||||
|
||||
if (this.getAllowedRunes() != null)
|
||||
if (this.getAllowedRunes().contains(rb.getObjectUUID()))
|
||||
return true;
|
||||
if (RuneBase.AllowedBaseClassRunesMap.containsKey(111111)){
|
||||
if (RuneBase.AllowedRaceRunesMap.get(111111).contains(rb.getObjectUUID()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public float getHealthBonus() {
|
||||
return this.healthBonus;
|
||||
}
|
||||
|
||||
public float getManaBonus() {
|
||||
return this.manaBonus;
|
||||
}
|
||||
|
||||
public float getStaminaBonus() {
|
||||
return this.staminaBonus;
|
||||
}
|
||||
|
||||
public float getMinHeight() {
|
||||
return this.minHeight;
|
||||
}
|
||||
|
||||
public float getStrHeightMod() {
|
||||
return this.strHeightMod;
|
||||
}
|
||||
|
||||
public float getHeight(short str) {
|
||||
return this.minHeight + (this.strHeightMod * str);
|
||||
}
|
||||
|
||||
public float getCenterHeight(short str) {
|
||||
return getHeight(str) / 2f;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Serializing
|
||||
*/
|
||||
|
||||
public void serializeForClientMsg(ByteBufferWriter writer) {
|
||||
writer.putInt(1); // For Race
|
||||
writer.putInt(0); // Pad
|
||||
writer.putInt(this.raceRuneID);
|
||||
|
||||
writer.putInt(Enum.GameObjectType.Race.ordinal());
|
||||
writer.putInt(raceRuneID);
|
||||
}
|
||||
|
||||
public static Race getRace(int id) {
|
||||
return _raceByID.get(id);
|
||||
}
|
||||
|
||||
public int getRaceRuneID() {
|
||||
return raceRuneID;
|
||||
}
|
||||
|
||||
public Enum.RaceType getRaceType() {
|
||||
return raceType;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<MobBaseEffects> getEffectsList() {
|
||||
return effectsList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,460 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.InterestManagement.RealmMap;
|
||||
import engine.db.archive.DataWarehouse;
|
||||
import engine.db.archive.RealmRecord;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.powers.PowersBase;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static engine.Enum.CharterType;
|
||||
|
||||
|
||||
public class Realm {
|
||||
|
||||
// Internal class cache
|
||||
|
||||
private static ConcurrentHashMap<Integer, Realm> _realms = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
private final float mapR; //Red color
|
||||
private final float mapG; //Green color
|
||||
private final float mapB; //Blue color
|
||||
private final float mapA; //Alpha color
|
||||
private final boolean canBeClaimed;
|
||||
private final boolean canPlaceCities;
|
||||
private final int numCities;
|
||||
private final String realmName;
|
||||
private int rulingCityUUID;
|
||||
private int rulingCharacterUUID;
|
||||
private int rulingCharacterOrdinal;
|
||||
private String rulingCharacterName;
|
||||
private int rulingNationUUID;
|
||||
private GuildTag rulingNationTags;
|
||||
private String rulingNationName;
|
||||
private int charterType;
|
||||
public LocalDateTime ruledSince;
|
||||
private final float mapY1;
|
||||
private final float mapX1;
|
||||
private final float mapY2;
|
||||
private final float mapX2;
|
||||
private final int stretchX;
|
||||
private final int stretchY;
|
||||
private final int locX;
|
||||
private final int locY;
|
||||
private final int realmID;
|
||||
private final HashSet<Integer> cities = new HashSet<>();
|
||||
private String hash;
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public Realm(ResultSet rs) throws SQLException, UnknownHostException {
|
||||
|
||||
this.mapR = rs.getFloat("mapR");
|
||||
this.mapG = rs.getFloat("mapG");
|
||||
this.mapB = rs.getFloat("mapB");
|
||||
this.mapA = rs.getFloat("mapA");
|
||||
this.canBeClaimed = rs.getBoolean("canBeClaimed");
|
||||
this.canPlaceCities = rs.getBoolean("canPlaceCities");
|
||||
this.numCities = rs.getInt("numCities");
|
||||
this.realmName = rs.getString("realmName");
|
||||
this.rulingCityUUID = rs.getInt("rulingCityUID");
|
||||
this.charterType = rs.getInt("charterType");
|
||||
|
||||
java.sql.Timestamp ruledTimeStamp = rs.getTimestamp("ruledSince");
|
||||
|
||||
if (ruledTimeStamp != null)
|
||||
this.ruledSince = LocalDateTime.ofInstant(ruledTimeStamp.toInstant(), ZoneId.systemDefault());
|
||||
|
||||
this.mapY1 = rs.getFloat("mapY1");
|
||||
this.mapX1 = rs.getFloat("mapX1");
|
||||
this.mapY2 = rs.getFloat("mapY2");
|
||||
this.mapX2 = rs.getFloat("mapX2");
|
||||
this.stretchX = rs.getInt("stretchX");
|
||||
this.stretchY = rs.getInt("stretchY");
|
||||
this.locX = rs.getInt("locX");
|
||||
this.locY = rs.getInt("locY");
|
||||
this.realmID = rs.getInt("realmID");
|
||||
this.hash = rs.getString("hash");
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public boolean isRuled() {
|
||||
return (this.rulingCityUUID != 0);
|
||||
}
|
||||
|
||||
public float getMapR() {
|
||||
return this.mapR;
|
||||
}
|
||||
|
||||
public float getMapG() {
|
||||
return this.mapG;
|
||||
}
|
||||
|
||||
public float getMapB() {
|
||||
return this.mapB;
|
||||
}
|
||||
|
||||
public float getMapA() {
|
||||
return this.mapA;
|
||||
}
|
||||
|
||||
public boolean getCanBeClaimed() {
|
||||
return this.canBeClaimed;
|
||||
}
|
||||
|
||||
public boolean getCanPlaceCities() {
|
||||
return this.canPlaceCities;
|
||||
}
|
||||
|
||||
public int getNumCities() {
|
||||
return this.numCities;
|
||||
}
|
||||
|
||||
public String getRealmName() {
|
||||
return this.realmName;
|
||||
}
|
||||
|
||||
public City getRulingCity() {
|
||||
return City.getCity(this.rulingCityUUID);
|
||||
}
|
||||
|
||||
public float getMapY1() {
|
||||
return this.mapY1;
|
||||
}
|
||||
|
||||
public float getMapX1() {
|
||||
return this.mapX1;
|
||||
}
|
||||
|
||||
public float getMapY2() {
|
||||
return this.mapY2;
|
||||
}
|
||||
|
||||
public float getMapX2() {
|
||||
return this.mapX2;
|
||||
}
|
||||
|
||||
public int getStretchX() {
|
||||
return this.stretchX;
|
||||
}
|
||||
|
||||
public int getStretchY() {
|
||||
return this.stretchY;
|
||||
}
|
||||
|
||||
public int getlocX() {
|
||||
return this.locX;
|
||||
}
|
||||
|
||||
public int getlocY() {
|
||||
return this.locY;
|
||||
}
|
||||
|
||||
public int getRealmID() {
|
||||
return this.realmID;
|
||||
}
|
||||
|
||||
public void addCity(int cityUUID) {
|
||||
if (!this.cities.add(cityUUID))
|
||||
this.cities.add(cityUUID);
|
||||
}
|
||||
|
||||
public void removeCity(int cityUUID) {
|
||||
this.cities.remove(cityUUID);
|
||||
}
|
||||
|
||||
public boolean isRealmFull() {
|
||||
|
||||
return this.cities.size() >= this.numCities;
|
||||
}
|
||||
|
||||
public boolean isRealmFullAfterBane() {
|
||||
|
||||
return this.cities.size() > this.numCities;
|
||||
}
|
||||
|
||||
public static void configureAllRealms() {
|
||||
|
||||
Realm serverRealm;
|
||||
int realmID;
|
||||
|
||||
for (Enum.RealmType realmType : Enum.RealmType.values()) {
|
||||
|
||||
realmID = realmType.getRealmID();
|
||||
// Don't serialize seafloor
|
||||
|
||||
if (realmID == 0)
|
||||
continue;
|
||||
|
||||
serverRealm = Realm.getRealm(realmID);
|
||||
serverRealm.configure();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Call this after changing ownership before you serialize a realm
|
||||
|
||||
public void configure() {
|
||||
|
||||
PlayerCharacter rulingCharacter;
|
||||
|
||||
// Configure what exactly? We won't send any of it.
|
||||
|
||||
if (this.rulingCityUUID == 0)
|
||||
return;
|
||||
if (this.getRulingCity() == null)
|
||||
return;
|
||||
if (this.getRulingCity().getTOL() == null)
|
||||
return;
|
||||
|
||||
rulingCharacter = PlayerCharacter.getPlayerCharacter(this.getRulingCity().getTOL().getOwnerUUID());
|
||||
if (rulingCharacter == null){
|
||||
Logger.info( this.realmName + " failed to load " + this.getRulingCity().getCityName() + " ID : " + this.rulingCityUUID);
|
||||
return;
|
||||
}
|
||||
|
||||
this.rulingCharacterUUID = rulingCharacter.getObjectUUID();
|
||||
this.rulingCharacterOrdinal = rulingCharacter.getObjectType().ordinal();
|
||||
this.rulingCharacterName = rulingCharacter.getFirstName() + ' ' + rulingCharacter.getLastName();
|
||||
this.rulingNationUUID = rulingCharacter.getGuild().getNation().getObjectUUID();
|
||||
this.rulingNationName = rulingCharacter.getGuild().getNation().getName();
|
||||
this.rulingNationTags = rulingCharacter.getGuild().getNation().getGuildTag();
|
||||
}
|
||||
|
||||
public void serializeForClientMsg(ByteBufferWriter writer) {
|
||||
|
||||
writer.putFloat(this.mapR);
|
||||
writer.putFloat(this.mapG);
|
||||
writer.putFloat(this.mapB);
|
||||
writer.putFloat(this.mapA);
|
||||
writer.put((byte) (this.canBeClaimed ? 0x1 : 0x0));
|
||||
writer.put((byte) (this.canPlaceCities ? 0x1 : 0x0));
|
||||
writer.putInt(this.numCities);
|
||||
writer.putFloat(this.mapR);
|
||||
writer.putFloat(this.mapG);
|
||||
writer.putFloat(this.mapB);
|
||||
writer.putFloat(this.mapA);
|
||||
writer.putString(this.realmName);
|
||||
|
||||
if (isRuled() == true) {
|
||||
writer.putInt(Enum.GameObjectType.Guild.ordinal());
|
||||
writer.putInt(rulingNationUUID);
|
||||
|
||||
writer.putInt(rulingCharacterOrdinal);
|
||||
writer.putInt(rulingCharacterUUID);
|
||||
|
||||
writer.putInt(Enum.GameObjectType.City.ordinal());
|
||||
writer.putInt(rulingCityUUID);
|
||||
|
||||
writer.putLocalDateTime(this.ruledSince);
|
||||
|
||||
writer.putString(rulingNationName);
|
||||
GuildTag._serializeForDisplay(rulingNationTags,writer);
|
||||
writer.putString(rulingCharacterName);
|
||||
writer.putInt(0xB); // Display Title: enum index starts at 10.
|
||||
} else {
|
||||
if (this.rulingCityUUID != 0)
|
||||
Logger.error( "Failed to Load realm info for city" + this.rulingCityUUID);
|
||||
writer.putLong(0);
|
||||
writer.putLong(0);
|
||||
writer.putLong(0);
|
||||
writer.put((byte) 1);
|
||||
writer.put((byte) 0);
|
||||
writer.putInt(0x64);
|
||||
writer.put((byte) 0);
|
||||
writer.put((byte) 0);
|
||||
writer.put((byte) 0);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0x10);
|
||||
writer.putInt(0x10);
|
||||
writer.putInt(0x10);
|
||||
writer.putInt(0x0);
|
||||
writer.putInt(0x0);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
}
|
||||
writer.putInt(0); // Male/Female
|
||||
writer.putInt(this.charterType); // Charter Type
|
||||
writer.putFloat(this.mapY1);
|
||||
writer.putFloat(this.mapX1);
|
||||
writer.putFloat(this.mapY2);
|
||||
writer.putFloat(this.mapX2);
|
||||
writer.putInt(this.stretchX);
|
||||
writer.putInt(this.stretchY);
|
||||
writer.putInt(this.locX);
|
||||
writer.putInt(this.locY);
|
||||
}
|
||||
|
||||
public void updateDatabase() {
|
||||
DbManager.RealmQueries.REALM_UPDATE(this);
|
||||
}
|
||||
|
||||
public static Realm getRealm(int realmID) {
|
||||
return _realms.get(realmID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the charterType
|
||||
*/
|
||||
public int getCharterType() {
|
||||
return charterType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param charterType the charterType to set
|
||||
*/
|
||||
public void setCharterType(int charterType) {
|
||||
this.charterType = charterType;
|
||||
}
|
||||
|
||||
public void abandonRealm() {
|
||||
|
||||
// Push event to warehouse
|
||||
|
||||
RealmRecord realmRecord = RealmRecord.borrow(this, Enum.RecordEventType.LOST);
|
||||
DataWarehouse.pushToWarehouse(realmRecord);
|
||||
|
||||
// No longer own a realm
|
||||
this.getRulingCity().getGuild().setRealmsOwned(this.getRulingCity().getGuild().getRealmsOwned() - 1);
|
||||
if (!this.getRulingCity().getGuild().getNation().equals(this.getRulingCity().getGuild()))
|
||||
this.getRulingCity().getGuild().getNation().setRealmsOwned(this.getRulingCity().getGuild().getNation().getRealmsOwned() - 1);
|
||||
|
||||
// Configure realm
|
||||
this.charterType = 0;
|
||||
this.rulingCityUUID = 0;
|
||||
this.ruledSince = null;
|
||||
|
||||
this.updateDatabase();
|
||||
}
|
||||
|
||||
public void claimRealmForCity(City city, int charterType) {
|
||||
|
||||
// Configure realm
|
||||
this.charterType = charterType;
|
||||
this.rulingCityUUID = city.getObjectUUID();
|
||||
this.ruledSince = LocalDateTime.now();
|
||||
this.configure();
|
||||
this.updateDatabase();
|
||||
|
||||
// Push event to warehouse
|
||||
|
||||
RealmRecord realmRecord = RealmRecord.borrow(this, Enum.RecordEventType.CAPTURE);
|
||||
DataWarehouse.pushToWarehouse(realmRecord);
|
||||
|
||||
}
|
||||
|
||||
public static boolean HasAllBlessings(PlayerCharacter claimer) {
|
||||
|
||||
if (claimer == null)
|
||||
return false;
|
||||
|
||||
PowersBase powerBlessing = PowersManager.getPowerByIDString("BLS-POWER");
|
||||
if (!claimer.effects.containsKey(Integer.toString(powerBlessing.getActions().get(0).getUUID())))
|
||||
return false;
|
||||
PowersBase wisdomBlessing = PowersManager.getPowerByIDString("BLS-POWER");
|
||||
if (!claimer.effects.containsKey(Integer.toString(wisdomBlessing.getActions().get(0).getUUID())))
|
||||
return false;
|
||||
PowersBase fortuneBlessing = PowersManager.getPowerByIDString("BLS-FORTUNE");
|
||||
return claimer.effects.containsKey(Integer.toString(fortuneBlessing.getActions().get(0).getUUID()));
|
||||
}
|
||||
|
||||
public static float getRealmHealthMod(City city) {
|
||||
Realm serverRealm;
|
||||
int charterType;
|
||||
float returnBonus = 0.0f;
|
||||
|
||||
serverRealm = RealmMap.getRealmForCity(city);
|
||||
charterType = serverRealm.charterType;
|
||||
|
||||
switch (charterType) {
|
||||
|
||||
case 762228431:
|
||||
returnBonus = 0.0f;
|
||||
break;
|
||||
case -15978914:
|
||||
returnBonus = -.15f;
|
||||
break;
|
||||
case -600065291:
|
||||
returnBonus = .15f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return returnBonus;
|
||||
}
|
||||
|
||||
public static int getRealmMesh(City city) {
|
||||
Realm serverRealm;
|
||||
CharterType charterType;
|
||||
|
||||
serverRealm = city.getRealm();
|
||||
charterType = CharterType.getCharterTypeByID(serverRealm.charterType);
|
||||
|
||||
return charterType.getMeshID();
|
||||
}
|
||||
|
||||
public static void loadAllRealms() {
|
||||
|
||||
_realms = DbManager.RealmQueries.LOAD_ALL_REALMS();
|
||||
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public void setHash() {
|
||||
|
||||
this.hash = DataWarehouse.hasher.encrypt(this.realmID);
|
||||
|
||||
// Write hash to player character table
|
||||
|
||||
DataWarehouse.writeHash(Enum.DataRecordType.REALM, this.realmID);
|
||||
}
|
||||
|
||||
/* *** Keeping around in case needed for server wipe or some other emergency
|
||||
|
||||
public static void backfillRealms() {
|
||||
|
||||
// Backfill realm records
|
||||
|
||||
for (Realm realm : _realms.values()) {
|
||||
|
||||
realm.setHash();
|
||||
|
||||
if ( (realm.isRuled() == true) &&
|
||||
(DataWarehouse.recordExists(Enum.DataRecordType.REALM, realm.getRealmID()) == false)) {
|
||||
RealmRecord realmRecord = RealmRecord.borrow(realm, Enum.RecordEventType.CAPTURE);
|
||||
DataWarehouse.pushToWarehouse(realmRecord);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.math.Bounds;
|
||||
import engine.math.FastMath;
|
||||
import engine.math.Vector3f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
|
||||
public class Regions {
|
||||
|
||||
public int room;
|
||||
public boolean outside;
|
||||
public int level;
|
||||
public final boolean stairs;
|
||||
public final boolean exit;
|
||||
public static HashMap<Integer,Regions> FurnitureRegionMap = new HashMap<>();
|
||||
public Vector3fImmutable lowLerp;
|
||||
public Vector3fImmutable highLerp;
|
||||
public Vector3f center;
|
||||
public float regionDistanceSquared;
|
||||
|
||||
public ArrayList<Vector3f> regionPoints;
|
||||
|
||||
public int parentBuildingID;
|
||||
|
||||
|
||||
public Regions(ArrayList<Vector3f> regionPoints, int level, int room, boolean outside, boolean exit,boolean stairs, Vector3f center, int parentBuildingID) {
|
||||
super();
|
||||
|
||||
this.level = level;
|
||||
this.room = room;
|
||||
|
||||
this.outside = (outside);
|
||||
this.regionPoints = regionPoints;
|
||||
this.exit = exit;
|
||||
this.stairs = stairs;
|
||||
this.center = center;
|
||||
this.parentBuildingID = parentBuildingID;
|
||||
//order regionpoints clockwise starting from top left, and ending bottom left.
|
||||
|
||||
ArrayList<Vector3f> top = new ArrayList<>();
|
||||
ArrayList<Vector3f> bottom = new ArrayList<>();
|
||||
|
||||
for (Vector3f point : this.regionPoints){
|
||||
if (point.y > center.y)
|
||||
top.add(point);
|
||||
else if (point.y < center.y)
|
||||
bottom.add(point);
|
||||
}
|
||||
|
||||
|
||||
if (top.size() == 2 && bottom.size() == 2){
|
||||
Vector3f topLeft = Vector3f.min(top.get(0), top.get(1));
|
||||
Vector3f topRight = Vector3f.max(top.get(0), top.get(1));
|
||||
|
||||
Vector3f topCenter = topLeft.lerp(topRight, .5f);
|
||||
|
||||
Vector3f bottomLeft = Vector3f.min(bottom.get(0), bottom.get(1));
|
||||
Vector3f bottomRight = Vector3f.max(bottom.get(0), bottom.get(1));
|
||||
|
||||
Vector3f bottomCenter = bottomLeft.lerp(bottomRight, .5f);
|
||||
|
||||
this.lowLerp = new Vector3fImmutable(bottomCenter);
|
||||
this.highLerp = new Vector3fImmutable(topCenter);
|
||||
|
||||
} else if (top.size() == 2 && bottom.size() == 1){
|
||||
Vector3f topLeft = Vector3f.min(top.get(0), top.get(1));
|
||||
Vector3f topRight = Vector3f.max(top.get(0), top.get(1));
|
||||
|
||||
Vector3f topCenter = topLeft.lerp(topRight, .5f);
|
||||
|
||||
Vector3f topCopy = topRight.subtract2D(topLeft);
|
||||
topCopy.normalize();
|
||||
|
||||
float topMagnitude = topRight.subtract2D(topLeft).length();
|
||||
|
||||
topCopy.multLocal(topMagnitude);
|
||||
|
||||
Vector3f bottomLeft = null;
|
||||
Vector3f bottomRight = null;
|
||||
if (bottom.get(0).distance2D(topLeft) <= bottom.get(0).distance2D(topRight))
|
||||
bottomLeft = bottom.get(0);
|
||||
else if (bottom.get(0).distance2D(topRight) <= bottom.get(0).distance2D(topLeft))
|
||||
bottomRight = bottom.get(0);
|
||||
//find bottom right point
|
||||
|
||||
if (bottomLeft != null){
|
||||
bottomRight = bottomLeft.add(topCopy);
|
||||
}else if (bottomRight != null){
|
||||
bottomLeft = bottomRight.subtract(topCopy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vector3f bottomCenter = bottomLeft.lerp(bottomRight, .5f);
|
||||
|
||||
this.lowLerp = new Vector3fImmutable(bottomCenter);
|
||||
this.highLerp = new Vector3fImmutable(topCenter);
|
||||
|
||||
}else if (bottom.size() == 2 && top.size() == 1){
|
||||
Vector3f topLeft = Vector3f.min(bottom.get(0), bottom.get(1));
|
||||
Vector3f topRight = Vector3f.max(bottom.get(0), bottom.get(1));
|
||||
|
||||
Vector3f topCenter = topLeft.lerp(topRight, .5f);
|
||||
|
||||
Vector3f topCopy = topRight.subtract2D(topLeft);
|
||||
topCopy.normalize();
|
||||
|
||||
float topMagnitude = topRight.subtract2D(topLeft).length();
|
||||
|
||||
topCopy.multLocal(topMagnitude);
|
||||
|
||||
Vector3f bottomLeft = null;
|
||||
Vector3f bottomRight = null;
|
||||
if (top.get(0).distance2D(topLeft) < top.get(0).distance2D(topRight))
|
||||
bottomLeft = bottom.get(0);
|
||||
else if (top.get(0).distance2D(topRight) < top.get(0).distance2D(topLeft))
|
||||
bottomRight = bottom.get(0);
|
||||
//find bottom right point
|
||||
|
||||
if (bottomLeft != null){
|
||||
bottomRight = bottomLeft.add(topCopy);
|
||||
}else if (bottomRight != null){
|
||||
bottomLeft = bottomRight.subtract(topCopy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vector3f bottomCenter = bottomLeft.lerp(bottomRight, .5f);
|
||||
|
||||
this.lowLerp = new Vector3fImmutable(bottomCenter);
|
||||
this.highLerp = new Vector3fImmutable(topCenter);
|
||||
}
|
||||
|
||||
if (this.lowLerp == null)
|
||||
this.lowLerp = new Vector3fImmutable(this.regionPoints.get(0));
|
||||
|
||||
if (this.highLerp == null){
|
||||
this.highLerp = new Vector3fImmutable(this.regionPoints.get(2));
|
||||
}
|
||||
|
||||
this.regionDistanceSquared = this.lowLerp.distanceSquared2D(this.highLerp);
|
||||
}
|
||||
|
||||
public int getRoom() {
|
||||
return room;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public boolean isOutside() {
|
||||
return outside;
|
||||
}
|
||||
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public boolean collides(Vector3fImmutable collisionPoint){
|
||||
|
||||
//test if inside triangle // Regions either have 3 or 4 points
|
||||
if (this.regionPoints.size() == 3){
|
||||
float regionArea = FastMath.area(regionPoints.get(0).x, regionPoints.get(0).z, regionPoints.get(1).x, regionPoints.get(1).z, regionPoints.get(2).x, regionPoints.get(2).z);
|
||||
float collisionArea1 = FastMath.area(collisionPoint.x, collisionPoint.z, regionPoints.get(0).x, regionPoints.get(0).z,regionPoints.get(1).x, regionPoints.get(1).z);
|
||||
float collisionArea2 = FastMath.area(collisionPoint.x, collisionPoint.z, regionPoints.get(1).x, regionPoints.get(1).z,regionPoints.get(2).x, regionPoints.get(2).z);
|
||||
float collisionArea3 = FastMath.area(collisionPoint.x, collisionPoint.z, regionPoints.get(0).x, regionPoints.get(0).z,regionPoints.get(2).x, regionPoints.get(2).z);
|
||||
|
||||
if ((collisionArea1 + collisionArea2 + collisionArea3) == regionArea)
|
||||
return true;
|
||||
|
||||
}else{
|
||||
|
||||
int i;
|
||||
int j;
|
||||
for (i = 0, j = this.regionPoints.size() - 1; i < this.regionPoints.size(); j = i++) {
|
||||
if ((regionPoints.get(i).z > collisionPoint.z) != (regionPoints.get(j).z > collisionPoint.z) &&
|
||||
(collisionPoint.x < (regionPoints.get(j).x - regionPoints.get(i).x) * (collisionPoint.z - regionPoints.get(i).z) / (regionPoints.get(j).z-regionPoints.get(i).z) + regionPoints.get(i).x)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPointInPolygon( Vector3fImmutable point)
|
||||
{
|
||||
boolean inside = false;
|
||||
for (int i = 0, j = regionPoints.size()-1; i < regionPoints.size(); j = i++)
|
||||
{
|
||||
if (((regionPoints.get(i).z > point.z) != (regionPoints.get(j).z > point.z)) &&
|
||||
(point.x < (regionPoints.get(j).x - regionPoints.get(i).x) * (point.z - regionPoints.get(i).z) / (regionPoints.get(j).z - regionPoints.get(i).z) + regionPoints.get(i).x))
|
||||
inside = !inside;
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
|
||||
public static boolean CanEnterRegion(AbstractWorldObject worldObject, Regions toEnter){
|
||||
|
||||
if (worldObject.getRegion() == null)
|
||||
if (toEnter.level == 0 || toEnter.room == -1 || toEnter.exit)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
if (worldObject.getRegion().equals(toEnter))
|
||||
return true;
|
||||
|
||||
if (worldObject.getRegion().level == toEnter.level)
|
||||
return true;
|
||||
|
||||
//next region is stairs, if they are on the same level as stairs or 1 up, world object can enter.
|
||||
if (toEnter.stairs)
|
||||
if (worldObject.getRegion().level == toEnter.level || toEnter.level - 1 == worldObject.getRegion().level)
|
||||
return true;
|
||||
if (worldObject.getRegion().stairs){
|
||||
|
||||
boolean movingUp = false;
|
||||
|
||||
boolean movingDown = false;
|
||||
float yLerp = worldObject.getRegion().lerpY(worldObject);
|
||||
|
||||
if (yLerp == (worldObject.getRegion().highLerp.y))
|
||||
movingUp = true;
|
||||
else if (yLerp == (worldObject.getRegion().lowLerp.y))
|
||||
movingDown = true;
|
||||
//Stairs are always considered on the bottom floor.
|
||||
|
||||
|
||||
if (movingUp){
|
||||
if(toEnter.level == worldObject.getRegion().level + 1)
|
||||
return true;
|
||||
}else if (movingDown)
|
||||
if (toEnter.level == worldObject.getRegion().level)
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public float lerpY (AbstractWorldObject lerper){
|
||||
|
||||
Vector3fImmutable lengthVector = this.highLerp.subtract2D(this.lowLerp);
|
||||
Vector3fImmutable characterVector = lerper.getLoc().subtract2D(this.lowLerp);
|
||||
float lengthVectorMagnitude = lengthVector.magnitude();
|
||||
float characterVectorMagnitude = characterVector.magnitude();
|
||||
float percentDistance = characterVectorMagnitude/lengthVectorMagnitude;
|
||||
float interpolatedY = this.lowLerp.interpolate(this.highLerp, percentDistance).y;
|
||||
|
||||
if (interpolatedY > this.highLerp.y)
|
||||
interpolatedY = this.highLerp.y;
|
||||
else if (interpolatedY < this.lowLerp.y)
|
||||
interpolatedY = this.lowLerp.y;
|
||||
return interpolatedY;
|
||||
}
|
||||
|
||||
|
||||
public boolean isStairs() {
|
||||
return stairs;
|
||||
}
|
||||
|
||||
|
||||
public boolean isExit() {
|
||||
return exit;
|
||||
}
|
||||
|
||||
public static float GetMagnitudeOfRegionSlope(Regions region){
|
||||
Vector3fImmutable lengthVector = region.highLerp.subtract2D(region.lowLerp);
|
||||
return lengthVector.magnitude();
|
||||
}
|
||||
|
||||
public static float GetMagnitudeOfPlayerOnRegionSlope(Regions region, PlayerCharacter player){
|
||||
Vector3fImmutable characterVector = player.getLoc().subtract2D(region.lowLerp);
|
||||
return characterVector.magnitude();
|
||||
}
|
||||
|
||||
public static float SlopeLerpPercent(PlayerCharacter player, Regions region){
|
||||
|
||||
float lengthVectorMagnitude = Regions.GetMagnitudeOfRegionSlope(region);
|
||||
float characterVectorMagnitude = Regions.GetMagnitudeOfPlayerOnRegionSlope(region, player);
|
||||
float percentDistance = characterVectorMagnitude/lengthVectorMagnitude * 2;
|
||||
return percentDistance;
|
||||
}
|
||||
|
||||
public static boolean CanEnterFromOutsideBuilding(Building building,Regions region){
|
||||
if (!region.outside)
|
||||
return false;
|
||||
if (region.lowLerp.y - building.getLoc().y > 1 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean CanEnterNextLevel(Regions fromRegion,Regions toRegion, AbstractWorldObject worldObject){
|
||||
|
||||
if (fromRegion == null)
|
||||
return false;
|
||||
|
||||
if (toRegion == null)
|
||||
return false;
|
||||
|
||||
// regions are the same, no need to go any further.
|
||||
if (fromRegion.equals(toRegion))
|
||||
return true;
|
||||
|
||||
//cant move up a level without stairs.
|
||||
if (!fromRegion.stairs)
|
||||
return false;
|
||||
|
||||
boolean movingUp = false;
|
||||
|
||||
Vector3fImmutable closestPoint = Vector3fImmutable.ClosestPointOnLine(fromRegion.lowLerp, fromRegion.highLerp, worldObject.getLoc());
|
||||
|
||||
//Closest point of a region higher than current region will always return highlerp.
|
||||
if (closestPoint.equals(fromRegion.highLerp))
|
||||
movingUp = true;
|
||||
//Stairs are always considered on the bottom floor.
|
||||
|
||||
if (movingUp){
|
||||
if(toRegion.level != fromRegion.level + 1)
|
||||
return false;
|
||||
}else if (toRegion.level != fromRegion.level)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean IsGroundLevel(Regions region, Building building){
|
||||
|
||||
if (region.lowLerp.y - building.getLoc().y > 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Building GetBuildingForRegion(Regions region){
|
||||
return BuildingManager.getBuildingFromCache(region.parentBuildingID);
|
||||
}
|
||||
public static Regions GetRegionForTeleport(Vector3fImmutable location){
|
||||
Regions region = null;
|
||||
|
||||
|
||||
//Find building
|
||||
for (AbstractWorldObject awo:WorldGrid.getObjectsInRangePartial(location, MBServerStatics.STRUCTURE_LOAD_RANGE, MBServerStatics.MASK_BUILDING)){
|
||||
Building building = (Building)awo;
|
||||
if (!Bounds.collide(location, building.getBounds()))
|
||||
continue;
|
||||
|
||||
//find regions that intersect x and z, check if object can enter.
|
||||
for (Regions toEnter: building.getBounds().getRegions()){
|
||||
if (toEnter.isPointInPolygon(location)){
|
||||
|
||||
if (region == null)
|
||||
region = toEnter;
|
||||
else // we're using a low level to high level tree structure, database not always in order low to high.
|
||||
//check for highest level index.
|
||||
if(region != null && toEnter.highLerp.y > region.highLerp.y)
|
||||
region = toEnter;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return region;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,562 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.Enum.DamageType;
|
||||
import engine.Enum.ModType;
|
||||
import engine.Enum.SourceType;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class Resists {
|
||||
|
||||
private ConcurrentHashMap<DamageType, Float> resists = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private ConcurrentHashMap<DamageType, Boolean> immuneTo = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private DamageType protection;
|
||||
private int protectionTrains=0;
|
||||
private boolean immuneToAll;
|
||||
private static ConcurrentHashMap<Integer, Resists> mobResists = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
/**
|
||||
* Generic Constructor
|
||||
*/
|
||||
|
||||
public Resists(String type) {
|
||||
switch (type) {
|
||||
case "Building":
|
||||
setBuildingResists();
|
||||
break;
|
||||
case "Mine":
|
||||
setMineResists();
|
||||
break;
|
||||
default:
|
||||
setGenericResists();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public Resists(Resists r) {
|
||||
for (DamageType dt : r.resists.keySet())
|
||||
this.resists.put(dt, r.resists.get(dt));
|
||||
for (DamageType dt : r.immuneTo.keySet())
|
||||
this.immuneTo.put(dt, r.immuneTo.get(dt));
|
||||
this.protection = r.protection;
|
||||
this.protectionTrains = r.protectionTrains;
|
||||
this.immuneToAll = r.immuneToAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic Constructor for player
|
||||
*/
|
||||
public Resists(PlayerCharacter pc) {
|
||||
setGenericResists();
|
||||
}
|
||||
|
||||
public Resists(Mob mob) {
|
||||
setGenericResists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called for mobBase when getting from the db fails
|
||||
*/
|
||||
public Resists(MobBase mobBase) {
|
||||
setGenericResists();
|
||||
}
|
||||
/**
|
||||
* Database Constructor
|
||||
*/
|
||||
public Resists(ResultSet rs) throws SQLException {
|
||||
this.immuneToAll = false;
|
||||
this.resists.put(DamageType.Slash, rs.getFloat("slash"));
|
||||
this.resists.put(DamageType.Crush, rs.getFloat("crush"));
|
||||
this.resists.put(DamageType.Pierce, rs.getFloat("pierce"));
|
||||
this.resists.put(DamageType.Magic, rs.getFloat("magic"));
|
||||
this.resists.put(DamageType.Bleed, rs.getFloat("bleed"));
|
||||
this.resists.put(DamageType.Poison, rs.getFloat("poison"));
|
||||
this.resists.put(DamageType.Mental, rs.getFloat("mental"));
|
||||
this.resists.put(DamageType.Holy, rs.getFloat("holy"));
|
||||
this.resists.put(DamageType.Unholy, rs.getFloat("unholy"));
|
||||
this.resists.put(DamageType.Lightning, rs.getFloat("lightning"));
|
||||
this.resists.put(DamageType.Fire, rs.getFloat("fire"));
|
||||
this.resists.put(DamageType.Cold, rs.getFloat("cold"));
|
||||
this.resists.put(DamageType.Healing, 0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create generic resists for buildings
|
||||
*/
|
||||
public final void setBuildingResists() {
|
||||
this.immuneToAll = false;
|
||||
this.resists.put(DamageType.Slash, 85f);
|
||||
this.resists.put(DamageType.Crush, 85f);
|
||||
this.resists.put(DamageType.Siege, 0f);
|
||||
this.immuneTo.put(DamageType.Pierce, true);
|
||||
this.immuneTo.put(DamageType.Magic, true);
|
||||
this.immuneTo.put(DamageType.Bleed, true);
|
||||
this.immuneTo.put(DamageType.Poison, true);
|
||||
this.immuneTo.put(DamageType.Mental, true);
|
||||
this.immuneTo.put(DamageType.Holy, true);
|
||||
this.immuneTo.put(DamageType.Unholy, true);
|
||||
this.immuneTo.put(DamageType.Lightning, true);
|
||||
this.immuneTo.put(DamageType.Fire, true);
|
||||
this.immuneTo.put(DamageType.Cold, true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create generic resists for mines
|
||||
*/
|
||||
public final void setMineResists() {
|
||||
this.immuneToAll = false;
|
||||
this.immuneTo.put(DamageType.Slash, true);
|
||||
this.immuneTo.put(DamageType.Crush, true);
|
||||
this.immuneTo.put(DamageType.Pierce, true);
|
||||
this.immuneTo.put(DamageType.Magic, true);
|
||||
this.immuneTo.put(DamageType.Bleed, true);
|
||||
this.immuneTo.put(DamageType.Poison, true);
|
||||
this.immuneTo.put(DamageType.Mental, true);
|
||||
this.immuneTo.put(DamageType.Holy, true);
|
||||
this.immuneTo.put(DamageType.Unholy, true);
|
||||
this.immuneTo.put(DamageType.Lightning, true);
|
||||
this.immuneTo.put(DamageType.Fire, true);
|
||||
this.immuneTo.put(DamageType.Cold, true);
|
||||
this.resists.put(DamageType.Siege, 0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create generic resists
|
||||
*/
|
||||
public final void setGenericResists() {
|
||||
this.immuneToAll = false;
|
||||
this.resists.put(DamageType.Slash, 0f);
|
||||
this.resists.put(DamageType.Crush, 0f);
|
||||
this.resists.put(DamageType.Pierce, 0f);
|
||||
this.resists.put(DamageType.Magic, 0f);
|
||||
this.resists.put(DamageType.Bleed, 0f);
|
||||
this.resists.put(DamageType.Poison, 0f);
|
||||
this.resists.put(DamageType.Mental, 0f);
|
||||
this.resists.put(DamageType.Holy, 0f);
|
||||
this.resists.put(DamageType.Unholy, 0f);
|
||||
this.resists.put(DamageType.Lightning, 0f);
|
||||
this.resists.put(DamageType.Fire, 0f);
|
||||
this.resists.put(DamageType.Cold, 0f);
|
||||
this.resists.put(DamageType.Healing, 0f);
|
||||
this.immuneTo.put(DamageType.Siege, true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a resist
|
||||
*/
|
||||
public float getResist(DamageType type, int trains) {
|
||||
//get resisted amount
|
||||
Float amount = 0f;
|
||||
if (this.resists.containsKey(type))
|
||||
amount = this.resists.get(type);
|
||||
|
||||
//add protection
|
||||
if (trains > 0 && protection != null && type.equals(this.protection)) {
|
||||
float prot = 50 + this.protectionTrains - trains;
|
||||
amount += (prot >= 0) ? prot : 0;
|
||||
}
|
||||
|
||||
if (amount == null)
|
||||
return 0f;
|
||||
if (amount > 75f)
|
||||
return 75f;
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* get immuneTo
|
||||
*/
|
||||
public boolean immuneTo(DamageType type) {
|
||||
if (this.immuneTo.containsKey(type))
|
||||
return this.immuneTo.get(type);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get immuneToAll
|
||||
*/
|
||||
public boolean immuneToAll() {
|
||||
return this.immuneToAll;
|
||||
}
|
||||
|
||||
public boolean immuneToPowers() {
|
||||
return immuneTo(DamageType.Powers);
|
||||
}
|
||||
|
||||
public boolean immuneToAttacks() {
|
||||
return immuneTo(DamageType.Attack);
|
||||
}
|
||||
|
||||
public boolean immuneToSpires() {
|
||||
return immuneTo(DamageType.Spires);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets immuneTo(type) and immuneToAll
|
||||
*/
|
||||
public boolean isImmune(DamageType type) {
|
||||
if (this.immuneToAll)
|
||||
return true;
|
||||
return this.immuneTo(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a resist
|
||||
*/
|
||||
public void setResist(DamageType type, float value) {
|
||||
this.resists.put(type, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* add to a resist
|
||||
*/
|
||||
public void incResist(DamageType type, float value) {
|
||||
Float amount = this.resists.get(type);
|
||||
if (amount == null)
|
||||
this.resists.put(type, value);
|
||||
else
|
||||
this.resists.put(type, amount + value);
|
||||
}
|
||||
|
||||
/**
|
||||
* subtract from a resist
|
||||
*/
|
||||
public void decResist(DamageType type, float value) {
|
||||
Float amount = this.resists.get(type);
|
||||
if (amount == null)
|
||||
this.resists.put(type, (0 - value));
|
||||
else
|
||||
this.resists.put(type, amount - value);
|
||||
}
|
||||
|
||||
/**
|
||||
* set immunities from mobbase
|
||||
*/
|
||||
public void setImmuneTo(int immune) {
|
||||
setImmuneTo(DamageType.Stun, ((immune & 1) != 0));
|
||||
setImmuneTo(DamageType.PowerBlock, ((immune & 2) != 0));
|
||||
setImmuneTo(DamageType.Drain, ((immune & 4) != 0));
|
||||
setImmuneTo(DamageType.Snare, ((immune & 8) != 0));
|
||||
setImmuneTo(DamageType.Siege, ((immune & 16) != 0));
|
||||
setImmuneTo(DamageType.Slash, ((immune & 32) != 0));
|
||||
setImmuneTo(DamageType.Crush, ((immune & 64) != 0));
|
||||
setImmuneTo(DamageType.Pierce, ((immune & 128) != 0));
|
||||
setImmuneTo(DamageType.Magic, ((immune & 256) != 0));
|
||||
setImmuneTo(DamageType.Bleed, ((immune & 512) != 0));
|
||||
setImmuneTo(DamageType.Poison, ((immune & 1024) != 0));
|
||||
setImmuneTo(DamageType.Mental, ((immune & 2048) != 0));
|
||||
setImmuneTo(DamageType.Holy, ((immune & 4096) != 0));
|
||||
setImmuneTo(DamageType.Unholy, ((immune & 8192) != 0));
|
||||
setImmuneTo(DamageType.Lightning, ((immune & 16384) != 0));
|
||||
setImmuneTo(DamageType.Fire, ((immune & 32768) != 0));
|
||||
setImmuneTo(DamageType.Cold, ((immune & 65536) != 0));
|
||||
setImmuneTo(DamageType.Steel, ((immune & 131072) != 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* set/unset immuneTo
|
||||
*/
|
||||
public void setImmuneTo(DamageType type, boolean value) {
|
||||
this.immuneTo.put(type, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* set immuneToAll
|
||||
*/
|
||||
public void setImmuneToAll(boolean value) {
|
||||
this.immuneToAll = value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set resists from mobbase
|
||||
*/
|
||||
public void setMobResists(int resistID) {
|
||||
//TODO add this in later
|
||||
//calls `static_npc_mob_resists` table WHERE `ID`='resistID'
|
||||
}
|
||||
|
||||
/**
|
||||
* get Damage after resist
|
||||
* Expects heals as negative damage and damage as positive damage for fortitudes.
|
||||
*/
|
||||
public float getResistedDamage(AbstractCharacter source, AbstractCharacter target, DamageType type, float damage, int trains) {
|
||||
//handle fortitudes
|
||||
damage = handleFortitude(target, type, damage);
|
||||
|
||||
//check to see if any damage absorbers should cancel
|
||||
float damageAfterResists = damage * (1 - (this.getResist(type, trains) / 100));
|
||||
if (target != null) {
|
||||
//debug damage shields if any found
|
||||
if (source.getDebug(2) && source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
|
||||
Effect da = target.getDamageAbsorber();
|
||||
if (da != null && da.getEffectsBase() != null) {
|
||||
EffectsBase eb = da.getEffectsBase();
|
||||
String text = "Damage: " + damage + '\n';
|
||||
text += "Damage after resists: " + damageAfterResists + '\n';
|
||||
text += "Attack damage type: " + type.name() + '\n';
|
||||
text += "Fortitude damage types; " + eb.getDamageTypes() + '\n';
|
||||
text += "Fortitude damage before attack: " + da.getDamageAmount() + '\n';
|
||||
text += "Fortitude total health: " + eb.getDamageAmount(da.getTrains()) + '\n';
|
||||
text += "Fortitude trains: " + da.getTrains();
|
||||
ChatManager.chatSystemInfo((PlayerCharacter) source, text);
|
||||
}
|
||||
}
|
||||
target.cancelOnTakeDamage(type, (damageAfterResists));
|
||||
}
|
||||
return damageAfterResists;
|
||||
}
|
||||
|
||||
//Handle Fortitudes
|
||||
private static float handleFortitude(AbstractCharacter target, DamageType type, float damage) {
|
||||
if (target == null || !(target.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)))
|
||||
return damage;
|
||||
PlayerBonuses bonus = target.getBonuses();
|
||||
|
||||
//see if there is a fortitude
|
||||
float damageCap = bonus.getFloatPercentAll(ModType.DamageCap, SourceType.None);
|
||||
if (damageCap == 0f || type == DamageType.Healing)
|
||||
return damage;
|
||||
|
||||
//is fortitude, Are we under the cap?
|
||||
float maxHealth = target.getHealthMax();
|
||||
float capFire = maxHealth * (damageCap);
|
||||
if (damage < capFire)
|
||||
return damage;
|
||||
|
||||
//let's see if valid damagetype to apply it
|
||||
boolean exclusive;
|
||||
HashSet<SourceType> forts = bonus.getList(ModType.IgnoreDamageCap);
|
||||
if (forts == null) {
|
||||
exclusive = true;
|
||||
forts = bonus.getList(ModType.ExclusiveDamageCap);
|
||||
} else
|
||||
exclusive = false;
|
||||
if (forts == null || !isValidDamageCapType(forts, type, exclusive))
|
||||
return damage;
|
||||
|
||||
float adjustedDamage = bonus.getFloatPercentAll(ModType.AdjustAboveDmgCap, SourceType.None);
|
||||
//Adjust damage down and return new amount
|
||||
float aadc = 1 +adjustedDamage;
|
||||
return capFire * aadc;
|
||||
}
|
||||
|
||||
//Test if Damagetype is valid for foritude
|
||||
private static boolean isValidDamageCapType(HashSet<SourceType> forts, DamageType damageType, boolean exclusive) {
|
||||
for (SourceType fort: forts) {
|
||||
DamageType dt = DamageType.valueOf(fort.name());
|
||||
|
||||
if (dt == DamageType.None)
|
||||
continue;
|
||||
|
||||
if (dt == damageType) {
|
||||
return exclusive;
|
||||
}
|
||||
}
|
||||
return !exclusive;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate Current Resists for Player
|
||||
*/
|
||||
public static void calculateResists(AbstractCharacter ac) {
|
||||
if (ac.getResists() != null)
|
||||
ac.getResists().calculateResists(ac, true);
|
||||
else
|
||||
Logger.error("Unable to find resists for character " + ac.getObjectUUID());
|
||||
}
|
||||
|
||||
public void calculateResists(AbstractCharacter ac, boolean val) {
|
||||
this.immuneTo.clear();
|
||||
|
||||
// get resists for runes
|
||||
PlayerBonuses rb = ac.getBonuses();
|
||||
float slash = 0f, crush = 0f, pierce = 0f, magic = 0f, bleed = 0f, mental = 0f, holy = 0f, unholy = 0f, poison = 0f, lightning = 0f, fire = 0f, cold = 0f, healing = 0f;
|
||||
|
||||
if (rb != null) {
|
||||
// Handle immunities
|
||||
if (rb.getBool(ModType.ImmuneTo, SourceType.Stun))
|
||||
this.immuneTo.put(DamageType.Stun, true);
|
||||
if (rb.getBool(ModType.ImmuneTo, SourceType.Blind))
|
||||
this.immuneTo.put(DamageType.Blind, true);
|
||||
if (rb.getBool(ModType.ImmuneToAttack, SourceType.None))
|
||||
this.immuneTo.put(DamageType.Attack, true);
|
||||
if (rb.getBool(ModType.ImmuneToPowers, SourceType.None))
|
||||
this.immuneTo.put(DamageType.Powers, true);
|
||||
if (rb.getBool(ModType.ImmuneTo, SourceType.Powerblock))
|
||||
this.immuneTo.put(DamageType.Powerblock, true);
|
||||
if (rb.getBool(ModType.ImmuneTo, SourceType.DeBuff))
|
||||
this.immuneTo.put(DamageType.DeBuff, true);
|
||||
if (rb.getBool(ModType.ImmuneTo, SourceType.Fear))
|
||||
this.immuneTo.put(DamageType.Fear, true);
|
||||
if (rb.getBool(ModType.ImmuneTo, SourceType.Charm))
|
||||
this.immuneTo.put(DamageType.Charm, true);
|
||||
if (rb.getBool(ModType.ImmuneTo, SourceType.Root))
|
||||
this.immuneTo.put(DamageType.Root, true);
|
||||
if (rb.getBool(ModType.ImmuneTo, SourceType.Snare))
|
||||
this.immuneTo.put(DamageType.Snare, true);
|
||||
|
||||
// Handle resists
|
||||
slash += rb.getFloat(ModType.Resistance, SourceType.Slash);
|
||||
crush += rb.getFloat(ModType.Resistance, SourceType.Crush);
|
||||
pierce += rb.getFloat(ModType.Resistance, SourceType.Pierce);
|
||||
magic += rb.getFloat(ModType.Resistance, SourceType.Magic);
|
||||
bleed += rb.getFloat(ModType.Resistance, SourceType.Bleed);
|
||||
poison += rb.getFloat(ModType.Resistance, SourceType.Poison);
|
||||
mental += rb.getFloat(ModType.Resistance, SourceType.Mental);
|
||||
holy += rb.getFloat(ModType.Resistance, SourceType.Holy);
|
||||
unholy += rb.getFloat(ModType.Resistance, SourceType.Unholy);
|
||||
lightning += rb.getFloat(ModType.Resistance, SourceType.Lightning);
|
||||
fire += rb.getFloat(ModType.Resistance, SourceType.Fire);
|
||||
cold += rb.getFloat(ModType.Resistance, SourceType.Cold);
|
||||
healing += rb.getFloat(ModType.Resistance, SourceType.Healing); // DamageType.Healing.name());
|
||||
|
||||
//HHO
|
||||
|
||||
// String protectionString = rb.getString("protection");
|
||||
//
|
||||
// if (protectionString.isEmpty())
|
||||
// this.protection = null;
|
||||
// else try {
|
||||
// this.protection = DamageType.valueOf(rb.getString("protection"));
|
||||
// } catch (IllegalArgumentException e) {
|
||||
// Logger.error( "No enum for: " + protectionString);
|
||||
// this.protection = null;
|
||||
// }
|
||||
// this.protectionTrains = rb.getFloat("protection");
|
||||
}
|
||||
|
||||
// get resists from equipment
|
||||
if (ac.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
|
||||
if (ac.getCharItemManager() != null && ac.getCharItemManager().getEquipped() != null) {
|
||||
float[] phys = { 0f, 0f, 0f };
|
||||
ConcurrentHashMap<Integer, Item> equip = ac.getCharItemManager().getEquipped();
|
||||
|
||||
// get base physical resists
|
||||
phys = Resists.getArmorResists(equip.get(MBServerStatics.SLOT_HELMET), phys);
|
||||
phys = Resists.getArmorResists(equip.get(MBServerStatics.SLOT_CHEST), phys);
|
||||
phys = Resists.getArmorResists(equip.get(MBServerStatics.SLOT_ARMS), phys);
|
||||
phys = Resists.getArmorResists(equip.get(MBServerStatics.SLOT_GLOVES), phys);
|
||||
phys = Resists.getArmorResists(equip.get(MBServerStatics.SLOT_LEGGINGS), phys);
|
||||
phys = Resists.getArmorResists(equip.get(MBServerStatics.SLOT_FEET), phys);
|
||||
slash += phys[0];
|
||||
crush += phys[1];
|
||||
pierce += phys[2];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
this.resists.put(DamageType.Slash, slash);
|
||||
this.resists.put(DamageType.Crush, crush);
|
||||
this.resists.put(DamageType.Pierce, pierce);
|
||||
this.resists.put(DamageType.Magic, magic);
|
||||
this.resists.put(DamageType.Bleed, bleed);
|
||||
this.resists.put(DamageType.Poison, poison);
|
||||
this.resists.put(DamageType.Mental, mental);
|
||||
this.resists.put(DamageType.Holy, holy);
|
||||
this.resists.put(DamageType.Unholy, unholy);
|
||||
this.resists.put(DamageType.Lightning, lightning);
|
||||
this.resists.put(DamageType.Fire, fire);
|
||||
this.resists.put(DamageType.Cold, cold);
|
||||
this.resists.put(DamageType.Healing, healing);
|
||||
|
||||
this.immuneTo.put(DamageType.Siege, true);
|
||||
|
||||
// debug printing of resists
|
||||
// printResists(pc);
|
||||
}
|
||||
|
||||
private static float[] getArmorResists(Item armor, float[] phys) {
|
||||
if (armor == null)
|
||||
return phys;
|
||||
ItemBase ab = armor.getItemBase();
|
||||
if (ab == null)
|
||||
return phys;
|
||||
phys[0] += ab.getSlashResist();
|
||||
phys[1] += ab.getCrushResist();
|
||||
phys[2] += ab.getPierceResist();
|
||||
return phys;
|
||||
}
|
||||
|
||||
public void printResistsToClient(PlayerCharacter pc) {
|
||||
for (DamageType dt : resists.keySet())
|
||||
ChatManager.chatSystemInfo(pc, " resist." + dt.name() + ": " + resists.get(dt));
|
||||
for (DamageType dt : immuneTo.keySet())
|
||||
ChatManager.chatSystemInfo(pc, " immuneTo." + dt.name() + ": " + immuneTo.get(dt));
|
||||
ChatManager.chatSystemInfo(pc, " immuneToAll: " + this.immuneToAll);
|
||||
if (protection != null)
|
||||
ChatManager.chatSystemInfo(pc, " Protection: " + protection.name() + ", Trains: " + protectionTrains);
|
||||
else
|
||||
ChatManager.chatSystemInfo(pc, " Protection: None");
|
||||
}
|
||||
|
||||
public String getResists(PlayerCharacter pc) {
|
||||
String out = pc.getName();
|
||||
|
||||
out += "Resists: ";
|
||||
Iterator<DamageType> it = this.resists.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
DamageType damType = it.next();
|
||||
String dtName = damType.name();
|
||||
out += dtName + '=' + this.resists.get(dtName) + ", ";
|
||||
}
|
||||
|
||||
out += "ImmuneTo: ";
|
||||
it = this.immuneTo.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
DamageType damType = it.next();
|
||||
|
||||
String dtName = damType.name();
|
||||
out += dtName + '=' + this.resists.get(dtName) + ", ";
|
||||
}
|
||||
|
||||
if (protection != null)
|
||||
out += "Protection: " + protection.name() + ", Trains: " + protectionTrains;
|
||||
else
|
||||
out += "Protection: none";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mob resists from db if there, otherwise set defaults
|
||||
*/
|
||||
public static Resists getResists(int resistID) {
|
||||
//check cache first
|
||||
if (mobResists.containsKey(resistID))
|
||||
return new Resists(mobResists.get(resistID));
|
||||
|
||||
//get from database
|
||||
Resists resists = DbManager.ResistQueries.GET_RESISTS_FOR_MOB(resistID);
|
||||
if (resists != null) {
|
||||
mobResists.put(resistID, resists);
|
||||
return new Resists(resists);
|
||||
}
|
||||
|
||||
//failed, may want to debug this
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public enum Resource {
|
||||
|
||||
ADAMANT("DefaultAdamant", 1557001525, 10, 1580003),
|
||||
AGATE("DefaultAgate", -1096157543, 20, 1580009),
|
||||
ANTIMONY("DefaultAntimony", 1256147265, 10, 1580014),
|
||||
AZOTH("DefaultAzoth", -1205326951, 20, 1580012),
|
||||
BLOODSTONE("DefaultBloodstone", -1912381716, 5, 1580020),
|
||||
BRONZEWOOD("DefaultBronzewood", -519681813, 30, 1580006),
|
||||
COAL("DefaultCoal", -1672872311, 30, 1580008),
|
||||
DIAMOND("DefaultDiamond", 1540225085, 20, 1580010),
|
||||
GALVOR("DefaultGalvor", -1683992404, 5, 1580017),
|
||||
IRON("DefaultIron", -1673518119, 20, 1580002),
|
||||
LUMBER("DefaultLumber", -1628412684, 100, 1580004),
|
||||
MANDRAKE("DefaultMandrake", -1519910613, 10, 1580007),
|
||||
MITHRIL("DefaultMithril", 626743397, 5, 1580021),
|
||||
OAK("DefaultOak", -1653034775, 30, 1580005),
|
||||
OBSIDIAN("DefaultObsidian", 778019055, 5, 1580019),
|
||||
ONYX("DefaultOnyx", -1675952151, 10, 1580011),
|
||||
ORICHALK("DefaultOrichalk", -1468730955, 30, 1580013),
|
||||
QUICKSILVER("DefaultQuicksilver", -2081208434, 10, 1580016),
|
||||
STONE("DefaultStone", -1094703863, 100, 1580000),
|
||||
SULFUR("DefaultSulfur", -1763687412, 10, 1580015),
|
||||
TRUESTEEL("DefaultTruesteel", -169012482, 20, 1580001),
|
||||
WORMWOOD("DefaultWormwood", 1204785075, 5, 1580018),
|
||||
GOLD("DefaultGold", -1670881623, 50000, 7);
|
||||
|
||||
public final String name;
|
||||
public final int hash;
|
||||
public final int baseProduction;
|
||||
public final int UUID;
|
||||
public static ConcurrentHashMap<Integer, Resource> resourceByHash;
|
||||
|
||||
Resource(String name, int hash, int baseProduction, int uuid) {
|
||||
this.name = name;
|
||||
this.hash = hash;
|
||||
this.baseProduction = baseProduction;
|
||||
this.UUID = uuid;
|
||||
}
|
||||
|
||||
public static Resource GetResourceByHash(int hash){
|
||||
for (Resource resource: Resource.values()){
|
||||
if (hash == resource.hash)
|
||||
return resource;
|
||||
}
|
||||
return Resource.MITHRIL;
|
||||
}
|
||||
|
||||
//load lookups via hashes
|
||||
static {
|
||||
resourceByHash = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
for (Resource r : Resource.values())
|
||||
resourceByHash.put(r.hash, r);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class RuneBase extends AbstractGameObject {
|
||||
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final int type;
|
||||
private final byte subtype;
|
||||
|
||||
private final ConcurrentHashMap<Integer, Boolean> race = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private final ConcurrentHashMap<Integer, Boolean> baseClass = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private final ConcurrentHashMap<Integer, Boolean> promotionClass = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private final ConcurrentHashMap<Integer, Boolean> discipline = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private final ArrayList<Integer> overwrite = new ArrayList<>();
|
||||
private int levelRequired = 1;
|
||||
|
||||
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
||||
|
||||
public static HashMap<Integer,ArrayList<Integer>> AllowedBaseClassRunesMap = new HashMap<>();
|
||||
public static HashMap<Integer,ArrayList<Integer>> AllowedRaceRunesMap = new HashMap<>();
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public RuneBase(String name, String description, int type, byte subtype, ArrayList<RuneBaseAttribute> attrs) {
|
||||
super();
|
||||
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.type = type;
|
||||
this.subtype = subtype;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public RuneBase(String name, String description, int type, byte subtype, ArrayList<RuneBaseAttribute> attrs, int newUUID) {
|
||||
super(newUUID);
|
||||
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.type = type;
|
||||
this.subtype = subtype;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public RuneBase(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
this.name = rs.getString("name");
|
||||
this.description = rs.getString("description");
|
||||
this.type = rs.getInt("type");
|
||||
this.subtype = rs.getByte("subtype");
|
||||
|
||||
DbManager.RuneBaseQueries.GET_RUNE_REQS(this);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (!super.equals(obj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(obj instanceof RuneBase) {
|
||||
RuneBase rbObj = (RuneBase) obj;
|
||||
if (!this.name.equals(rbObj.name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.description.equals(rbObj.description)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.type != rbObj.type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.subtype != rbObj.subtype) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the subtype
|
||||
*/
|
||||
public byte getSubtype() {
|
||||
return subtype;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the attrs
|
||||
*/
|
||||
public ArrayList<RuneBaseAttribute> getAttrs() {
|
||||
return RuneBaseAttribute.runeBaseAttributeMap.get(this.getObjectUUID());
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<Integer, Boolean> getRace() {
|
||||
return this.race;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<Integer, Boolean> getBaseClass() {
|
||||
return this.baseClass;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<Integer, Boolean> getPromotionClass() {
|
||||
return this.promotionClass;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<Integer, Boolean> getDiscipline() {
|
||||
return this.discipline;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getOverwrite() {
|
||||
return this.overwrite;
|
||||
}
|
||||
|
||||
public int getLevelRequired() {
|
||||
return this.levelRequired;
|
||||
}
|
||||
|
||||
public void setLevelRequired(int levelRequired) {
|
||||
this.levelRequired = levelRequired;
|
||||
}
|
||||
|
||||
public static RuneBase getRuneBase(int tableId) {
|
||||
|
||||
if (tableId == 0)
|
||||
return null;
|
||||
|
||||
RuneBase rb = (RuneBase) DbManager.getFromCache(Enum.GameObjectType.RuneBase, tableId);
|
||||
|
||||
if (rb != null)
|
||||
return rb;
|
||||
|
||||
return DbManager.RuneBaseQueries.GET_RUNEBASE(tableId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Serializing
|
||||
*/
|
||||
|
||||
public static void serializeForClientMsg(RuneBase runeBase,ByteBufferWriter writer) {
|
||||
writer.putInt(runeBase.type);
|
||||
writer.putInt(0); // Pad
|
||||
writer.putInt(runeBase.getObjectUUID());
|
||||
writer.putInt(runeBase.getObjectType().ordinal());
|
||||
writer.putInt(runeBase.getObjectUUID());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the effectsList
|
||||
*/
|
||||
public ArrayList<MobBaseEffects> getEffectsList() {
|
||||
return effectsList;
|
||||
}
|
||||
|
||||
public static void LoadAllRuneBases(){
|
||||
|
||||
DbManager.RuneBaseQueries.LOAD_ALL_RUNEBASES();
|
||||
RuneBase.AllowedBaseClassRunesMap = DbManager.RuneBaseQueries.LOAD_ALLOWED_STARTING_RUNES_FOR_BASECLASS();
|
||||
RuneBase.AllowedRaceRunesMap = DbManager.RuneBaseQueries.LOAD_ALLOWED_STARTING_RUNES_FOR_RACE();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.GameObjectType;
|
||||
import engine.gameManager.DbManager;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class RuneBaseAttribute extends AbstractGameObject {
|
||||
|
||||
private short attributeID;
|
||||
private short modValue;
|
||||
|
||||
private int runeBaseID;
|
||||
|
||||
public static HashMap<Integer,ArrayList<RuneBaseAttribute>> runeBaseAttributeMap = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public RuneBaseAttribute(short attributeID, short modValue) {
|
||||
super();
|
||||
|
||||
this.attributeID = attributeID;
|
||||
this.modValue = modValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal
|
||||
*/
|
||||
public RuneBaseAttribute(short attributeID, short modValue, int newUUID) {
|
||||
super(newUUID);
|
||||
|
||||
this.attributeID = attributeID;
|
||||
this.modValue = modValue;
|
||||
}
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public RuneBaseAttribute(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
this.attributeID = rs.getShort("attributeID");
|
||||
this.modValue = rs.getShort("modValue");
|
||||
this.runeBaseID = rs.getInt("RuneBaseID");
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public short getAttributeID() {
|
||||
return attributeID;
|
||||
}
|
||||
|
||||
public short getModValue() {
|
||||
return modValue;
|
||||
}
|
||||
|
||||
public static void LoadAllAttributes(){
|
||||
DbManager.RuneBaseAttributeQueries.GET_ATTRIBUTES_FOR_RUNEBASE();
|
||||
|
||||
|
||||
//cache attributeLists for rune.
|
||||
for (AbstractGameObject ago : DbManager.getList(GameObjectType.RuneBaseAttribute)){
|
||||
|
||||
RuneBaseAttribute runeBaseAttribute = (RuneBaseAttribute)ago;
|
||||
|
||||
int runeBaseID = ((RuneBaseAttribute)runeBaseAttribute).runeBaseID;
|
||||
if (runeBaseAttributeMap.get(runeBaseID) == null){
|
||||
ArrayList<RuneBaseAttribute> attributeList = new ArrayList<>();
|
||||
attributeList.add(runeBaseAttribute);
|
||||
runeBaseAttributeMap.put(runeBaseID, attributeList);
|
||||
}
|
||||
else{
|
||||
ArrayList<RuneBaseAttribute>attributeList = runeBaseAttributeMap.get(runeBaseID);
|
||||
attributeList.add(runeBaseAttribute);
|
||||
runeBaseAttributeMap.put(runeBaseID, attributeList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Utils
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class RuneBaseEffect extends AbstractGameObject {
|
||||
|
||||
private byte type;
|
||||
private String name;
|
||||
private short amount;
|
||||
private int runeBaseID;
|
||||
|
||||
public static HashMap<Integer,ArrayList<RuneBaseEffect>> RuneIDBaseEffectMap = new HashMap<>();
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public RuneBaseEffect(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
this.type = rs.getByte("type");
|
||||
this.name = rs.getString("name");
|
||||
this.amount = rs.getShort("amount");
|
||||
this.runeBaseID = rs.getInt("runeID");
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
|
||||
public int getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public short getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
|
||||
}
|
||||
|
||||
public int getRuneBaseID() {
|
||||
return runeBaseID;
|
||||
}
|
||||
|
||||
public static void LoadRuneBaseEffects(){
|
||||
//cache runebase effects.
|
||||
DbManager.RuneBaseEffectQueries.GET_ALL_RUNEBASE_EFFECTS();
|
||||
//store runebase effects in new hashmap.
|
||||
RuneBaseEffect.RuneIDBaseEffectMap = DbManager.RuneBaseEffectQueries.LOAD_BASEEFFECTS_FOR_RUNEBASE();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.RunegateType;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.net.ByteBufferWriter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/* Runegates are tied to particular buildings at
|
||||
* bootstrap. They aren't tighly coupled, with
|
||||
* the Runegate merely toggling effect bits on it's
|
||||
* parent building.
|
||||
*/
|
||||
|
||||
public class Runegate {
|
||||
|
||||
// Runegate class Instance variables
|
||||
private static final Runegate[] _runegates = new Runegate[9];
|
||||
|
||||
private final Portal[] _portals;
|
||||
private final RunegateType gateType;
|
||||
|
||||
private Runegate(RunegateType gateType) {
|
||||
|
||||
this._portals = new Portal[8];
|
||||
this.gateType = gateType;
|
||||
|
||||
// Each Runegate has a different destination
|
||||
// for each portal opened.
|
||||
configureGatePortals();
|
||||
|
||||
// Chaos, Khar and Oblivion are on by default
|
||||
|
||||
_portals[RunegateType.CHAOS.ordinal()].activate(false);
|
||||
_portals[RunegateType.OBLIV.ordinal()].activate(false);
|
||||
_portals[RunegateType.MERCHANT.ordinal()].activate(false);
|
||||
|
||||
}
|
||||
|
||||
public void activatePortal(RunegateType gateType) {
|
||||
|
||||
this._portals[gateType.ordinal()].activate(true);
|
||||
|
||||
}
|
||||
|
||||
public void deactivatePortal(RunegateType gateType) {
|
||||
|
||||
this._portals[gateType.ordinal()].deactivate();
|
||||
|
||||
}
|
||||
|
||||
public RunegateType getGateType() {
|
||||
return this.gateType;
|
||||
}
|
||||
|
||||
public static Runegate[] getRunegates() {
|
||||
return Runegate._runegates;
|
||||
}
|
||||
|
||||
public Portal[] getPortals() {
|
||||
|
||||
return this._portals;
|
||||
|
||||
}
|
||||
|
||||
public void collidePortals() {
|
||||
|
||||
for (Portal portal : this.getPortals()) {
|
||||
|
||||
if (portal.isActive())
|
||||
portal.collide();
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadAllRunegates() {
|
||||
|
||||
for (RunegateType runegateType : RunegateType.values()) {
|
||||
_runegates[runegateType.ordinal()] = new Runegate(runegateType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void _serializeForEnterWorld(ByteBufferWriter writer) {
|
||||
|
||||
Building gateBuilding;
|
||||
|
||||
gateBuilding = BuildingManager.getBuilding(this.gateType.getGateUUID());
|
||||
|
||||
writer.putInt(gateBuilding.getObjectType().ordinal());
|
||||
writer.putInt(gateBuilding.getObjectUUID());
|
||||
writer.putString(gateBuilding.getParentZone().getName());
|
||||
writer.putFloat(gateBuilding.getLoc().getLat());
|
||||
writer.putFloat(gateBuilding.getLoc().getAlt());
|
||||
writer.putFloat(gateBuilding.getLoc().getLong());
|
||||
}
|
||||
|
||||
private void configureGatePortals() {
|
||||
|
||||
// Source gate type, portal type and destination gate type;
|
||||
switch (this.gateType) {
|
||||
|
||||
case EARTH:
|
||||
_portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.EARTH, RunegateType.EARTH);
|
||||
_portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.AIR, RunegateType.AIR);
|
||||
_portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.FIRE, RunegateType.FORBID);
|
||||
_portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.WATER, RunegateType.WATER);
|
||||
_portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.SPIRIT, RunegateType.SPIRIT);
|
||||
_portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.CHAOS, RunegateType.CHAOS);
|
||||
_portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.OBLIV, RunegateType.OBLIV);
|
||||
_portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.MERCHANT, RunegateType.MERCHANT);
|
||||
break;
|
||||
|
||||
case AIR:
|
||||
_portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.AIR, RunegateType.EARTH, RunegateType.EARTH);
|
||||
_portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.AIR, RunegateType.AIR, RunegateType.FORBID);
|
||||
_portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.AIR, RunegateType.FIRE, RunegateType.FIRE);
|
||||
_portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.AIR, RunegateType.WATER, RunegateType.WATER);
|
||||
_portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.AIR, RunegateType.SPIRIT, RunegateType.SPIRIT);
|
||||
_portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.AIR, RunegateType.CHAOS, RunegateType.CHAOS);
|
||||
_portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.AIR, RunegateType.OBLIV, RunegateType.OBLIV);
|
||||
_portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.AIR, RunegateType.MERCHANT, RunegateType.MERCHANT);
|
||||
|
||||
break;
|
||||
|
||||
case FIRE:
|
||||
_portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.EARTH, RunegateType.EARTH);
|
||||
_portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.AIR, RunegateType.AIR);
|
||||
_portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.FIRE, RunegateType.FORBID);
|
||||
_portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.WATER, RunegateType.WATER);
|
||||
_portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.SPIRIT, RunegateType.SPIRIT);
|
||||
_portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.CHAOS, RunegateType.CHAOS);
|
||||
_portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.OBLIV, RunegateType.OBLIV);
|
||||
_portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.MERCHANT, RunegateType.MERCHANT);
|
||||
break;
|
||||
|
||||
case WATER:
|
||||
_portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.WATER, RunegateType.EARTH, RunegateType.EARTH);
|
||||
_portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.WATER, RunegateType.AIR, RunegateType.AIR);
|
||||
_portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.WATER, RunegateType.FIRE, RunegateType.FIRE);
|
||||
_portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.WATER, RunegateType.WATER, RunegateType.FORBID);
|
||||
_portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.WATER, RunegateType.SPIRIT, RunegateType.SPIRIT);
|
||||
_portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.WATER, RunegateType.CHAOS, RunegateType.CHAOS);
|
||||
_portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.WATER, RunegateType.OBLIV, RunegateType.OBLIV);
|
||||
_portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.WATER, RunegateType.MERCHANT, RunegateType.MERCHANT);
|
||||
break;
|
||||
|
||||
case SPIRIT:
|
||||
_portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.EARTH, RunegateType.EARTH);
|
||||
_portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.AIR, RunegateType.AIR);
|
||||
_portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.FIRE, RunegateType.FIRE);
|
||||
_portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.WATER, RunegateType.WATER);
|
||||
_portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.SPIRIT, RunegateType.FORBID);
|
||||
_portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.CHAOS, RunegateType.CHAOS);
|
||||
_portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.OBLIV, RunegateType.OBLIV);
|
||||
_portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.MERCHANT, RunegateType.MERCHANT);
|
||||
break;
|
||||
|
||||
case CHAOS:
|
||||
_portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.EARTH, RunegateType.EARTH);
|
||||
_portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.AIR, RunegateType.AIR);
|
||||
_portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.FIRE, RunegateType.FIRE);
|
||||
_portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.WATER, RunegateType.WATER);
|
||||
_portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.SPIRIT, RunegateType.SPIRIT);
|
||||
_portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.CHAOS, RunegateType.MERCHANT);
|
||||
_portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.OBLIV, RunegateType.OBLIV);
|
||||
_portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.MERCHANT, RunegateType.MERCHANT);
|
||||
break;
|
||||
|
||||
case OBLIV:
|
||||
_portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.EARTH, RunegateType.EARTH);
|
||||
_portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.AIR, RunegateType.AIR);
|
||||
_portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.FIRE, RunegateType.FIRE);
|
||||
_portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.WATER, RunegateType.WATER);
|
||||
_portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.SPIRIT, RunegateType.SPIRIT);
|
||||
_portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.CHAOS, RunegateType.CHAOS);
|
||||
_portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.OBLIV, RunegateType.MERCHANT);
|
||||
_portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.MERCHANT, RunegateType.MERCHANT);
|
||||
break;
|
||||
|
||||
case MERCHANT:
|
||||
_portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.EARTH, RunegateType.EARTH);
|
||||
_portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.AIR, RunegateType.AIR);
|
||||
_portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.FIRE, RunegateType.FIRE);
|
||||
_portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.WATER, RunegateType.WATER);
|
||||
_portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.SPIRIT, RunegateType.SPIRIT);
|
||||
_portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.CHAOS, RunegateType.CHAOS);
|
||||
_portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.OBLIV, RunegateType.OBLIV);
|
||||
_portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.MERCHANT, RunegateType.FORBID);
|
||||
break;
|
||||
|
||||
case FORBID:
|
||||
_portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.EARTH, RunegateType.EARTH);
|
||||
_portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.AIR, RunegateType.AIR);
|
||||
_portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.FIRE, RunegateType.FIRE);
|
||||
_portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.WATER, RunegateType.WATER);
|
||||
_portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.SPIRIT, RunegateType.SPIRIT);
|
||||
_portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.CHAOS, RunegateType.CHAOS);
|
||||
_portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.OBLIV, RunegateType.OBLIV);
|
||||
_portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.MERCHANT, RunegateType.MERCHANT);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static ArrayList<String> GetAllOpenGateIDStrings(){
|
||||
ArrayList<String> openGateIDStrings = new ArrayList<>();
|
||||
|
||||
openGateIDStrings.add("TRA-003");
|
||||
openGateIDStrings.add("TRA-004");
|
||||
openGateIDStrings.add("TRA-005");
|
||||
openGateIDStrings.add("TRA-006");
|
||||
openGateIDStrings.add("TRA-007");
|
||||
openGateIDStrings.add("TRA-008");
|
||||
openGateIDStrings.add("TRA-009");
|
||||
openGateIDStrings.add("TRA-010");
|
||||
return openGateIDStrings;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.Enum.BuildingGroup;
|
||||
import engine.Enum.ShrineType;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class Shrine extends AbstractWorldObject implements Comparable<Shrine> {
|
||||
|
||||
private final ShrineType shrineType;
|
||||
private Integer favors;
|
||||
private final int buildingID;
|
||||
|
||||
public static ConcurrentHashMap<Integer, Shrine> shrinesByBuildingUUID = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public Shrine(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
this.shrineType = ShrineType.valueOf(rs.getString("shrine_type"));
|
||||
this.favors = rs.getInt("shrine_favors");
|
||||
this.buildingID = rs.getInt("parent");
|
||||
shrinesByBuildingUUID.put(this.buildingID, this);
|
||||
}
|
||||
|
||||
// Decays this shrine's favor by 10%
|
||||
|
||||
public void decay() {
|
||||
|
||||
if (this.getFavors() == 0)
|
||||
return;
|
||||
|
||||
int decayAmount = (int) (this.getFavors() - (this.getFavors() *.10f));
|
||||
|
||||
if (decayAmount < 0)
|
||||
decayAmount = 0;
|
||||
|
||||
if (!DbManager.ShrineQueries.updateFavors(this, decayAmount, this.getFavors())) {
|
||||
Logger.error("Shrine Decay", "Error writing to DB. UUID: " + this.getObjectUUID());
|
||||
return;
|
||||
}
|
||||
this.favors = decayAmount;
|
||||
|
||||
Logger.info( shrineType.name() + " uuid:" + this.getObjectUUID() + " Amount: " + this.getFavors() *.10f );
|
||||
|
||||
}
|
||||
|
||||
public synchronized boolean addFavor(PlayerCharacter boonOwner, Item boonItem) {
|
||||
|
||||
if (boonOwner == null)
|
||||
return false;
|
||||
|
||||
if (boonItem == null)
|
||||
return false;
|
||||
|
||||
ItemBase ib = boonItem.getItemBase();
|
||||
|
||||
if (ib == null)
|
||||
return false;
|
||||
|
||||
if (!boonOwner.getCharItemManager().doesCharOwnThisItem(boonItem.getObjectUUID()))
|
||||
return false;
|
||||
|
||||
ArrayList<Boon> boonList = Boon.GetBoonsForItemBase.get(ib.getUUID());
|
||||
|
||||
if (boonList == null)
|
||||
return false;
|
||||
|
||||
for (Boon boon : boonList) {
|
||||
|
||||
ShrineType boonShrineType = boon.getShrineType();
|
||||
|
||||
if (boonShrineType != shrineType)
|
||||
continue;
|
||||
|
||||
//Same Shrine Type, add favors and stop loop.
|
||||
int amount = boon.getAmount() * boonItem.getNumOfItems();
|
||||
int oldAmount = this.favors;
|
||||
|
||||
if (!DbManager.ShrineQueries.updateFavors(this, this.favors + amount, oldAmount)) {
|
||||
ChatManager.chatSystemError(boonOwner, "Failed to add boon to shrine.");
|
||||
return false;
|
||||
}
|
||||
|
||||
this.favors += amount;
|
||||
boonOwner.getCharItemManager().delete(boonItem);
|
||||
boonOwner.getCharItemManager().updateInventory();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public synchronized boolean takeFavor(PlayerCharacter boonOwner) {
|
||||
|
||||
if (boonOwner == null)
|
||||
return false;
|
||||
|
||||
int oldAmount = this.favors;
|
||||
int newAmount = this.favors - 1;
|
||||
|
||||
if (!DbManager.ShrineQueries.updateFavors(this, newAmount, oldAmount)) {
|
||||
ChatManager.chatSystemError(boonOwner, "Failed to add boon to shrine.");
|
||||
return false;
|
||||
}
|
||||
this.favors = newAmount;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean canTakeFavor(PlayerCharacter grantee, Shrine shrine) {
|
||||
|
||||
if (shrine.shrineType.isRace())
|
||||
switch (grantee.getRaceID()) {
|
||||
case 2000:
|
||||
case 2001:
|
||||
if (shrine.shrineType == ShrineType.Aelfborn)
|
||||
return true;
|
||||
break;
|
||||
case 2002:
|
||||
case 2003:
|
||||
if (shrine.shrineType == ShrineType.Aracoix)
|
||||
return true;
|
||||
break;
|
||||
case 2004:
|
||||
case 2005:
|
||||
if (shrine.shrineType == ShrineType.Centaur)
|
||||
return true;
|
||||
break;
|
||||
case 2006:
|
||||
if (shrine.shrineType == ShrineType.Dwarf)
|
||||
return true;
|
||||
break;
|
||||
case 2008:
|
||||
case 2009:
|
||||
if (shrine.shrineType == ShrineType.Elf)
|
||||
return true;
|
||||
break;
|
||||
case 2010:
|
||||
case 2027:
|
||||
if (shrine.shrineType == ShrineType.HalfGiant)
|
||||
return true;
|
||||
break;
|
||||
case 2011:
|
||||
case 2012:
|
||||
if (shrine.shrineType == ShrineType.Human)
|
||||
return true;
|
||||
break;
|
||||
case 2013:
|
||||
case 2014:
|
||||
if (shrine.shrineType == ShrineType.Irekei)
|
||||
return true;
|
||||
break;
|
||||
case 2015:
|
||||
case 2016:
|
||||
if (shrine.shrineType == ShrineType.Shade)
|
||||
return true;
|
||||
break;
|
||||
case 2017:
|
||||
if (shrine.shrineType == ShrineType.Minotaur)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case 2025:
|
||||
case 2026:
|
||||
if (shrine.shrineType == ShrineType.Nephilim)
|
||||
return true;
|
||||
break;
|
||||
case 2028:
|
||||
case 2029:
|
||||
if (shrine.shrineType == ShrineType.Vampire)
|
||||
return true;
|
||||
break;
|
||||
|
||||
}
|
||||
else
|
||||
switch (grantee.getPromotionClassID()) {
|
||||
case 2504:
|
||||
if (shrine.shrineType == ShrineType.Assassin)
|
||||
return true;
|
||||
break;
|
||||
case 2505:
|
||||
if (shrine.shrineType == ShrineType.Barbarian)
|
||||
return true;
|
||||
break;
|
||||
case 2506:
|
||||
if (shrine.shrineType == ShrineType.Bard)
|
||||
return true;
|
||||
break;
|
||||
case 2507:
|
||||
if (shrine.shrineType == ShrineType.Channeler)
|
||||
return true;
|
||||
break;
|
||||
case 2508:
|
||||
if (shrine.shrineType == ShrineType.Confessor)
|
||||
return true;
|
||||
break;
|
||||
case 2509:
|
||||
if (shrine.shrineType == ShrineType.Crusader)
|
||||
return true;
|
||||
break;
|
||||
case 2510:
|
||||
if (shrine.shrineType == ShrineType.Druid)
|
||||
return true;
|
||||
break;
|
||||
case 2511:
|
||||
if (shrine.shrineType == ShrineType.Fury)
|
||||
return true;
|
||||
break;
|
||||
case 2512:
|
||||
if (shrine.shrineType == ShrineType.Huntress)
|
||||
return true;
|
||||
break;
|
||||
case 2513:
|
||||
if (shrine.shrineType == ShrineType.Prelate)
|
||||
return true;
|
||||
break;
|
||||
case 2514:
|
||||
if (shrine.shrineType == ShrineType.Ranger)
|
||||
return true;
|
||||
break;
|
||||
case 2515:
|
||||
if (shrine.shrineType == ShrineType.Scout)
|
||||
return true;
|
||||
break;
|
||||
case 2516:
|
||||
if (shrine.shrineType == ShrineType.Templar)
|
||||
return true;
|
||||
break;
|
||||
case 2517:
|
||||
if (shrine.shrineType == ShrineType.Warlock)
|
||||
return true;
|
||||
break;
|
||||
case 2518:
|
||||
if (shrine.shrineType == ShrineType.Warrior)
|
||||
return true;
|
||||
break;
|
||||
case 2519:
|
||||
if (shrine.shrineType == ShrineType.Priest)
|
||||
return true;
|
||||
break;
|
||||
case 2520:
|
||||
if (shrine.shrineType == ShrineType.Thief)
|
||||
return true;
|
||||
break;
|
||||
case 2521:
|
||||
if (shrine.shrineType == ShrineType.Wizard)
|
||||
return true;
|
||||
break;
|
||||
case 2523:
|
||||
if (shrine.shrineType == ShrineType.Doomsayer)
|
||||
return true;
|
||||
break;
|
||||
case 2524:
|
||||
if (shrine.shrineType == ShrineType.Sentinel)
|
||||
return true;
|
||||
break;
|
||||
case 2525:
|
||||
if (shrine.shrineType == ShrineType.Necromancer)
|
||||
return true;
|
||||
break;
|
||||
case 2526:
|
||||
if (shrine.shrineType == ShrineType.Nightstalker)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ShrineType getShrineTypeByBlueprintUUID(int blueprintUUID) {
|
||||
|
||||
for (ShrineType shrineType : ShrineType.values()) {
|
||||
|
||||
if (shrineType.getBlueprintUUID() == blueprintUUID)
|
||||
return shrineType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Shrine other) {
|
||||
return other.favors.compareTo(this.favors);
|
||||
}
|
||||
|
||||
public int getRank() {
|
||||
return shrineType.getShrinesCopy().indexOf(this);
|
||||
}
|
||||
|
||||
public ShrineType getShrineType() {
|
||||
return shrineType;
|
||||
}
|
||||
|
||||
public static void RemoveShrineFromCacheByBuilding(Building building) {
|
||||
|
||||
if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup() == BuildingGroup.SHRINE) {
|
||||
Shrine shrine = Shrine.shrinesByBuildingUUID.get(building.getObjectUUID());
|
||||
|
||||
if (shrine != null) {
|
||||
shrine.shrineType.RemoveShrineFromServerList(shrine);
|
||||
Shrine.shrinesByBuildingUUID.remove(building.getObjectUUID());
|
||||
DbManager.removeFromCache(Enum.GameObjectType.Shrine,
|
||||
shrine.getObjectUUID());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public int getFavors() {
|
||||
return favors;
|
||||
}
|
||||
|
||||
public int getBuildingID() {
|
||||
return buildingID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runAfterLoad() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void removeFromCache() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void setFavors(Integer favors) {
|
||||
this.favors = favors;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class SkillReq extends AbstractGameObject {
|
||||
|
||||
|
||||
private int skillID;
|
||||
private short level;
|
||||
private ArrayList<Byte> skillReqs;
|
||||
|
||||
/* This shouldn't be used
|
||||
public SkillReq(SkillsBase skillsBase, short level, ArrayList<Byte>skillReqs) {
|
||||
|
||||
super();
|
||||
this.skillsBase = skillsBase;
|
||||
this.level = level;
|
||||
this.skillReqs = skillReqs;
|
||||
}
|
||||
*/
|
||||
|
||||
/* This shouldn't be used
|
||||
public SkillReq(SkillsBase skillsBase, short level, ArrayList<Byte>skillReqs, int newUUID) {
|
||||
|
||||
super(newUUID);
|
||||
this.skillsBase = skillsBase;
|
||||
this.level = level;
|
||||
this.skillReqs = skillReqs;
|
||||
}
|
||||
*/
|
||||
|
||||
/* This shouldn't be used
|
||||
public SkillReq(SkillReq a, int newUUID) {
|
||||
super(a, newUUID);
|
||||
this.skillsBase = a.skillsBase;
|
||||
this.level = a.level;
|
||||
this.skillReqs = a.skillReqs;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public SkillReq(ResultSet rs) throws SQLException {
|
||||
super(rs, 0);
|
||||
this.skillID = rs.getInt("skillID");
|
||||
this.level = rs.getShort("level");
|
||||
skillReqs = new ArrayList<>(0);
|
||||
|
||||
int skillReq;
|
||||
skillReq = rs.getInt("skillreq1");
|
||||
if (skillReq > 0) skillReqs.add((byte)skillReq);
|
||||
skillReq = rs.getInt("skillreq2");
|
||||
if (skillReq > 0) skillReqs.add((byte)skillReq);
|
||||
skillReq = rs.getInt("skillreq3");
|
||||
if (skillReq > 0) skillReqs.add((byte)skillReq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public SkillsBase getSkillsBase() {
|
||||
return DbManager.SkillsBaseQueries.GET_BASE(this.skillID);
|
||||
}
|
||||
|
||||
public int getSkillID() {
|
||||
return this.skillID;
|
||||
}
|
||||
|
||||
public short getLevel() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public ArrayList<Byte> getSkillReqs() {
|
||||
return this.skillReqs;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.SourceType;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class SkillsBase extends AbstractGameObject {
|
||||
|
||||
private final String name;
|
||||
private final String nameNoSpace;
|
||||
private final String description;
|
||||
private final int token;
|
||||
private final short strMod;
|
||||
private final short dexMod;
|
||||
private final short conMod;
|
||||
private final short intMod;
|
||||
private final short spiMod;
|
||||
public static ConcurrentHashMap<String, SkillsBase> skillsCache = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
public static ConcurrentHashMap<Integer, SkillsBase> tokenCache = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
public static HashMap<Integer, HashMap<Integer, Integer>> runeSkillsCache = new HashMap<>();
|
||||
public SourceType sourceType;
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public SkillsBase(String name, String description, int token, short strMod,
|
||||
short dexMod, short conMod, short intMod, short spiMod) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.nameNoSpace = name.replace(" ", "");
|
||||
this.sourceType = SourceType.GetSourceType(this.nameNoSpace.replace(",", ""));
|
||||
this.description = description;
|
||||
this.token = token;
|
||||
this.strMod = strMod;
|
||||
this.dexMod = dexMod;
|
||||
this.conMod = conMod;
|
||||
this.intMod = intMod;
|
||||
this.spiMod = spiMod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public SkillsBase(String name, String description, int token, short strMod,
|
||||
short dexMod, short conMod, short intMod, short spiMod, int newUUID) {
|
||||
super(newUUID);
|
||||
this.name = name;
|
||||
this.nameNoSpace = name.replace(" ", "");
|
||||
this.description = description;
|
||||
this.token = token;
|
||||
this.strMod = strMod;
|
||||
this.dexMod = dexMod;
|
||||
this.conMod = conMod;
|
||||
this.intMod = intMod;
|
||||
this.spiMod = spiMod;
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public SkillsBase(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
this.name = rs.getString("name");
|
||||
this.nameNoSpace = name.replace(" ", "");
|
||||
this.description = rs.getString("description");
|
||||
this.sourceType = SourceType.GetSourceType(this.nameNoSpace.replace("-", "").replace("\"", "").replace(",", ""));
|
||||
this.token = rs.getInt("token");
|
||||
this.strMod = rs.getShort("strMod");
|
||||
this.dexMod = rs.getShort("dexMod");
|
||||
this.conMod = rs.getShort("conMod");
|
||||
this.intMod = rs.getShort("intMod");
|
||||
this.spiMod = rs.getShort("spiMod");
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getNameNoSpace() {
|
||||
return nameNoSpace;
|
||||
}
|
||||
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public int getToken() {
|
||||
return this.token;
|
||||
}
|
||||
|
||||
public short getStrMod() {
|
||||
return this.strMod;
|
||||
}
|
||||
|
||||
public short getDexMod() {
|
||||
return this.dexMod;
|
||||
}
|
||||
|
||||
public short getConMod() {
|
||||
return this.conMod;
|
||||
}
|
||||
|
||||
public short getIntMod() {
|
||||
return this.intMod;
|
||||
}
|
||||
|
||||
public short getSpiMod() {
|
||||
return this.spiMod;
|
||||
}
|
||||
|
||||
public static SkillsBase getFromCache(String name) {
|
||||
if (skillsCache.containsKey(name))
|
||||
return skillsCache.get(name);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static SkillsBase getFromCache(int token) {
|
||||
if (tokenCache.containsKey(token))
|
||||
return tokenCache.get(token);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void putInCache(SkillsBase sb) {
|
||||
|
||||
if(sb == null)
|
||||
return;
|
||||
|
||||
DbManager.addToCache(sb);
|
||||
skillsCache.putIfAbsent(sb.name, sb);
|
||||
tokenCache.putIfAbsent(sb.token, sb);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
public class SkillsBaseAttribute extends AbstractGameObject {
|
||||
|
||||
private short attributeID;
|
||||
private short modValue;
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public SkillsBaseAttribute(short attributeID, short modValue) {
|
||||
super();
|
||||
|
||||
this.attributeID = attributeID;
|
||||
this.modValue = modValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public SkillsBaseAttribute(short attributeID, short modValue, int newUUID) {
|
||||
super(newUUID);
|
||||
|
||||
this.attributeID = attributeID;
|
||||
this.modValue = modValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public SkillsBaseAttribute(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
this.attributeID = rs.getShort("attributeID");
|
||||
this.modValue = rs.getShort("modValue");
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public short getAttributeID() {
|
||||
return attributeID;
|
||||
}
|
||||
|
||||
public short getModValue() {
|
||||
return modValue;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Database
|
||||
*/
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class SpecialLoot extends AbstractGameObject {
|
||||
|
||||
private int itemID;
|
||||
private int dropChance;
|
||||
private boolean dropOnDeath;
|
||||
private boolean noSteal;
|
||||
private int lootSetID;
|
||||
|
||||
public static HashMap<Integer,ArrayList<SpecialLoot>> LootMap = new HashMap<>();
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public SpecialLoot(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
this.itemID = rs.getInt("itemID");
|
||||
this.dropChance = rs.getInt("dropChance");
|
||||
this.dropOnDeath = rs.getBoolean("dropOnDeath");
|
||||
this.noSteal = rs.getBoolean("noSteal");
|
||||
}
|
||||
|
||||
public SpecialLoot(ResultSet rs,boolean specialLoot) throws SQLException {
|
||||
super(rs);
|
||||
|
||||
this.lootSetID = rs.getInt("lootSet");
|
||||
this.itemID = rs.getInt("itemID");
|
||||
this.dropChance = rs.getInt("dropChance");
|
||||
this.dropOnDeath = false;
|
||||
this.noSteal = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
|
||||
public int getItemID() {
|
||||
return this.itemID;
|
||||
}
|
||||
|
||||
public int getDropChance() {
|
||||
return this.dropChance;
|
||||
}
|
||||
|
||||
public boolean dropOnDeath() {
|
||||
return this.dropOnDeath;
|
||||
}
|
||||
|
||||
public boolean noSteal() {
|
||||
return this.noSteal;
|
||||
}
|
||||
|
||||
public static ArrayList<SpecialLoot> getSpecialLoot(int mobbaseID) {
|
||||
return DbManager.SpecialLootQueries.GET_SPECIALLOOT(mobbaseID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class StaticColliders {
|
||||
|
||||
private int meshID;
|
||||
private float startX;
|
||||
private float startY;
|
||||
private float endX;
|
||||
private float endY;
|
||||
private int doorID;
|
||||
public static HashMap<Integer,ArrayList<StaticColliders>> _staticColliders = new HashMap<>();
|
||||
private boolean link = false;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public StaticColliders(ResultSet rs) throws SQLException {
|
||||
this.meshID = rs.getInt("meshID");
|
||||
this.startX = rs.getInt("startX");
|
||||
this.startY = rs.getInt("startY");
|
||||
this.endX = rs.getInt("endX");
|
||||
this.endY = rs.getInt("endY");
|
||||
this.doorID = rs.getInt("doorID");
|
||||
this.link = rs.getBoolean("link");
|
||||
}
|
||||
|
||||
public StaticColliders(int meshID, float startX, float startY, float endX,
|
||||
float endY, int doorID,boolean link) {
|
||||
super();
|
||||
this.meshID = meshID;
|
||||
this.startX = startX;
|
||||
this.startY = startY;
|
||||
this.endX = endX;
|
||||
this.endY = endY;
|
||||
this.doorID = doorID;
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public static void loadAllStaticColliders(){
|
||||
_staticColliders = DbManager.BuildingQueries.LOAD_ALL_STATIC_COLLIDERS();
|
||||
}
|
||||
|
||||
public static ArrayList<StaticColliders> GetStaticCollidersForMeshID(int meshID) {
|
||||
return _staticColliders.get(meshID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public int getMeshID() {
|
||||
return meshID;
|
||||
}
|
||||
|
||||
public float getStartX() {
|
||||
return startX;
|
||||
}
|
||||
|
||||
public float getStartY() {
|
||||
return startY;
|
||||
}
|
||||
|
||||
public float getEndX() {
|
||||
return endX;
|
||||
}
|
||||
|
||||
public float getEndY() {
|
||||
return endY;
|
||||
}
|
||||
|
||||
public int getDoorID() {
|
||||
return doorID;
|
||||
}
|
||||
|
||||
public boolean isLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
public void setLink(boolean link) {
|
||||
this.link = link;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum.GameObjectType;
|
||||
import engine.Enum.TransactionType;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
|
||||
public class Transaction implements Comparable<Transaction> {
|
||||
|
||||
private final int warehouseUUID;
|
||||
private final int targetUUID;
|
||||
private final Resource resource;
|
||||
private final DateTime date;
|
||||
private final int amount;
|
||||
private GameObjectType targetType;
|
||||
private final TransactionType transactionType;
|
||||
|
||||
|
||||
|
||||
public Transaction(ResultSet rs) throws SQLException {
|
||||
this.warehouseUUID = rs.getInt("warehouseUID");
|
||||
this.targetUUID = rs.getInt("targetUID");
|
||||
this.targetType = GameObjectType.valueOf(rs.getString("targetType"));
|
||||
this.transactionType = TransactionType.valueOf(rs.getString("type").toUpperCase());
|
||||
this.resource = Resource.valueOf(rs.getString("resource").toUpperCase());
|
||||
this.amount = rs.getInt("amount");
|
||||
|
||||
Date sqlDateTime = rs.getTimestamp("date");
|
||||
|
||||
if (sqlDateTime != null)
|
||||
this.date = new DateTime(sqlDateTime);
|
||||
else
|
||||
this.date = DateTime.now();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public Transaction(int warehouseUUID,GameObjectType targetType, int targetUUID, TransactionType transactionType, Resource resource, int amount,
|
||||
DateTime date) {
|
||||
this.warehouseUUID = warehouseUUID;
|
||||
this.targetUUID = targetUUID;
|
||||
this.resource = resource;
|
||||
this.date = date;
|
||||
this.amount = amount;
|
||||
this.targetType = targetType;
|
||||
this.transactionType = transactionType;
|
||||
}
|
||||
|
||||
|
||||
public int getWarehouseUUID() {
|
||||
return warehouseUUID;
|
||||
}
|
||||
|
||||
|
||||
public int getTargetUUID() {
|
||||
return targetUUID;
|
||||
}
|
||||
|
||||
|
||||
public Resource getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
|
||||
public DateTime getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
|
||||
public TransactionType getTransactionType() {
|
||||
return transactionType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compareTo(Transaction arg0) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public GameObjectType getTargetType() {
|
||||
return targetType;
|
||||
}
|
||||
|
||||
|
||||
public void setTargetType(GameObjectType targetType) {
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class VendorDialog extends AbstractGameObject {
|
||||
|
||||
private final String dialogType;
|
||||
private final String intro;
|
||||
private ArrayList<MenuOption> options = new ArrayList<>();
|
||||
|
||||
public VendorDialog(String dialogType, String intro, int UUID) {
|
||||
super(UUID);
|
||||
this.dialogType = dialogType;
|
||||
this.intro = intro;
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public VendorDialog(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
this.dialogType = rs.getString("dialogType");
|
||||
this.intro = rs.getString("intro");
|
||||
this.options = DbManager.MenuQueries.GET_MENU_OPTIONS(this.getObjectUUID());
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public String getDialogType() {
|
||||
return this.dialogType;
|
||||
}
|
||||
|
||||
public String getIntro() {
|
||||
return this.intro;
|
||||
}
|
||||
|
||||
public ArrayList<MenuOption> getOptions() {
|
||||
return this.options;
|
||||
}
|
||||
|
||||
private static VendorDialog vd;
|
||||
public static VendorDialog getHostileVendorDialog() {
|
||||
if (VendorDialog.vd == null)
|
||||
VendorDialog.vd = new VendorDialog("TrainerDialog", "HostileIntro", 0);
|
||||
return VendorDialog.vd;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Database
|
||||
*/
|
||||
@Override
|
||||
public void updateDatabase() {}
|
||||
|
||||
public static VendorDialog getVendorDialog(int id) {
|
||||
|
||||
return DbManager.VendorDialogQueries.GET_VENDORDIALOG(id);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,512 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.InterestManagement.HeightMap;
|
||||
import engine.db.archive.DataWarehouse;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.math.Bounds;
|
||||
import engine.math.Vector2f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class Zone extends AbstractGameObject {
|
||||
|
||||
private final int playerCityID;
|
||||
private final String zoneName;
|
||||
private final float xCoord;
|
||||
private final float zCoord;
|
||||
private final float yCoord;
|
||||
public float absX = 0.0f;
|
||||
public float absY = 0.0f;
|
||||
public float absZ = 0.0f;
|
||||
private final int loadNum;
|
||||
private final byte safeZone;
|
||||
private final String Icon1;
|
||||
private final String Icon2;
|
||||
private final String Icon3;
|
||||
private ArrayList<Zone> nodes = null;
|
||||
private int parentZoneID;
|
||||
private Zone parent = null;
|
||||
private Bounds bounds;
|
||||
private boolean isNPCCity = false;
|
||||
private boolean isPlayerCity = false;
|
||||
private String hash;
|
||||
private int minLvl;
|
||||
private int maxLvl;
|
||||
|
||||
private float worldAltitude = 0;
|
||||
|
||||
private float seaLevel = 0;
|
||||
public final Set<Building> zoneBuildingSet = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
public final Set<NPC> zoneNPCSet = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
public final Set<Mob> zoneMobSet = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public Zone(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
this.parentZoneID = rs.getInt("parent");
|
||||
this.playerCityID = rs.getInt("isPlayerCity");
|
||||
this.isPlayerCity = this.playerCityID != 0;
|
||||
this.zoneName = rs.getString("Name");
|
||||
this.xCoord = rs.getFloat("XCoord");
|
||||
this.zCoord = rs.getFloat("ZCoord");
|
||||
this.yCoord = rs.getFloat("YOffset");
|
||||
this.loadNum = rs.getInt("LoadNum");
|
||||
this.safeZone = rs.getByte("SafeZone");
|
||||
this.Icon1 = rs.getString("Icon1");
|
||||
this.Icon2 = rs.getString("Icon2");
|
||||
this.Icon3 = rs.getString("Icon3");
|
||||
this.hash = rs.getString("hash");
|
||||
|
||||
this.minLvl = rs.getInt("minLvl");
|
||||
this.maxLvl = rs.getInt("maxLvl");
|
||||
|
||||
//this needs to be here specifically for new zones created after server boot (e.g. player city zones)
|
||||
Zone parentZone = ZoneManager.getZoneByUUID(parentZoneID);
|
||||
|
||||
this.setParent(parentZone);
|
||||
|
||||
if (this.minLvl == 0 && parentZone != null){
|
||||
this.minLvl = parentZone.minLvl;
|
||||
this.maxLvl = parentZone.maxLvl;
|
||||
}
|
||||
|
||||
if (parentZone != null)
|
||||
parentZone.addNode(this);
|
||||
|
||||
// If zone doesn't yet hava a hash then write it back to the zone table
|
||||
|
||||
if (hash == null)
|
||||
setHash();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Method sets a default value for player cities
|
||||
* otherwise using values derived from the loadnum
|
||||
* field in the obj_zone database table.
|
||||
*/
|
||||
public void setBounds() {
|
||||
|
||||
float halfExtentX;
|
||||
float halfExtentY;
|
||||
|
||||
// Set initial bounds object
|
||||
|
||||
this.bounds = Bounds.borrow();
|
||||
|
||||
// Player cities are assigned default value
|
||||
|
||||
if (this.loadNum == 0) {
|
||||
bounds.setBounds(new Vector2f(this.absX, this.absZ), new Vector2f(Enum.CityBoundsType.ZONE.extents, Enum.CityBoundsType.ZONE.extents), 0.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
// All other zones have bounding boxes loaded from database
|
||||
ResultSet rs = DbManager.ZoneQueries.GET_ZONE_EXTENTS(this.loadNum);
|
||||
boolean loaded = false;
|
||||
|
||||
if (rs != null)
|
||||
try {
|
||||
if (rs.next()) {
|
||||
halfExtentX = rs.getFloat("xRadius");
|
||||
halfExtentY = rs.getFloat("zRadius");
|
||||
this.bounds.setBounds(new Vector2f(this.absX, this.absZ), new Vector2f(halfExtentX, halfExtentY), 0.0f);
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error("SQLException: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (!loaded) {
|
||||
|
||||
// Default to Citygrid size on error
|
||||
|
||||
bounds.setBounds(new Vector2f(this.absX, this.absZ), new Vector2f(Enum.CityBoundsType.ZONE.extents, Enum.CityBoundsType.ZONE.extents), 0.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public int getPlayerCityUUID() {
|
||||
if (this.playerCityID == 0)
|
||||
return 0;
|
||||
return this.playerCityID;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return zoneName;
|
||||
}
|
||||
|
||||
public float getXCoord() {
|
||||
return xCoord;
|
||||
}
|
||||
|
||||
public float getYCoord() {
|
||||
return yCoord;
|
||||
}
|
||||
|
||||
public float getZCoord() {
|
||||
return zCoord;
|
||||
}
|
||||
|
||||
public int getLoadNum() {
|
||||
return loadNum;
|
||||
}
|
||||
|
||||
public int getLoadNumClient() {
|
||||
return loadNum;
|
||||
}
|
||||
|
||||
public byte getSafeZone() {
|
||||
return safeZone;
|
||||
}
|
||||
|
||||
public String getIcon1() {
|
||||
return Icon1;
|
||||
}
|
||||
|
||||
public String getIcon2() {
|
||||
return Icon2;
|
||||
}
|
||||
|
||||
public String getIcon3() {
|
||||
return Icon3;
|
||||
}
|
||||
|
||||
public void setParent(final Zone value) {
|
||||
|
||||
this.parent = value;
|
||||
this.parentZoneID = (this.parent != null) ? this.parent.getObjectUUID() : 0;
|
||||
|
||||
if (this.parent != null) {
|
||||
this.absX = this.xCoord + parent.absX;
|
||||
this.absY = this.yCoord + parent.absY;
|
||||
this.absZ = this.zCoord + parent.absZ;
|
||||
|
||||
if (this.minLvl == 0 || this.maxLvl == 0){
|
||||
this.minLvl = this.parent.minLvl;
|
||||
this.maxLvl = this.parent.maxLvl;
|
||||
}
|
||||
} else { //only the Sea Floor zone does not have a parent
|
||||
this.absX = this.xCoord;
|
||||
this.absY = MBServerStatics.SEA_FLOOR_ALTITUDE;
|
||||
this.absZ = this.zCoord;
|
||||
}
|
||||
|
||||
// Zone AABB is set here as it's coordinate space is world requiring a parent.
|
||||
this.setBounds();
|
||||
|
||||
if (this.getHeightMap() != null && this.getHeightMap().getSeaLevel() != 0)
|
||||
this.seaLevel = this.getHeightMap().getSeaLevel();
|
||||
|
||||
}
|
||||
|
||||
public void generateWorldAltitude(){
|
||||
|
||||
if (ZoneManager.getSeaFloor().getObjectUUID() == this.getObjectUUID()){
|
||||
this.worldAltitude = MBServerStatics.SEA_FLOOR_ALTITUDE;
|
||||
return;
|
||||
}
|
||||
|
||||
Zone parentZone = this.parent;
|
||||
|
||||
Zone currentZone = this;
|
||||
float altitude = this.absY;
|
||||
|
||||
//seafloor only zone with null parent;
|
||||
|
||||
while(parentZone != ZoneManager.getSeaFloor()){
|
||||
|
||||
if(parentZone.getHeightMap() != null){
|
||||
|
||||
Vector2f zoneLoc = ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone);
|
||||
altitude += parentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc);
|
||||
|
||||
}
|
||||
currentZone = parentZone;
|
||||
parentZone = parentZone.parent;
|
||||
|
||||
}
|
||||
|
||||
this.worldAltitude = altitude;
|
||||
|
||||
if (ZoneManager.getSeaFloor().equals(this))
|
||||
this.seaLevel = 0;
|
||||
else if
|
||||
(this.getHeightMap() != null && this.getHeightMap().getSeaLevel() == 0){
|
||||
this.seaLevel = this.parent.seaLevel;
|
||||
|
||||
}else if (this.getHeightMap() != null){
|
||||
this.seaLevel = this.worldAltitude + this.getHeightMap().getSeaLevel();
|
||||
}else {
|
||||
this.seaLevel = this.parent.seaLevel;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Zone getParent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
public float getAbsX() {
|
||||
return this.absX;
|
||||
}
|
||||
|
||||
public float getAbsY() {
|
||||
return this.absY;
|
||||
}
|
||||
|
||||
public float getAbsZ() {
|
||||
return this.absZ;
|
||||
}
|
||||
|
||||
public boolean isMacroZone() {
|
||||
|
||||
// Player cities are not considered a macrozone
|
||||
// although their parent is always a continent.
|
||||
|
||||
if (this.isPlayerCity == true)
|
||||
return false;
|
||||
|
||||
if (this.parent == null)
|
||||
return false;
|
||||
|
||||
return (this.parent.isContininent() == true);
|
||||
}
|
||||
|
||||
public boolean isNPCCity() {
|
||||
return this.isNPCCity;
|
||||
}
|
||||
|
||||
public boolean isPlayerCity() {
|
||||
return this.isPlayerCity;
|
||||
}
|
||||
|
||||
public void setNPCCity(boolean value) {
|
||||
this.isNPCCity = value;
|
||||
}
|
||||
|
||||
public void setPlayerCity(boolean value) {
|
||||
this.isPlayerCity = value;
|
||||
}
|
||||
|
||||
public Vector3fImmutable getLoc() {
|
||||
return new Vector3fImmutable(this.absX, this.absY, this.absZ);
|
||||
}
|
||||
|
||||
public int getParentZoneID() {
|
||||
return this.parentZoneID;
|
||||
}
|
||||
|
||||
public ArrayList<Zone> getNodes() {
|
||||
if (this.nodes == null) {
|
||||
this.nodes = DbManager.ZoneQueries.GET_MAP_NODES(super.getObjectUUID());
|
||||
|
||||
//Add reverse lookup for child->parent
|
||||
if (this.nodes != null)
|
||||
for (Zone zone : this.nodes) {
|
||||
zone.setParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public void addNode(Zone child) {
|
||||
this.nodes.add(child);
|
||||
}
|
||||
|
||||
public void removeNode(Zone child) {
|
||||
this.nodes.remove(child);
|
||||
}
|
||||
|
||||
/*
|
||||
* Serializing
|
||||
*/
|
||||
|
||||
|
||||
public static void serializeForClientMsg(Zone zone,ByteBufferWriter writer) {
|
||||
|
||||
if (zone.loadNum == 0 && zone.playerCityID == 0)
|
||||
Logger.warn( "Warning! WorldServerMap with ID " + zone.getObjectUUID() + " has a loadnum of 0 (player city) and no city linked. This will probably crash the client!");
|
||||
|
||||
// Player City Terraform values serialized here.
|
||||
|
||||
if (zone.playerCityID > 0) {
|
||||
writer.put((byte) 1); // Player City - True
|
||||
writer.putFloat(Enum.CityBoundsType.TERRAFORM.extents);
|
||||
writer.putFloat(Enum.CityBoundsType.TERRAFORM.extents);
|
||||
} else
|
||||
writer.put((byte) 0); // Player City - False
|
||||
|
||||
writer.putFloat(zone.xCoord);
|
||||
writer.putFloat(zone.zCoord);
|
||||
writer.putFloat(zone.yCoord);
|
||||
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
writer.putInt(zone.loadNum);
|
||||
|
||||
if (zone.playerCityID > 0) {
|
||||
City k = City.getCity(zone.playerCityID);
|
||||
|
||||
if (k != null) {
|
||||
writer.putInt(k.getObjectType().ordinal());
|
||||
writer.putInt(k.getObjectUUID());
|
||||
}
|
||||
else
|
||||
writer.putLong(0x0);
|
||||
} else {
|
||||
writer.putInt(zone.getObjectType().ordinal());
|
||||
writer.putInt(zone.getObjectUUID());
|
||||
}
|
||||
writer.putInt(zone.nodes.size());
|
||||
|
||||
City city = City.getCity(zone.playerCityID);
|
||||
|
||||
if (city != null)
|
||||
writer.putString(city.getCityName());
|
||||
else
|
||||
writer.putString(zone.zoneName);
|
||||
writer.put(zone.safeZone);
|
||||
writer.putString(zone.Icon1);
|
||||
writer.putString(zone.Icon2);
|
||||
writer.putString(zone.Icon3);
|
||||
writer.put((byte) 0); // Pad
|
||||
|
||||
for (Zone child : zone.nodes) {
|
||||
Zone.serializeForClientMsg(child,writer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
public Zone findRuinedCityZone(float centerX, float centerY, float centerZ){
|
||||
Bounds cityBounds;
|
||||
cityBounds = Bounds.borrow();
|
||||
Zone RuinedZone = null;
|
||||
cityBounds.setBounds(new Vector2f(centerX, centerZ), new Vector2f(Enum.CityBoundsType.ZONE.extents, Enum.CityBoundsType.ZONE.extents), 0.0f);
|
||||
Zone currentZone = ZoneManager.findSmallestZone(new Vector3fImmutable(centerX, centerY, centerZ));
|
||||
if (currentZone != null)
|
||||
if (this.getObjectUUID() == currentZone.getObjectUUID()){
|
||||
|
||||
if (currentZone.getPlayerCityUUID() != 0){
|
||||
//null player city? skip..
|
||||
if (City.GetCityFromCache(currentZone.getPlayerCityUUID()) == null)
|
||||
RuinedZone = null;
|
||||
else //no tol? skip...
|
||||
if (City.GetCityFromCache(currentZone.getPlayerCityUUID()).getTOL() == null)
|
||||
RuinedZone = null;
|
||||
else
|
||||
if (City.GetCityFromCache(currentZone.getPlayerCityUUID()).getTOL().getRank() == -1)
|
||||
RuinedZone = currentZone;
|
||||
//Dead tree? skip.
|
||||
cityBounds.release();
|
||||
return RuinedZone;
|
||||
}
|
||||
}
|
||||
|
||||
for (Zone zone : this.getNodes()) {
|
||||
|
||||
if (zone == this)
|
||||
continue;
|
||||
|
||||
if (zone.isContininent() && zone.getPlayerCityUUID() == 0)
|
||||
continue;
|
||||
|
||||
if (zone.getPlayerCityUUID() != 0){
|
||||
//null player city? skip..
|
||||
if (City.GetCityFromCache(zone.getPlayerCityUUID()) == null)
|
||||
continue;
|
||||
//no tol? skip...
|
||||
if (City.GetCityFromCache(zone.getPlayerCityUUID()).getTOL() == null)
|
||||
continue;
|
||||
|
||||
//Dead tree? skip.
|
||||
if (Bounds.collide(zone.bounds, cityBounds, 0.0f)){
|
||||
if (City.GetCityFromCache(zone.getPlayerCityUUID()).getTOL().getRank() == -1){
|
||||
RuinedZone = zone;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cityBounds.release();
|
||||
return RuinedZone;
|
||||
}
|
||||
|
||||
public boolean isContininent() {
|
||||
|
||||
if (this.parent == null)
|
||||
return false;
|
||||
|
||||
return this.parent.equals(ZoneManager.getSeaFloor());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the bounds
|
||||
*/
|
||||
public Bounds getBounds() {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public void setHash() {
|
||||
|
||||
this.hash = DataWarehouse.hasher.encrypt(this.getObjectUUID());
|
||||
|
||||
// Write hash to player character table
|
||||
|
||||
DataWarehouse.writeHash(Enum.DataRecordType.ZONE, this.getObjectUUID());
|
||||
}
|
||||
|
||||
// Return heightmap for this Zone.
|
||||
|
||||
public HeightMap getHeightMap() {
|
||||
|
||||
if (this.isPlayerCity)
|
||||
return HeightMap.PlayerCityHeightMap;
|
||||
|
||||
return HeightMap.heightmapByLoadNum.get(this.loadNum);
|
||||
}
|
||||
|
||||
public float getSeaLevel() {
|
||||
return seaLevel;
|
||||
}
|
||||
|
||||
public float getWorldAltitude() {
|
||||
return worldAltitude;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user