Initial Repository Push

This commit is contained in:
2022-04-30 09:41:17 -04:00
parent d4eef9097a
commit bbfdde57a3
835 changed files with 168392 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+235
View File
@@ -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);
}
}
}
}
+638
View File
@@ -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;
}
}
+390
View File
@@ -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);
}
}
+650
View File
@@ -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;
}
}
+220
View File
@@ -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;
}
}
+630
View File
@@ -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;
}
}
+64
View File
@@ -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
+51
View File
@@ -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;
}
}
+143
View File
@@ -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);
}
}
}
+87
View File
@@ -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);
}
}
+388
View File
@@ -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
+628
View File
@@ -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;
}
}
+211
View File
@@ -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
+121
View File
@@ -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
+65
View File
@@ -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;
}
}
+98
View File
@@ -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;
}
}
+301
View File
@@ -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;
}
}
+419
View File
@@ -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;
}
}
+665
View File
@@ -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;
}
}
+92
View File
@@ -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.
}
}
+47
View File
@@ -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;
}
}
+441
View File
@@ -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));
}
}
}
+118
View File
@@ -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];
}
}
}
+182
View File
@@ -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
+102
View File
@@ -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;
}
}
+77
View File
@@ -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;
}
}
+94
View File
@@ -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;
}
+93
View File
@@ -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 + ')';
}
}
+171
View File
@@ -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
+918
View File
@@ -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;
}
}
+102
View File
@@ -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
+429
View File
@@ -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.
}
}
+72
View File
@@ -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;
}
}
+63
View File
@@ -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
+79
View File
@@ -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;
}
}
+58
View File
@@ -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() {}
}
+49
View File
@@ -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();
}
}
+791
View File
@@ -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;
}
}
+94
View File
@@ -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
+396
View File
@@ -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;
}
}
+66
View File
@@ -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;
}
}
+95
View File
@@ -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;
}
}
+396
View File
@@ -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;
}
}
+408
View File
@@ -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;
}
}
+59
View File
@@ -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;
}
}
+57
View File
@@ -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
+106
View File
@@ -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;
}
}
+119
View File
@@ -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() {
}
}
+121
View File
@@ -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() {}
}
+500
View File
@@ -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
+122
View File
@@ -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);
}
}
}
}
+169
View File
@@ -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;
}
}
+138
View File
@@ -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() {}
}
+194
View File
@@ -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
+236
View File
@@ -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;
}
}
+203
View File
@@ -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;
}
}
+368
View File
@@ -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;
}
}
+460
View File
@@ -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);
}
}
}
*/
}
+384
View File
@@ -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;
}
}
+562
View File
@@ -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;
}
}
+69
View File
@@ -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);
}
}
+217
View File
@@ -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();
}
}
+107
View File
@@ -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
}
}
+72
View File
@@ -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();
}
}
+220
View File
@@ -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;
}
}
+355
View File
@@ -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;
}
}
+97
View File
@@ -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() {
}
}
+160
View File
@@ -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
}
}
+77
View File
@@ -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() {
}
}
+101
View File
@@ -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;
}
}
+111
View File
@@ -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;
}
}
+74
View File
@@ -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
+512
View File
@@ -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;
}
}