Compare commits

..
Author SHA1 Message Date
SlaveOfMagicbot 8a136d84f4 refactor: migrate JodaTime to java.time (rebuild on subdate2 ab96cfc)
Complete the JodaTime -> java.time migration across 30 files on the
correct subdate2 base. No org.joda references remain.
2026-10-09 20:12:23 -05:00
287 changed files with 7025 additions and 9502 deletions

No files matched your search

@@ -468,12 +468,7 @@ public enum InterestManager implements Runnable {
continue; continue;
awonpc.playerAgroMap.put(player.getObjectUUID(), 0f); awonpc.playerAgroMap.put(player.getObjectUUID(), 0f);
((Mob) awonpc).setCombatTarget(null);
// siege engines keep firing at their target when a new player loads them
if (!awonpc.isSiege())
((Mob) awonpc).setCombatTarget(null);
lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii()); lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii());
} else if ((awo.getObjectTypeMask() & MBServerStatics.MASK_NPC) != 0) { } else if ((awo.getObjectTypeMask() & MBServerStatics.MASK_NPC) != 0) {
@@ -118,6 +118,11 @@ public class WorldGrid {
return outbound; return outbound;
} }
public static HashSet<AbstractWorldObject> getObjectsInRangePartialNecroPets(Vector3fImmutable loc, double r) {
HashSet<AbstractWorldObject> outbound = new HashSet<>();
return outbound;
}
public static HashSet<AbstractWorldObject> getObjectsInRangeContains(Vector3fImmutable loc, double r, int mask) { public static HashSet<AbstractWorldObject> getObjectsInRangeContains(Vector3fImmutable loc, double r, int mask) {
HashSet<AbstractWorldObject> outbound = getObjectsInRangePartial(loc, r, mask); HashSet<AbstractWorldObject> outbound = getObjectsInRangePartial(loc, r, mask);
return outbound; return outbound;
+10 -11
View File
@@ -14,7 +14,6 @@ import engine.mbEnums;
import engine.objects.Bane; import engine.objects.Bane;
import engine.objects.City; import engine.objects.City;
import engine.workthreads.WarehousePushThread; import engine.workthreads.WarehousePushThread;
import org.joda.time.DateTime;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.*; import java.sql.*;
@@ -34,8 +33,8 @@ public class BaneRecord extends DataRecord {
private String baneDropperHash; private String baneDropperHash;
private String baneGuildHash; private String baneGuildHash;
private String baneNationHash; private String baneNationHash;
private DateTime baneLiveTime; private LocalDateTime baneLiveTime;
private DateTime baneDropTime; private LocalDateTime baneDropTime;
private BaneRecord(Bane bane) { private BaneRecord(Bane bane) {
this.recordType = mbEnums.DataRecordType.BANE; this.recordType = mbEnums.DataRecordType.BANE;
@@ -129,9 +128,9 @@ public class BaneRecord extends DataRecord {
return outStatement; return outStatement;
} }
public static DateTime getLastBaneDateTime(City city) { public static LocalDateTime getLastBaneDateTime(City city) {
DateTime outDateTime = null; LocalDateTime outDateTime = null;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement statement = buildDateTimeQueryStatement(connection, city); PreparedStatement statement = buildDateTimeQueryStatement(connection, city);
@@ -139,7 +138,7 @@ public class BaneRecord extends DataRecord {
while (rs.next()) { while (rs.next()) {
outDateTime = new DateTime(rs.getTimestamp("endDatetime")); outDateTime = rs.getTimestamp("endDatetime").toLocalDateTime();
} }
@@ -160,7 +159,7 @@ public class BaneRecord extends DataRecord {
} }
public static void updateLiveDate(Bane bane, DateTime dateTime) { public static void updateLiveDate(Bane bane, LocalDateTime dateTime) {
if (bane == null) if (bane == null)
return; return;
@@ -175,13 +174,13 @@ public class BaneRecord extends DataRecord {
} }
} }
private static PreparedStatement buildUpdateLiveDateStatement(Connection connection, Bane bane, DateTime dateTime) throws SQLException { private static PreparedStatement buildUpdateLiveDateStatement(Connection connection, Bane bane, LocalDateTime dateTime) throws SQLException {
PreparedStatement outStatement = null; PreparedStatement outStatement = null;
String queryString = "UPDATE `warehouse_banehistory` SET `liveDatetime` = ?, `dirty` = 1 WHERE `city_id` = ? AND `resolution` = 'PENDING'"; String queryString = "UPDATE `warehouse_banehistory` SET `liveDatetime` = ?, `dirty` = 1 WHERE `city_id` = ? AND `resolution` = 'PENDING'";
outStatement = connection.prepareStatement(queryString); outStatement = connection.prepareStatement(queryString);
outStatement.setTimestamp(1, new java.sql.Timestamp(dateTime.getMillis())); outStatement.setTimestamp(1, Timestamp.valueOf(dateTime));
outStatement.setString(2, bane.getCity().getHash()); outStatement.setString(2, bane.getCity().getHash());
return outStatement; return outStatement;
@@ -366,12 +365,12 @@ public class BaneRecord extends DataRecord {
if (this.baneDropTime == null) if (this.baneDropTime == null)
outStatement.setNull(8, java.sql.Types.DATE); outStatement.setNull(8, java.sql.Types.DATE);
else else
outStatement.setTimestamp(8, new java.sql.Timestamp(this.baneDropTime.getMillis())); outStatement.setTimestamp(8, Timestamp.valueOf(this.baneDropTime));
if (this.baneLiveTime == null) if (this.baneLiveTime == null)
outStatement.setNull(9, java.sql.Types.DATE); outStatement.setNull(9, java.sql.Types.DATE);
else else
outStatement.setTimestamp(9, new java.sql.Timestamp(this.baneLiveTime.getMillis())); outStatement.setTimestamp(9, Timestamp.valueOf(this.baneLiveTime));
outStatement.setString(10, this.eventType.name()); outStatement.setString(10, this.eventType.name());
+3 -3
View File
@@ -14,7 +14,7 @@ import engine.objects.Bane;
import engine.objects.Building; import engine.objects.Building;
import engine.objects.City; import engine.objects.City;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import org.joda.time.DateTime; import java.time.LocalDateTime;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -71,12 +71,12 @@ public class dbBaneHandler extends dbHandlerBase {
} }
public boolean SET_BANE_TIME(DateTime toSet, int cityUUID) { public boolean SET_BANE_TIME(LocalDateTime toSet, int cityUUID) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_banes` SET `liveDate`=? WHERE `cityUUID`=?")) { PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_banes` SET `liveDate`=? WHERE `cityUUID`=?")) {
preparedStatement.setTimestamp(1, new java.sql.Timestamp(toSet.getMillis())); preparedStatement.setTimestamp(1, java.sql.Timestamp.valueOf(toSet));
preparedStatement.setLong(2, cityUUID); preparedStatement.setLong(2, cityUUID);
preparedStatement.execute(); preparedStatement.execute();
+60 -1
View File
@@ -13,7 +13,13 @@ import engine.gameManager.DbManager;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.objects.BaseClass; import engine.objects.BaseClass;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
public class dbBaseClassHandler extends dbHandlerBase { public class dbBaseClassHandler extends dbHandlerBase {
@@ -27,6 +33,59 @@ public class dbBaseClassHandler extends dbHandlerBase {
if (id == 0) if (id == 0)
return null; return null;
return (BaseClass) DbManager.getFromCache(GameObjectType.BaseClass, id); BaseClass baseClass = (BaseClass) DbManager.getFromCache(GameObjectType.BaseClass, id);
if (baseClass != null)
return baseClass;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `obj_account` WHERE `UID`=?")) {
preparedStatement.setLong(1, id);
ResultSet rs = preparedStatement.executeQuery();
baseClass = (BaseClass) getObjectFromRs(rs);
} catch (SQLException e) {
Logger.error(e);
}
return baseClass;
}
public ArrayList<BaseClass> GET_BASECLASS_FOR_RACE(final int id) {
ArrayList<BaseClass> baseClasses = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT b.* FROM `static_rune_baseclass` b, `static_rune_racebaseclass` r WHERE b.`ID` = r.`BaseClassID` && r.`RaceID` = ?")) {
preparedStatement.setInt(1, id);
ResultSet rs = preparedStatement.executeQuery();
baseClasses = getObjectsFromRs(rs, 20);
} catch (SQLException e) {
Logger.error(e);
}
return baseClasses;
}
public ArrayList<BaseClass> GET_ALL_BASE_CLASSES() {
ArrayList<BaseClass> baseClasses = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_baseclass`;")) {
ResultSet rs = preparedStatement.executeQuery();
baseClasses = getObjectsFromRs(rs, 20);
} catch (SQLException e) {
Logger.error(e);
}
return baseClasses;
} }
} }
@@ -17,7 +17,9 @@ import engine.mbEnums.DbObjectType;
import engine.mbEnums.ProtectionState; import engine.mbEnums.ProtectionState;
import engine.mbEnums.TaxType; import engine.mbEnums.TaxType;
import engine.objects.*; import engine.objects.*;
import org.joda.time.DateTime; import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -40,7 +42,7 @@ public class dbBuildingHandler extends dbHandlerBase {
public Building CREATE_BUILDING(int parentZoneID, int OwnerUUID, String name, int meshUUID, public Building CREATE_BUILDING(int parentZoneID, int OwnerUUID, String name, int meshUUID,
Vector3fImmutable location, float meshScale, int currentHP, Vector3fImmutable location, float meshScale, int currentHP,
ProtectionState protectionState, int currentGold, int rank, ProtectionState protectionState, int currentGold, int rank,
DateTime upgradeDate, int blueprintUUID, float w, float rotY) { Instant upgradeDate, int blueprintUUID, float w, float rotY) {
Building building = null; Building building = null;
@@ -61,7 +63,7 @@ public class dbBuildingHandler extends dbHandlerBase {
preparedStatement.setInt(12, rank); preparedStatement.setInt(12, rank);
if (upgradeDate != null) if (upgradeDate != null)
preparedStatement.setTimestamp(13, new java.sql.Timestamp(upgradeDate.getMillis())); preparedStatement.setTimestamp(13, new java.sql.Timestamp(upgradeDate.toEpochMilli()));
else else
preparedStatement.setNull(13, java.sql.Types.DATE); preparedStatement.setNull(13, java.sql.Types.DATE);
@@ -749,7 +751,7 @@ public class dbBuildingHandler extends dbHandlerBase {
return false; return false;
} }
public boolean updateBuildingUpgradeTime(LocalDateTime upgradeDateTime, Building toUpgrade, int costToUpgrade) { public boolean updateBuildingUpgradeTime(Instant upgradeDateTime, Building toUpgrade, int costToUpgrade) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_building SET upgradeDate=?, currentGold=? " PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_building SET upgradeDate=?, currentGold=? "
@@ -758,8 +760,7 @@ public class dbBuildingHandler extends dbHandlerBase {
if (upgradeDateTime == null) if (upgradeDateTime == null)
preparedStatement.setNull(1, java.sql.Types.DATE); preparedStatement.setNull(1, java.sql.Types.DATE);
else else
preparedStatement.setTimestamp(1, new java.sql.Timestamp(upgradeDateTime.atZone(ZoneId.systemDefault()) preparedStatement.setTimestamp(1, new java.sql.Timestamp(upgradeDateTime.toEpochMilli()));
.toInstant().toEpochMilli()));
preparedStatement.setInt(2, toUpgrade.getStrongboxValue() - costToUpgrade); preparedStatement.setInt(2, toUpgrade.getStrongboxValue() - costToUpgrade);
preparedStatement.setInt(3, toUpgrade.getObjectUUID()); preparedStatement.setInt(3, toUpgrade.getObjectUUID());
@@ -838,7 +839,7 @@ public class dbBuildingHandler extends dbHandlerBase {
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_building SET taxDate=? " PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_building SET taxDate=? "
+ "WHERE UID = ?")) { + "WHERE UID = ?")) {
preparedStatement.setTimestamp(1, new java.sql.Timestamp(DateTime.now().plusDays(7).getMillis())); preparedStatement.setTimestamp(1, new java.sql.Timestamp(Instant.now().plus(7, java.time.temporal.ChronoUnit.DAYS).toEpochMilli()));
preparedStatement.setInt(2, building.getObjectUUID()); preparedStatement.setInt(2, building.getObjectUUID());
return (preparedStatement.executeUpdate() > 0); return (preparedStatement.executeUpdate() > 0);
@@ -0,0 +1,303 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.gameManager.PowersManager;
import engine.mbEnums;
import engine.powers.EffectsBase;
import engine.powers.effectmodifiers.*;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
public class dbEffectsBaseHandler extends dbHandlerBase {
public dbEffectsBaseHandler() {
}
public static ArrayList<EffectsBase> getAllEffectsBase() {
ArrayList<EffectsBase> effectList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement prepareStatement = connection.prepareStatement("SELECT * FROM static_power_effectbase ORDER BY `IDString` DESC")) {
ResultSet rs = prepareStatement.executeQuery();
while (rs.next()) {
EffectsBase effectBase = new EffectsBase(rs);
effectList.add(effectBase);
}
} catch (SQLException e) {
Logger.error(e.toString());
}
return effectList;
}
public static void cacheAllEffectModifiers() {
String IDString;
AbstractEffectModifier abstractEffectModifier = null;
try (Connection connection = DbManager.getConnection();
PreparedStatement prepareStatement = connection.prepareStatement("SELECT * FROM static_power_effectmod")) {
ResultSet rs = prepareStatement.executeQuery();
while (rs.next()) {
IDString = rs.getString("IDString");
EffectsBase effectBase = PowersManager.getEffectByIDString(IDString);
mbEnums.ModType modifier = mbEnums.ModType.GetModType(rs.getString("modType"));
//combine item prefix and suffix effect modifiers
abstractEffectModifier = getCombinedModifiers(abstractEffectModifier, rs, effectBase, modifier);
if (abstractEffectModifier != null) {
if (EffectsBase.modifiersMap.containsKey(effectBase.getIDString()) == false)
EffectsBase.modifiersMap.put(effectBase.getIDString(), new HashSet<>());
EffectsBase.modifiersMap.get(effectBase.getIDString()).add(abstractEffectModifier);
}
}
} catch (Exception e) {
Logger.error(e);
}
}
private static AbstractEffectModifier getCombinedModifiers(AbstractEffectModifier abstractEffectModifier, ResultSet rs, EffectsBase effectBase, mbEnums.ModType modifier) throws SQLException {
switch (modifier) {
case AdjustAboveDmgCap:
abstractEffectModifier = new AdjustAboveDmgCapEffectModifier(rs);
break;
case Ambidexterity:
abstractEffectModifier = new AmbidexterityEffectModifier(rs);
break;
case AnimOverride:
break;
case ArmorPiercing:
abstractEffectModifier = new ArmorPiercingEffectModifier(rs);
break;
case AttackDelay:
abstractEffectModifier = new AttackDelayEffectModifier(rs);
break;
case Attr:
abstractEffectModifier = new AttributeEffectModifier(rs);
break;
case BlackMantle:
abstractEffectModifier = new BlackMantleEffectModifier(rs);
break;
case BladeTrails:
abstractEffectModifier = new BladeTrailsEffectModifier(rs);
break;
case Block:
abstractEffectModifier = new BlockEffectModifier(rs);
break;
case BlockedPowerType:
abstractEffectModifier = new BlockedPowerTypeEffectModifier(rs);
break;
case CannotAttack:
abstractEffectModifier = new CannotAttackEffectModifier(rs);
break;
case CannotCast:
abstractEffectModifier = new CannotCastEffectModifier(rs);
break;
case CannotMove:
abstractEffectModifier = new CannotMoveEffectModifier(rs);
break;
case CannotTrack:
abstractEffectModifier = new CannotTrackEffectModifier(rs);
break;
case Charmed:
abstractEffectModifier = new CharmedEffectModifier(rs);
break;
case ConstrainedAmbidexterity:
abstractEffectModifier = new ConstrainedAmbidexterityEffectModifier(rs);
break;
case DamageCap:
abstractEffectModifier = new DamageCapEffectModifier(rs);
break;
case DamageShield:
abstractEffectModifier = new DamageShieldEffectModifier(rs);
break;
case DCV:
abstractEffectModifier = new DCVEffectModifier(rs);
break;
case Dodge:
abstractEffectModifier = new DodgeEffectModifier(rs);
break;
case DR:
abstractEffectModifier = new DREffectModifier(rs);
break;
case Durability:
abstractEffectModifier = new DurabilityEffectModifier(rs);
break;
case ExclusiveDamageCap:
abstractEffectModifier = new ExclusiveDamageCapEffectModifier(rs);
break;
case Fade:
abstractEffectModifier = new FadeEffectModifier(rs);
break;
case Fly:
abstractEffectModifier = new FlyEffectModifier(rs);
break;
case Health:
abstractEffectModifier = new HealthEffectModifier(rs);
break;
case HealthFull:
abstractEffectModifier = new HealthFullEffectModifier(rs);
break;
case HealthRecoverRate:
abstractEffectModifier = new HealthRecoverRateEffectModifier(rs);
break;
case IgnoreDamageCap:
abstractEffectModifier = new IgnoreDamageCapEffectModifier(rs);
break;
case IgnorePassiveDefense:
abstractEffectModifier = new IgnorePassiveDefenseEffectModifier(rs);
break;
case ImmuneTo:
abstractEffectModifier = new ImmuneToEffectModifier(rs);
break;
case ImmuneToAttack:
abstractEffectModifier = new ImmuneToAttackEffectModifier(rs);
break;
case ImmuneToPowers:
abstractEffectModifier = new ImmuneToPowersEffectModifier(rs);
break;
case Invisible:
abstractEffectModifier = new InvisibleEffectModifier(rs);
break;
case ItemName:
abstractEffectModifier = new ItemNameEffectModifier(rs);
if (((ItemNameEffectModifier) abstractEffectModifier).name.isEmpty())
break;
if (effectBase != null)
effectBase.setName((((ItemNameEffectModifier) abstractEffectModifier).name));
break;
case Mana:
abstractEffectModifier = new ManaEffectModifier(rs);
break;
case ManaFull:
abstractEffectModifier = new ManaFullEffectModifier(rs);
break;
case ManaRecoverRate:
abstractEffectModifier = new ManaRecoverRateEffectModifier(rs);
break;
case MaxDamage:
abstractEffectModifier = new MaxDamageEffectModifier(rs);
break;
case MeleeDamageModifier:
abstractEffectModifier = new MeleeDamageEffectModifier(rs);
break;
case MinDamage:
abstractEffectModifier = new MinDamageEffectModifier(rs);
break;
case NoMod:
abstractEffectModifier = new NoModEffectModifier(rs);
break;
case OCV:
abstractEffectModifier = new OCVEffectModifier(rs);
break;
case Parry:
abstractEffectModifier = new ParryEffectModifier(rs);
break;
case PassiveDefense:
abstractEffectModifier = new PassiveDefenseEffectModifier(rs);
break;
case PowerCost:
abstractEffectModifier = new PowerCostEffectModifier(rs);
break;
case PowerCostHealth:
abstractEffectModifier = new PowerCostHealthEffectModifier(rs);
break;
case PowerDamageModifier:
abstractEffectModifier = new PowerDamageEffectModifier(rs);
break;
case ProtectionFrom:
abstractEffectModifier = new ProtectionFromEffectModifier(rs);
break;
case Resistance:
abstractEffectModifier = new ResistanceEffectModifier(rs);
break;
case ScaleHeight:
abstractEffectModifier = new ScaleHeightEffectModifier(rs);
break;
case ScaleWidth:
abstractEffectModifier = new ScaleWidthEffectModifier(rs);
break;
case ScanRange:
abstractEffectModifier = new ScanRangeEffectModifier(rs);
break;
case SeeInvisible:
abstractEffectModifier = new SeeInvisibleEffectModifier(rs);
break;
case Silenced:
abstractEffectModifier = new SilencedEffectModifier(rs);
break;
case Skill:
abstractEffectModifier = new SkillEffectModifier(rs);
break;
case Slay:
abstractEffectModifier = new SlayEffectModifier(rs);
break;
case Speed:
abstractEffectModifier = new SpeedEffectModifier(rs);
break;
case SpireBlock:
abstractEffectModifier = new SpireBlockEffectModifier(rs);
break;
case Stamina:
abstractEffectModifier = new StaminaEffectModifier(rs);
break;
case StaminaFull:
abstractEffectModifier = new StaminaFullEffectModifier(rs);
break;
case StaminaRecoverRate:
abstractEffectModifier = new StaminaRecoverRateEffectModifier(rs);
break;
case Stunned:
abstractEffectModifier = new StunnedEffectModifier(rs);
break;
case Value:
abstractEffectModifier = new ValueEffectModifier(rs);
if (effectBase != null) {
ValueEffectModifier valueEffect = (ValueEffectModifier) abstractEffectModifier;
effectBase.setValue(valueEffect.minMod);
}
break;
case WeaponProc:
abstractEffectModifier = new WeaponProcEffectModifier(rs);
break;
case WeaponRange:
abstractEffectModifier = new WeaponRangeEffectModifier(rs);
break;
case WeaponSpeed:
abstractEffectModifier = new WeaponSpeedEffectModifier(rs);
break;
}
return abstractEffectModifier;
}
}
@@ -0,0 +1,58 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.gameManager.PowersManager;
import engine.mbEnums;
import engine.objects.EffectsResourceCosts;
import org.json.JSONObject;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
public class dbEffectsResourceCostHandler extends dbHandlerBase {
public dbEffectsResourceCostHandler() {
this.localClass = EffectsResourceCosts.class;
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
}
public void LOAD_ALL_COSTMAPS() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_effect_costmaps`")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
String effectID = rs.getString("effectID");
String costString = rs.getString("costmap");
JSONObject costJSON = new JSONObject(costString);
HashMap<mbEnums.ResourceType, Integer> costmap = new HashMap<>();
for (String key : costJSON.keySet()) {
int value = costJSON.getInt(key);
costmap.put(mbEnums.ResourceType.valueOf(key), value);
}
PowersManager._effect_costMaps.put(effectID, costmap);
}
} catch (SQLException e) {
Logger.error(e);
}
}
}
+3 -3
View File
@@ -14,7 +14,7 @@ import engine.mbEnums;
import engine.mbEnums.GuildHistoryType; import engine.mbEnums.GuildHistoryType;
import engine.objects.*; import engine.objects.*;
import engine.server.world.WorldServer; import engine.server.world.WorldServer;
import org.joda.time.DateTime; import java.time.Instant;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.*; import java.sql.*;
@@ -125,7 +125,7 @@ public class dbGuildHandler extends dbHandlerBase {
return false; return false;
} }
public boolean ADD_TO_GUILDHISTORY(int target, PlayerCharacter playerCharacter, DateTime historyDate, GuildHistoryType historyType) { public boolean ADD_TO_GUILDHISTORY(int target, PlayerCharacter playerCharacter, Instant historyDate, GuildHistoryType historyType) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_character_guildhistory` (`GuildID`, `CharacterID`, `historyDate`, `historyType`) VALUES (?,?,?,?)")) { PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_character_guildhistory` (`GuildID`, `CharacterID`, `historyDate`, `historyType`) VALUES (?,?,?,?)")) {
@@ -136,7 +136,7 @@ public class dbGuildHandler extends dbHandlerBase {
if (historyDate == null) if (historyDate == null)
preparedStatement.setNull(3, java.sql.Types.DATE); preparedStatement.setNull(3, java.sql.Types.DATE);
else else
preparedStatement.setTimestamp(3, new Timestamp(historyDate.getMillis())); preparedStatement.setTimestamp(3, java.sql.Timestamp.from(historyDate));
preparedStatement.setString(4, historyType.name()); preparedStatement.setString(4, historyType.name());
+35 -9
View File
@@ -16,6 +16,8 @@ import engine.mbEnums.ItemType;
import engine.objects.AbstractCharacter; import engine.objects.AbstractCharacter;
import engine.objects.CharacterItemManager; import engine.objects.CharacterItemManager;
import engine.objects.Item; import engine.objects.Item;
import engine.objects.ItemTemplate;
import org.json.JSONObject;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -175,23 +177,47 @@ public class dbItemHandler extends dbHandlerBase {
return itemList; return itemList;
} }
public HashMap<Integer, Integer> LOAD_TEMPLATE_MODTABLES() { public void LOAD_ITEM_TEMPLATES() {
HashMap<Integer, Integer> modTables = new HashMap<>(); HashMap<ItemType, Integer> templateTCountMap = new HashMap<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_item_templates`;");
ResultSet rs = preparedStatement.executeQuery()) {
while (rs.next()) {
int templateID = rs.getInt("id");
JSONObject jsonObject = new JSONObject(rs.getString("template"));
ItemTemplate itemTemplate = new ItemTemplate(jsonObject);
itemTemplate.template_id = templateID;
ItemTemplate.templates.put(templateID, itemTemplate);
templateTCountMap.merge(itemTemplate.item_type, 1, Integer::sum);
}
Logger.info(templateTCountMap.toString());
} catch (Exception e) {
Logger.error(e);
}
}
public void LOAD_TEMPLATE_MODTABLES() {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_vendor_items`;"); PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_vendor_items`;");
ResultSet rs = preparedStatement.executeQuery()) { ResultSet rs = preparedStatement.executeQuery()) {
while (rs.next()) while (rs.next()) {
modTables.put(rs.getInt("templateID"), rs.getInt("modTable")); int templateID = rs.getInt("templateID");
int modTable = rs.getInt("modTable");
ItemTemplate template = ItemTemplate.templates.get(templateID);
template.modTable = modTable;
}
} catch (Exception e) { } catch (Exception e) {
Logger.error(e); Logger.error(e);
} }
Logger.info("read: " + modTables.size());
return modTables;
} }
public Item GET_ITEM(final int itemUUID) { public Item GET_ITEM(final int itemUUID) {
@@ -299,7 +325,7 @@ public class dbItemHandler extends dbHandlerBase {
for (Item item : inventory) { for (Item item : inventory) {
if (item.template.getItemType().equals(ItemType.GOLD)) if (item.template.item_type.equals(ItemType.GOLD))
continue; continue;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
@@ -448,7 +474,7 @@ public class dbItemHandler extends dbHandlerBase {
*/ */
public boolean UPDATE_GOLD(final Item item, int newValue, int oldValue) { public boolean UPDATE_GOLD(final Item item, int newValue, int oldValue) {
if (!item.template.getItemType().equals(ItemType.GOLD)) if (!item.template.item_type.equals(ItemType.GOLD))
return false; return false;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
@@ -528,7 +554,7 @@ public class dbItemHandler extends dbHandlerBase {
// Write 0 if we will not modify the value from template // Write 0 if we will not modify the value from template
if (value == item.template.getItemValue()) if (value == item.template.item_value)
value = 0; value = 0;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
+46
View File
@@ -0,0 +1,46 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.mbEnums;
import engine.objects.Kit;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
public class dbKitHandler extends dbHandlerBase {
public dbKitHandler() {
this.localClass = Kit.class;
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
}
public ArrayList<Kit> GET_ALL_KITS() {
ArrayList<Kit> kitList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_validkit`")) {
ResultSet rs = preparedStatement.executeQuery();
kitList = getObjectsFromRs(rs, 20);
} catch (SQLException e) {
Logger.error(e);
}
return kitList;
}
}
+17
View File
@@ -11,6 +11,7 @@ package engine.db.handlers;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.loot.*; import engine.loot.*;
import engine.objects.Item;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -220,4 +221,20 @@ public class dbLootHandler extends dbHandlerBase {
return bootySets; return bootySets;
} }
public void LOAD_ENCHANT_VALUES() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `IDString`, `minMod` FROM `static_power_effectmod` WHERE `modType` = ?")) {
preparedStatement.setString(1, "Value");
ResultSet rs = preparedStatement.executeQuery();
while (rs.next())
Item.addEnchantValue(rs.getString("IDString"), rs.getInt("minMod"));
} catch (SQLException e) {
Logger.error(e);
}
}
} }
+66 -3
View File
@@ -13,6 +13,8 @@ import engine.gameManager.DbManager;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.objects.MobBase; import engine.objects.MobBase;
import engine.objects.MobBaseEffects;
import engine.objects.MobBaseStats;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -67,10 +69,71 @@ public class dbMobBaseHandler extends dbHandlerBase {
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);
} }
Logger.info("Loaded " + mobbaseList.size() + " mobbases");
return mobbaseList; return mobbaseList;
} }
public ArrayList<MobBaseEffects> GET_RUNEBASE_EFFECTS(int runeID) {
ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_mobbase_effects` WHERE `mobbaseUUID` = ?")) {
preparedStatement.setInt(1, runeID);
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
MobBaseEffects mbs = new MobBaseEffects(rs);
effectsList.add(mbs);
}
} catch (SQLException e) {
Logger.error(e);
}
return effectsList;
}
public MobBaseStats LOAD_STATS(int mobBaseUUID) {
MobBaseStats mobBaseStats = MobBaseStats.GetGenericStats();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_mobbase_stats` WHERE `mobbaseUUID` = ?")) {
preparedStatement.setInt(1, mobBaseUUID);
ResultSet rs = preparedStatement.executeQuery();
while (rs.next())
mobBaseStats = new MobBaseStats(rs);
} catch (SQLException e) {
Logger.error(e);
}
return mobBaseStats;
}
public void LOAD_ALL_MOBBASE_SPEEDS(MobBase mobBase) {
if (mobBase.getLoadID() == 0)
return;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_mobbase_race` WHERE `mobbaseID` = ?")) {
preparedStatement.setInt(1, mobBase.getLoadID());
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
float walk = rs.getFloat("walkStandard");
float walkCombat = rs.getFloat("walkCombat");
float run = rs.getFloat("runStandard");
float runCombat = rs.getFloat("runCombat");
mobBase.updateSpeeds(walk, walkCombat, run, runCombat);
}
} catch (SQLException e) {
Logger.error(e);
}
}
} }
+4 -3
View File
@@ -12,7 +12,8 @@ package engine.db.handlers;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.mbEnums; import engine.mbEnums;
import engine.objects.Mob; import engine.objects.Mob;
import org.joda.time.DateTime; import java.time.LocalDateTime;
import java.time.ZoneId;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -82,7 +83,7 @@ public class dbMobHandler extends dbHandlerBase {
return mobileList; return mobileList;
} }
public boolean updateUpgradeTime(Mob mob, DateTime upgradeDateTime) { public boolean updateUpgradeTime(Mob mob, LocalDateTime upgradeDateTime) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_mob SET upgradeDate=? " PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_mob SET upgradeDate=? "
@@ -91,7 +92,7 @@ public class dbMobHandler extends dbHandlerBase {
if (upgradeDateTime == null) if (upgradeDateTime == null)
preparedStatement.setNull(1, java.sql.Types.DATE); preparedStatement.setNull(1, java.sql.Types.DATE);
else else
preparedStatement.setTimestamp(1, new java.sql.Timestamp(upgradeDateTime.getMillis())); preparedStatement.setTimestamp(1, new java.sql.Timestamp(upgradeDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()));
preparedStatement.setInt(2, mob.getObjectUUID()); preparedStatement.setInt(2, mob.getObjectUUID());
+5 -4
View File
@@ -15,7 +15,8 @@ import engine.mbEnums;
import engine.mbEnums.ProfitType; import engine.mbEnums.ProfitType;
import engine.objects.NPC; import engine.objects.NPC;
import engine.objects.NPCProfits; import engine.objects.NPCProfits;
import org.joda.time.DateTime; import java.time.LocalDateTime;
import java.time.ZoneId;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -57,7 +58,7 @@ public class dbNPCHandler extends dbHandlerBase {
runeSets.put(runeSetID, runeList); runeSets.put(runeSetID, runeList);
} else { } else {
ArrayList<Integer> runeList = runeSets.get(runeSetID); ArrayList<Integer> runeList = runeSets.get(runeSetID);
runeList.add(runeBaseID); runeList.add(runeSetID);
runeSets.put(runeSetID, runeList); runeSets.put(runeSetID, runeList);
} }
} }
@@ -240,7 +241,7 @@ public class dbNPCHandler extends dbHandlerBase {
} }
} }
public boolean updateUpgradeTime(NPC npc, DateTime upgradeDateTime) { public boolean updateUpgradeTime(NPC npc, LocalDateTime upgradeDateTime) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_npc SET upgradeDate=? " PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_npc SET upgradeDate=? "
@@ -249,7 +250,7 @@ public class dbNPCHandler extends dbHandlerBase {
if (upgradeDateTime == null) if (upgradeDateTime == null)
preparedStatement.setNull(1, java.sql.Types.DATE); preparedStatement.setNull(1, java.sql.Types.DATE);
else else
preparedStatement.setTimestamp(1, new java.sql.Timestamp(upgradeDateTime.getMillis())); preparedStatement.setTimestamp(1, new java.sql.Timestamp(upgradeDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()));
preparedStatement.setInt(2, npc.getObjectUUID()); preparedStatement.setInt(2, npc.getObjectUUID());
@@ -0,0 +1,82 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.gameManager.PowersManager;
import engine.mbEnums;
import engine.objects.Mob;
import engine.powers.EffectsBase;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashSet;
public class dbPowerHandler extends dbHandlerBase {
public dbPowerHandler() {
this.localClass = Mob.class;
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
}
public static void addAllSourceTypes() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_power_sourcetype")) {
ResultSet rs = preparedStatement.executeQuery();
String IDString, source;
while (rs.next()) {
IDString = rs.getString("IDString");
int token = DbManager.hasher.SBStringHash(IDString);
source = rs.getString("source").replace("-", "").trim();
mbEnums.EffectSourceType effectSourceType = mbEnums.EffectSourceType.GetEffectSourceType(source);
if (EffectsBase.effectSourceTypeMap.containsKey(token) == false)
EffectsBase.effectSourceTypeMap.put(token, new HashSet<>());
EffectsBase.effectSourceTypeMap.get(token).add(effectSourceType);
}
} catch (Exception e) {
Logger.error(e);
}
}
public static void addAllAnimationOverrides() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_power_animation_override")) {
ResultSet rs = preparedStatement.executeQuery();
String IDString;
int animation;
while (rs.next()) {
IDString = rs.getString("IDString");
EffectsBase eb = PowersManager.getEffectByIDString(IDString);
if (eb != null)
IDString = eb.getIDString();
animation = rs.getInt("animation");
PowersManager.AnimationOverrides.put(IDString, animation);
}
} catch (Exception e) {
Logger.error(e);
}
}
}
@@ -27,17 +27,30 @@ public class dbPromotionClassHandler extends dbHandlerBase {
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName()); this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
} }
public ArrayList<Integer> GET_ALLOWED_RUNES(final PromotionClass pc) {
ArrayList<Integer> runeList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_promotionrunereq` WHERE `promoID`=?")) {
preparedStatement.setInt(1, pc.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery();
while (rs.next())
runeList.add(rs.getInt("runereqID"));
} catch (SQLException e) {
Logger.error(e);
}
return runeList;
}
public PromotionClass GET_PROMOTION_CLASS(final int objectUUID) { public PromotionClass GET_PROMOTION_CLASS(final int objectUUID) {
PromotionClass promotionClass; PromotionClass promotionClass = null;
if (objectUUID == 0)
return null;
promotionClass = (PromotionClass) DbManager.getFromCache(mbEnums.GameObjectType.PromotionClass, objectUUID);
if (promotionClass != null)
return promotionClass;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_promotion` WHERE `ID` = ?")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_promotion` WHERE `ID` = ?")) {
+60 -7
View File
@@ -10,14 +10,15 @@
package engine.db.handlers; package engine.db.handlers;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.objects.Race;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
public class dbRaceHandler extends dbHandlerBase { public class dbRaceHandler extends dbHandlerBase {
@@ -45,6 +46,27 @@ public class dbRaceHandler extends dbHandlerBase {
return integerSet; return integerSet;
} }
public HashSet<Integer> BEARD_STYLES_FOR_RACE(final int id) {
HashSet<Integer> integerSet = new HashSet<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `beardStyle` FROM `static_rune_racebeardstyle` WHERE `RaceID` = ?")) {
preparedStatement.setInt(1, id);
ResultSet rs = preparedStatement.executeQuery();
while (rs.next())
integerSet.add(rs.getInt(1));
} catch (SQLException e) {
Logger.error(e);
}
return integerSet;
}
public HashSet<Integer> HAIR_COLORS_FOR_RACE(final int id) { public HashSet<Integer> HAIR_COLORS_FOR_RACE(final int id) {
HashSet<Integer> integerSet = new HashSet<>(); HashSet<Integer> integerSet = new HashSet<>();
@@ -67,6 +89,28 @@ public class dbRaceHandler extends dbHandlerBase {
} }
public HashSet<Integer> HAIR_STYLES_FOR_RACE(final int id) {
HashSet<Integer> integerSet = new HashSet<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `hairStyle` FROM `static_rune_racehairstyle` WHERE `RaceID` = ?")) {
preparedStatement.setInt(1, id);
ResultSet rs = preparedStatement.executeQuery();
while (rs.next())
integerSet.add(rs.getInt(1));
} catch (SQLException e) {
Logger.error(e);
}
return integerSet;
}
public HashSet<Integer> SKIN_COLOR_FOR_RACE(final int id) { public HashSet<Integer> SKIN_COLOR_FOR_RACE(final int id) {
HashSet<Integer> integerSet = new HashSet<>(); HashSet<Integer> integerSet = new HashSet<>();
@@ -88,23 +132,32 @@ public class dbRaceHandler extends dbHandlerBase {
return integerSet; return integerSet;
} }
// Rune id -> {minHeight, strHeightMod}; the rows also decide which race runes are player races public ConcurrentHashMap<Integer, Race> LOAD_ALL_RACES() {
public HashMap<Integer, float[]> LOAD_RACE_HEIGHTS() {
HashMap<Integer, float[]> raceHeights = new HashMap<>(); ConcurrentHashMap<Integer, Race> races;
Race thisRace;
races = new ConcurrentHashMap<>();
int recordsRead = 0;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_race")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_race")) {
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) while (rs.next()) {
raceHeights.put(rs.getInt("ID"), new float[]{rs.getFloat("minHeight"), rs.getFloat("strHeightMod")});
recordsRead++;
thisRace = new Race(rs);
races.put(thisRace.getRaceRuneID(), thisRace);
}
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);
} }
return raceHeights; Logger.info("read: " + recordsRead + " cached: " + races.size());
return races;
} }
} }
@@ -0,0 +1,47 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.objects.Resists;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class dbResistHandler extends dbHandlerBase {
public dbResistHandler() {
}
public Resists GET_RESISTS_FOR_MOB(int resistID) {
Resists resists = null;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_mob_resists` WHERE `ID` = ?;")) {
preparedStatement.setInt(1, resistID);
ResultSet rs = preparedStatement.executeQuery();
if (rs.next())
resists = new Resists(rs);
} catch (SQLException e) {
Logger.error(e);
}
return resists;
}
}
@@ -0,0 +1,48 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.mbEnums;
import engine.objects.RuneBaseAttribute;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
public class dbRuneBaseAttributeHandler extends dbHandlerBase {
public dbRuneBaseAttributeHandler() {
this.localClass = RuneBaseAttribute.class;
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
}
public ArrayList<RuneBaseAttribute> GET_ATTRIBUTES_FOR_RUNEBASE() {
ArrayList<RuneBaseAttribute> runeBaseAttributesList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_runebaseattribute`")) {
ResultSet rs = preparedStatement.executeQuery();
runeBaseAttributesList = getObjectsFromRs(rs, 10);
} catch (SQLException e) {
Logger.error(e);
}
return runeBaseAttributesList;
}
}
@@ -0,0 +1,92 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.mbEnums;
import engine.mbEnums.GameObjectType;
import engine.objects.AbstractGameObject;
import engine.objects.RuneBaseEffect;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
public class dbRuneBaseEffectHandler extends dbHandlerBase {
public dbRuneBaseEffectHandler() {
this.localClass = RuneBaseEffect.class;
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
}
public ArrayList<RuneBaseEffect> GET_EFFECTS_FOR_RUNEBASE(int id) {
ArrayList<RuneBaseEffect> runeBaseEffectsList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_baseeffect` WHERE `runeID`=?")) {
preparedStatement.setInt(1, id);
ResultSet rs = preparedStatement.executeQuery();
runeBaseEffectsList = getObjectsFromRs(rs, 250);
} catch (SQLException e) {
Logger.error(e);
}
return runeBaseEffectsList;
}
public ArrayList<RuneBaseEffect> GET_ALL_RUNEBASE_EFFECTS() {
ArrayList<RuneBaseEffect> runeBaseEffectsList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_baseeffect`;")) {
ResultSet rs = preparedStatement.executeQuery();
runeBaseEffectsList = getObjectsFromRs(rs, 250);
} catch (SQLException e) {
Logger.error(e);
}
return runeBaseEffectsList;
}
//This calls from cache only. Call this AFTER caching all runebase effects;
public HashMap<Integer, ArrayList<RuneBaseEffect>> LOAD_BASEEFFECTS_FOR_RUNEBASE() {
HashMap<Integer, ArrayList<RuneBaseEffect>> runeBaseEffectSet;
runeBaseEffectSet = new HashMap<>();
for (AbstractGameObject runeBaseEffect : DbManager.getList(GameObjectType.RuneBaseEffect)) {
int runeBaseID = ((RuneBaseEffect) runeBaseEffect).getRuneBaseID();
if (runeBaseEffectSet.get(runeBaseID) == null) {
ArrayList<RuneBaseEffect> runeBaseEffectList = new ArrayList<>();
runeBaseEffectList.add((RuneBaseEffect) runeBaseEffect);
runeBaseEffectSet.put(runeBaseID, runeBaseEffectList);
} else {
ArrayList<RuneBaseEffect> runeBaseEffectList = runeBaseEffectSet.get(runeBaseID);
runeBaseEffectList.add((RuneBaseEffect) runeBaseEffect);
runeBaseEffectSet.put(runeBaseID, runeBaseEffectList);
}
}
return runeBaseEffectSet;
}
}
+219 -44
View File
@@ -11,16 +11,17 @@ package engine.db.handlers;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.mbEnums; import engine.mbEnums;
import engine.objects.AbstractGameObject;
import engine.objects.BaseClass;
import engine.objects.PromotionClass;
import engine.objects.Race;
import engine.objects.RuneBase; import engine.objects.RuneBase;
import engine.powers.RunePowerEntry;
import engine.powers.RuneSkillAdjustEntry;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
public class dbRuneBaseHandler extends dbHandlerBase { public class dbRuneBaseHandler extends dbHandlerBase {
@@ -29,57 +30,231 @@ public class dbRuneBaseHandler extends dbHandlerBase {
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName()); this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
} }
// static_rune_lookup is generated for the DB views; a failed write must never stop the boot public static HashMap<Integer, ArrayList<RunePowerEntry>> LOAD_RUNE_POWERS() {
public static void WRITE_RUNE_LOOKUP() {
int rowsWritten = 0; HashMap<Integer, ArrayList<RunePowerEntry>> mobPowers = new HashMap<>();
RunePowerEntry runePowerEntry;
int rune_id;
int recordsRead = 0;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement deleteStatement = connection.prepareStatement("DELETE FROM `static_rune_lookup`"); PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_powers")) {
PreparedStatement insertStatement = connection.prepareStatement("INSERT INTO `static_rune_lookup` (`ID`, `type`, `name`) VALUES (?, ?, ?)")) {
connection.setAutoCommit(false); ResultSet rs = preparedStatement.executeQuery();
try { while (rs.next()) {
deleteStatement.executeUpdate();
for (Race race : Race.getAllRaces()) { recordsRead++;
addRuneLookupRow(insertStatement, race.getRaceRuneID(), "RACE", race.getName());
rowsWritten++; rune_id = rs.getInt("rune_id");
runePowerEntry = new RunePowerEntry(rs);
if (mobPowers.get(rune_id) == null) {
ArrayList<RunePowerEntry> runePowerList = new ArrayList<>();
runePowerList.add(runePowerEntry);
mobPowers.put(rune_id, runePowerList);
} else {
ArrayList<RunePowerEntry> powerList = mobPowers.get(rune_id);
powerList.add(runePowerEntry);
mobPowers.put(rune_id, powerList);
} }
for (AbstractGameObject baseClass : DbManager.getMap(mbEnums.GameObjectType.BaseClass).values()) {
addRuneLookupRow(insertStatement, baseClass.getObjectUUID(), "BASECLASS", ((BaseClass) baseClass).getName());
rowsWritten++;
}
for (AbstractGameObject promotionClass : DbManager.getMap(mbEnums.GameObjectType.PromotionClass).values()) {
addRuneLookupRow(insertStatement, promotionClass.getObjectUUID(), "PROMOTION", ((PromotionClass) promotionClass).getName());
rowsWritten++;
}
insertStatement.executeBatch();
connection.commit();
} catch (SQLException | RuntimeException e) {
// Roll back before setAutoCommit(true), which would otherwise commit the delete
connection.rollback();
throw e;
} finally {
connection.setAutoCommit(true);
} }
} catch (SQLException e) {
} catch (Exception e) { Logger.error(e);
Logger.warn("static_rune_lookup not written; DB views keep their old names: " + e.getMessage()); return mobPowers;
return;
} }
Logger.info("static_rune_lookup: wrote " + rowsWritten + " rows"); Logger.info("read: " + recordsRead + " cached: " + mobPowers.size());
return mobPowers;
} }
private static void addRuneLookupRow(PreparedStatement insertStatement, int runeID, String type, String name) throws SQLException { public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> LOAD_RUNE_SKILL_ADJUSTS() {
insertStatement.setInt(1, runeID);
insertStatement.setString(2, type); HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> runeSkillAdjusts = new HashMap<>();
insertStatement.setString(3, name); RuneSkillAdjustEntry runeSkillAdjustEntry;
insertStatement.addBatch();
int rune_id;
int recordsRead = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_skill_adjusts")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
recordsRead++;
rune_id = rs.getInt("rune_id");
runeSkillAdjustEntry = new RuneSkillAdjustEntry(rs);
if (runeSkillAdjusts.get(rune_id) == null) {
ArrayList<RuneSkillAdjustEntry> skillAdjustList = new ArrayList<>();
skillAdjustList.add(runeSkillAdjustEntry);
runeSkillAdjusts.put(rune_id, skillAdjustList);
} else {
ArrayList<RuneSkillAdjustEntry> powerList = runeSkillAdjusts.get(rune_id);
powerList.add(runeSkillAdjustEntry);
runeSkillAdjusts.put(rune_id, powerList);
}
}
} catch (SQLException e) {
Logger.error(e);
return runeSkillAdjusts;
}
Logger.info("read: " + recordsRead + " cached: " + runeSkillAdjusts.size());
return runeSkillAdjusts;
}
public void GET_RUNE_REQS(final RuneBase rb) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_runereq` WHERE `runeID` = ?")) {
preparedStatement.setInt(1, rb.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
int type = rs.getInt("type");
switch (type) {
case 1:
rb.getRace().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed"));
break;
case 2:
rb.getBaseClass().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed"));
break;
case 3:
rb.getPromotionClass().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed"));
break;
case 4:
rb.getDiscipline().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed"));
break;
case 5:
rb.getOverwrite().add(rs.getInt("requiredRuneID"));
break;
case 6:
rb.setLevelRequired(rs.getInt("requiredRuneID"));
break;
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
public RuneBase GET_RUNEBASE(final int id) {
RuneBase runeBase = null;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_runebase` WHERE `ID` = ?")) {
preparedStatement.setInt(1, id);
ResultSet rs = preparedStatement.executeQuery();
runeBase = (RuneBase) getObjectFromRs(rs);
} catch (SQLException e) {
Logger.error(e);
}
return runeBase;
}
public ArrayList<RuneBase> LOAD_ALL_RUNEBASES() {
ArrayList<RuneBase> runeBasesList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_runebase`;")) {
ResultSet rs = preparedStatement.executeQuery();
runeBasesList = getObjectsFromRs(rs, 1000);
} catch (SQLException e) {
Logger.error(e);
}
return runeBasesList;
}
public HashMap<Integer, ArrayList<Integer>> LOAD_ALLOWED_STARTING_RUNES_FOR_BASECLASS() {
HashMap<Integer, ArrayList<Integer>> runeSets = new HashMap<>();
int recordsRead = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_baseclassrune")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
recordsRead++;
int baseClassID = rs.getInt("BaseClassesID");
int runeBaseID = rs.getInt("RuneBaseID");
if (runeSets.get(baseClassID) == null) {
ArrayList<Integer> runeList = new ArrayList<>();
runeList.add(runeBaseID);
runeSets.put(baseClassID, runeList);
} else {
ArrayList<Integer> runeList = runeSets.get(baseClassID);
runeList.add(runeBaseID);
runeSets.put(baseClassID, runeList);
}
}
} catch (SQLException e) {
Logger.error(e);
}
Logger.info("read: " + recordsRead + " cached: " + runeSets.size());
return runeSets;
}
public HashMap<Integer, ArrayList<Integer>> LOAD_ALLOWED_STARTING_RUNES_FOR_RACE() {
HashMap<Integer, ArrayList<Integer>> runeSets;
runeSets = new HashMap<>();
int recordsRead = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_racerune")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
recordsRead++;
int raceID = rs.getInt("RaceID");
int runeBaseID = rs.getInt("RuneBaseID");
if (runeSets.get(raceID) == null) {
ArrayList<Integer> runeList = new ArrayList<>();
runeList.add(runeBaseID);
runeSets.put(raceID, runeList);
} else {
ArrayList<Integer> runeList = runeSets.get(raceID);
runeList.add(runeBaseID);
runeSets.put(raceID, runeList);
}
}
} catch (SQLException e) {
Logger.error(e);
}
Logger.info("read: " + recordsRead + " cached: " + runeSets.size());
return runeSets;
} }
} }
+3 -3
View File
@@ -16,7 +16,7 @@ import engine.mbEnums.ProtectionState;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Building; import engine.objects.Building;
import engine.objects.Shrine; import engine.objects.Shrine;
import org.joda.time.DateTime; import java.time.Instant;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -53,7 +53,7 @@ public class dbShrineHandler extends dbHandlerBase {
public ArrayList<AbstractGameObject> CREATE_SHRINE(int parentZoneID, int OwnerUUID, String name, int meshUUID, public ArrayList<AbstractGameObject> CREATE_SHRINE(int parentZoneID, int OwnerUUID, String name, int meshUUID,
Vector3fImmutable location, float meshScale, int currentHP, Vector3fImmutable location, float meshScale, int currentHP,
ProtectionState protectionState, int currentGold, int rank, ProtectionState protectionState, int currentGold, int rank,
DateTime upgradeDate, int blueprintUUID, float w, float rotY, String shrineType) { Instant upgradeDate, int blueprintUUID, float w, float rotY, String shrineType) {
ArrayList<AbstractGameObject> shrineList = new ArrayList<>(); ArrayList<AbstractGameObject> shrineList = new ArrayList<>();
@@ -74,7 +74,7 @@ public class dbShrineHandler extends dbHandlerBase {
preparedStatement.setInt(12, rank); preparedStatement.setInt(12, rank);
if (upgradeDate != null) if (upgradeDate != null)
preparedStatement.setTimestamp(13, new java.sql.Timestamp(upgradeDate.getMillis())); preparedStatement.setTimestamp(13, java.sql.Timestamp.from(upgradeDate));
else else
preparedStatement.setNull(13, java.sql.Types.DATE); preparedStatement.setNull(13, java.sql.Types.DATE);
+107 -16
View File
@@ -12,6 +12,7 @@ package engine.db.handlers;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.objects.MaxSkills;
import engine.objects.SkillsBase; import engine.objects.SkillsBase;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -19,6 +20,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
public class dbSkillBaseHandler extends dbHandlerBase { public class dbSkillBaseHandler extends dbHandlerBase {
@@ -29,33 +31,122 @@ public class dbSkillBaseHandler extends dbHandlerBase {
} }
public SkillsBase GET_BASE(final int objectUUID) { public SkillsBase GET_BASE(final int objectUUID) {
return (SkillsBase) DbManager.getFromCache(GameObjectType.SkillsBase, objectUUID);
}
public SkillsBase GET_BASE_BY_NAME(String name) { SkillsBase skillsBase = (SkillsBase) DbManager.getFromCache(GameObjectType.SkillsBase, objectUUID);
return SkillsBase.getFromCache(name);
}
public SkillsBase GET_BASE_BY_TOKEN(final int token) { if (skillsBase != null)
return SkillsBase.getFromCache(token); return skillsBase;
}
public HashMap<Integer, String> GET_ALL_SKILL_NAMES() {
HashMap<Integer, String> skillNames = new HashMap<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT ID, name FROM static_skill_skillsbase")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_skill_skillsbase WHERE ID = ?")) {
preparedStatement.setInt(1, objectUUID);
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) skillsBase = (SkillsBase) getObjectFromRs(rs);
skillNames.put(rs.getInt("ID"), rs.getString("name"));
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);
} }
return skillNames; SkillsBase.putInCache(skillsBase);
return skillsBase;
} }
public SkillsBase GET_BASE_BY_NAME(String name) {
SkillsBase skillsBase = SkillsBase.getFromCache(name);
if (skillsBase != null)
return skillsBase;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_skill_skillsbase WHERE name = ?")) {
preparedStatement.setString(1, name);
ResultSet rs = preparedStatement.executeQuery();
skillsBase = (SkillsBase) getObjectFromRs(rs);
} catch (SQLException e) {
Logger.error(e);
}
SkillsBase.putInCache(skillsBase);
return skillsBase;
}
public SkillsBase GET_BASE_BY_TOKEN(final int token) {
SkillsBase skillsBase = SkillsBase.getFromCache(token);
if (skillsBase != null)
return skillsBase;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_skill_skillsbase WHERE token = ?")) {
preparedStatement.setInt(1, token);
ResultSet rs = preparedStatement.executeQuery();
skillsBase = (SkillsBase) getObjectFromRs(rs);
} catch (SQLException e) {
Logger.error(e);
}
SkillsBase.putInCache(skillsBase);
return skillsBase;
}
public void LOAD_ALL_MAX_SKILLS_FOR_CONTRACT() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_maxskills`")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
MaxSkills maxSKills = new MaxSkills(rs);
if (MaxSkills.MaxSkillsSet.get(maxSKills.getRuneID()) == null) {
ArrayList<MaxSkills> newMaxSkillsList = new ArrayList<>();
newMaxSkillsList.add(maxSKills);
MaxSkills.MaxSkillsSet.put(maxSKills.getRuneID(), newMaxSkillsList);
} else
MaxSkills.MaxSkillsSet.get(maxSKills.getRuneID()).add(maxSKills);
}
} catch (SQLException e) {
Logger.error(e);
}
}
public void LOAD_ALL_RUNE_SKILLS() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_skill_skillsgranted`")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
int runeID = rs.getInt("runeID");
int token = rs.getInt("token");
int amount = rs.getInt("amount");
if (SkillsBase.runeSkillsCache.get(runeID) == null)
SkillsBase.runeSkillsCache.put(runeID, new HashMap<>());
SkillsBase.runeSkillsCache.get(runeID).put(token, amount);
}
} catch (SQLException e) {
Logger.error(e);
}
}
} }
@@ -9,8 +9,18 @@
package engine.db.handlers; package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.mbEnums; import engine.mbEnums;
import engine.objects.SkillReq; import engine.objects.SkillReq;
import engine.powers.PowersBase;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
public class dbSkillReqHandler extends dbHandlerBase { public class dbSkillReqHandler extends dbHandlerBase {
@@ -18,4 +28,72 @@ public class dbSkillReqHandler extends dbHandlerBase {
this.localClass = SkillReq.class; this.localClass = SkillReq.class;
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName()); this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
} }
public static ArrayList<PowersBase> getAllPowersBase() {
ArrayList<PowersBase> powerBaseList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_power_powerbase")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
PowersBase toAdd = new PowersBase(rs);
powerBaseList.add(toAdd);
}
} catch (SQLException e) {
Logger.error(e);
}
return powerBaseList;
}
public static void getFailConditions(HashMap<String, PowersBase> powers) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT IDString, type FROM static_power_failcondition where powerOrEffect = 'Power'")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
String type = rs.getString("type");
String IDString = rs.getString("IDString");
PowersBase pb = powers.get(IDString);
if (pb != null)
switch (type) {
case "CastSpell":
pb.cancelOnCastSpell = true;
break;
case "TakeDamage":
pb.cancelOnTakeDamage = true;
break;
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
public ArrayList<SkillReq> GET_REQS_FOR_RUNE(final int objectUUID) {
ArrayList<SkillReq> skillReqsList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_skill_skillreq` WHERE `runeID`=?")) {
preparedStatement.setInt(1, objectUUID);
ResultSet rs = preparedStatement.executeQuery();
skillReqsList = getObjectsFromRs(rs, 5);
} catch (SQLException e) {
Logger.error(e);
}
return skillReqsList;
}
} }
+8 -22
View File
@@ -20,9 +20,8 @@ import engine.objects.City;
import engine.objects.Transaction; import engine.objects.Transaction;
import engine.objects.Warehouse; import engine.objects.Warehouse;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.joda.time.DateTime; import java.time.Instant;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -41,7 +40,7 @@ public class dbWarehouseHandler extends dbHandlerBase {
} }
public boolean CREATE_TRANSACTION(int warehouseBuildingID, GameObjectType targetType, int targetUUID, TransactionType transactionType, mbEnums.ResourceType resource, int amount, DateTime date) { public boolean CREATE_TRANSACTION(int warehouseBuildingID, GameObjectType targetType, int targetUUID, TransactionType transactionType, mbEnums.ResourceType resource, int amount, Instant date) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_warehouse_transactions` (`warehouseUID`, `targetType`,`targetUID`, `type`,`resource`,`amount`,`date` ) VALUES (?,?,?,?,?,?,?)")) { PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_warehouse_transactions` (`warehouseUID`, `targetType`,`targetUID`, `type`,`resource`,`amount`,`date` ) VALUES (?,?,?,?,?,?,?)")) {
@@ -52,7 +51,7 @@ public class dbWarehouseHandler extends dbHandlerBase {
preparedStatement.setString(4, transactionType.name()); preparedStatement.setString(4, transactionType.name());
preparedStatement.setString(5, resource.name()); preparedStatement.setString(5, resource.name());
preparedStatement.setInt(6, amount); preparedStatement.setInt(6, amount);
preparedStatement.setTimestamp(7, new java.sql.Timestamp(date.getMillis())); preparedStatement.setTimestamp(7, new java.sql.Timestamp(date.toEpochMilli()));
return (preparedStatement.executeUpdate() > 0); return (preparedStatement.executeUpdate() > 0);
@@ -135,6 +134,7 @@ public class dbWarehouseHandler extends dbHandlerBase {
while (rs.next()) { while (rs.next()) {
int cityUID = rs.getInt("cityUUID"); int cityUID = rs.getInt("cityUUID");
JSONObject jsonObject = new JSONObject(rs.getString("warehouse"));
City city = City.getCity(cityUID); City city = City.getCity(cityUID);
if (city == null) { if (city == null) {
@@ -142,18 +142,12 @@ public class dbWarehouseHandler extends dbHandlerBase {
continue; continue;
} }
try { city.warehouse = new Warehouse(jsonObject);
city.warehouse = new Warehouse(new JSONObject(rs.getString("warehouse")));
} catch (JSONException e) {
Logger.error("Warehouse for city " + cityUID + " failed to load: " + e.getMessage());
continue;
}
city.warehouse.city = city; city.warehouse.city = city;
// Locate warehouse building // Locate warehouse building
for (Building building : city.parentZone.zoneBuildingSet) { for (Building building : city.parentZone.zoneBuildingSet) {
if (building.getBlueprint().getBuildingGroup().equals(mbEnums.BuildingGroup.WAREHOUSE) && building.getRank() != -1) { if (building.getBlueprint().getBuildingGroup().equals(mbEnums.BuildingGroup.WAREHOUSE)) {
city.warehouse.building = building; city.warehouse.building = building;
break; break;
} }
@@ -211,16 +205,8 @@ public class dbWarehouseHandler extends dbHandlerBase {
ResultSet rs = preparedStatement.executeQuery()) { ResultSet rs = preparedStatement.executeQuery()) {
while (rs.next()) { while (rs.next()) {
int workOrderID = rs.getInt("workorderID"); JSONObject jsonObject = new JSONObject(rs.getString("workorder"));
WorkOrder workOrder; WorkOrder workOrder = new WorkOrder(jsonObject);
try {
workOrder = new WorkOrder(new JSONObject(rs.getString("workorder")));
} catch (JSONException e) {
Logger.error("WorkOrder " + workOrderID + " failed to load: " + e.getMessage());
continue;
}
submitList.add(workOrder); submitList.add(workOrder);
} }
} catch (Exception e) { } catch (Exception e) {
+3 -3
View File
@@ -15,8 +15,8 @@ import engine.gameManager.DbManager;
import engine.mbEnums; import engine.mbEnums;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Item; import engine.objects.Item;
import engine.objects.ItemTemplate;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import engine.parsers.objects.CObjectTemplate;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
/** /**
@@ -38,7 +38,7 @@ public class CreateItemCmd extends AbstractDevCmd {
} }
int templateID = Integer.parseInt(words[0]); int templateID = Integer.parseInt(words[0]);
CObjectTemplate template = CObjectTemplate.lookup(templateID); ItemTemplate template = ItemTemplate.templates.get(templateID);
if (template == null) { if (template == null) {
ChatManager.chatSystemInfo(playerCharacter, "No such template found."); ChatManager.chatSystemInfo(playerCharacter, "No such template found.");
@@ -51,7 +51,7 @@ public class CreateItemCmd extends AbstractDevCmd {
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if (!playerCharacter.charItemManager.hasRoomInventory(template.getItemWt())) { if (!playerCharacter.charItemManager.hasRoomInventory(template.item_wt)) {
ChatManager.chatSystemInfo(playerCharacter, "You are encumbered!."); ChatManager.chatSystemInfo(playerCharacter, "You are encumbered!.");
break; break;
} }
-106
View File
@@ -1,106 +0,0 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ChatManager;
import engine.gameManager.DbManager;
import engine.mbEnums;
import engine.objects.AbstractGameObject;
import engine.objects.Building;
import engine.objects.City;
import engine.objects.PlayerCharacter;
import engine.objects.Warehouse;
import java.util.HashMap;
public class FillCmd extends AbstractDevCmd {
public FillCmd() {
super("fill");
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
Building building;
City city;
Warehouse warehouse;
int amount = Integer.MAX_VALUE;
HashMap<mbEnums.ResourceType, Integer> oldResources;
if (words.length > 1) {
this.sendUsage(pc);
return;
}
if (words.length == 1 && !words[0].isEmpty()) {
try {
amount = Integer.parseInt(words[0]);
} catch (NumberFormatException e) {
throwbackError(pc, "Amount must be a number, " + words[0] + " is invalid");
return;
}
if (amount < 0) {
throwbackError(pc, "Amount must be 0 or more");
return;
}
}
if (target == null || target.getObjectType() != mbEnums.GameObjectType.Building) {
throwbackError(pc, "Select a warehouse");
return;
}
building = (Building) target;
if (building.getBlueprint() == null || building.getBlueprint().getBuildingGroup() != mbEnums.BuildingGroup.WAREHOUSE) {
throwbackError(pc, "Selected building is not a warehouse");
return;
}
city = building.getCity();
if (city == null || city.warehouse == null || city.warehouse.building == null
|| city.warehouse.building.getObjectUUID() != building.getObjectUUID()) {
throwbackError(pc, "Selected warehouse is not the active warehouse of a city");
return;
}
warehouse = city.warehouse;
oldResources = new HashMap<>(warehouse.resources);
for (mbEnums.ResourceType resourceType : mbEnums.ResourceType.values())
warehouse.resources.put(resourceType, Math.min(amount, resourceType.deposit_limit));
if (!DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse)) {
warehouse.resources.putAll(oldResources);
throwbackError(pc, "Failed to update the warehouse in the database");
return;
}
ChatManager.chatSayInfo(pc, "Filled the " + city.getCityName() + " warehouse"
+ (amount == Integer.MAX_VALUE ? " to each deposit limit" : " with " + amount + " of each resource (capped at the deposit limit)"));
}
@Override
protected String _getHelpString() {
return "Sets every resource in the selected warehouse";
}
@Override
protected String _getUsageString() {
return "' ./fill [amount]' with a warehouse selected (no amount fills each resource to its deposit limit)";
}
}
+5 -6
View File
@@ -18,7 +18,6 @@ import engine.mbEnums.BuildingGroup;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.mbEnums.TargetColor; import engine.mbEnums.TargetColor;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import engine.util.StringUtils; import engine.util.StringUtils;
import java.text.DecimalFormat; import java.text.DecimalFormat;
@@ -508,17 +507,17 @@ public class InfoCmd extends AbstractDevCmd {
case Item: //intentional passthrough case Item: //intentional passthrough
case MobLoot: case MobLoot:
Item item = (Item) target; Item item = (Item) target;
CObjectTemplate template = CObjectTemplate.lookup(item.templateID); ItemTemplate template = ItemTemplate.templates.get(item.templateID);
output += StringUtils.addWS("Template: " + template.getTemplateId(), 20); output += StringUtils.addWS("Template: " + template.template_id, 20);
output += "Weight: " + template.getItemWt(); output += "Weight: " + template.item_wt;
output += newline; output += newline;
DecimalFormat df = new DecimalFormat("###,###,###,###,##0"); DecimalFormat df = new DecimalFormat("###,###,###,###,##0");
output += StringUtils.addWS("Qty: " output += StringUtils.addWS("Qty: "
+ df.format(item.getNumOfItems()), 20); + df.format(item.getNumOfItems()), 20);
output += "Charges: " + (byte) item.chargesRemaining output += "Charges: " + (byte) item.chargesRemaining
+ '/' + item.template.getItemInitialCharges(); + '/' + item.template.item_initial_charges;
output += newline; output += newline;
output += "Name: " + template.getItemBaseName(); output += "Name: " + template.item_base_name;
output += newline; output += newline;
output += item.getContainerInfo(); output += item.getContainerInfo();
+9 -16
View File
@@ -11,11 +11,9 @@ package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.mbEnums.ItemContainerType;
import engine.mbEnums.ItemType; import engine.mbEnums.ItemType;
import engine.mbEnums.OwnerType; import engine.mbEnums.OwnerType;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
/** /**
@@ -61,17 +59,18 @@ public class MakeItemCmd extends AbstractDevCmd {
} }
int templateID; int templateID;
CObjectTemplate template; ItemTemplate template;
try { try {
templateID = Integer.parseInt(words[0]); templateID = Integer.parseInt(words[0]);
template = CObjectTemplate.lookup(templateID); template = ItemTemplate.templates.get(words[0].toLowerCase());
if (template == null) { if (template == null) {
throwbackError(pc, "No item template with id " + words[0]); throwbackError(pc, "Supplied type " + words[0]
+ " failed to parse to an Integer");
return; return;
} }
if (template.getItemType() == ItemType.GOLD) { if (template.item_type == ItemType.GOLD) {
this.throwbackInfo(pc, "use /addgold to add gold."); this.throwbackInfo(pc, "use /addgold to add gold.");
return; return;
} }
@@ -133,7 +132,7 @@ public class MakeItemCmd extends AbstractDevCmd {
return; return;
} }
} }
template = CObjectTemplate.lookup(templateID); template = ItemTemplate.templates.get(templateID);
if (template == null) { if (template == null) {
throwbackError(pc, "Unable to find template " + templateID); throwbackError(pc, "Unable to find template " + templateID);
@@ -141,8 +140,8 @@ public class MakeItemCmd extends AbstractDevCmd {
} }
if ((numItems > 1) if ((numItems > 1)
&& (template.getItemType().equals(ItemType.RESOURCE) == false) && (template.item_type.equals(ItemType.RESOURCE) == false)
&& (template.getItemType().equals(ItemType.OFFERING)) == false) && (template.item_type.equals(ItemType.OFFERING)) == false)
numItems = 1; numItems = 1;
CharacterItemManager cim = pc.charItemManager; CharacterItemManager cim = pc.charItemManager;
@@ -156,7 +155,7 @@ public class MakeItemCmd extends AbstractDevCmd {
for (int i = 0; i < quantity; i++) { for (int i = 0; i < quantity; i++) {
int weight = template.getItemWt(); int weight = template.item_wt;
if (!cim.hasRoomInventory(weight)) { if (!cim.hasRoomInventory(weight)) {
throwbackError(pc, "Not enough room in inventory for any more of this item. " + i + " produced."); throwbackError(pc, "Not enough room in inventory for any more of this item. " + i + " produced.");
@@ -170,7 +169,6 @@ public class MakeItemCmd extends AbstractDevCmd {
Item item = new Item(templateID); Item item = new Item(templateID);
item.ownerID = pc.getObjectUUID(); item.ownerID = pc.getObjectUUID();
item.ownerType = OwnerType.PlayerCharacter; item.ownerType = OwnerType.PlayerCharacter;
item.containerType = ItemContainerType.INVENTORY;
if (numItems > 1) if (numItems > 1)
item.setNumOfItems(numItems); item.setNumOfItems(numItems);
@@ -182,11 +180,6 @@ public class MakeItemCmd extends AbstractDevCmd {
return; return;
} }
if (item == null) {
throwbackError(pc, "DB error 2: Unable to create item " + templateID + ".");
return;
}
//create prefix //create prefix
if (!prefix.isEmpty()) if (!prefix.isEmpty())
item.addPermanentEnchantmentForDev(prefix, 0); item.addPermanentEnchantmentForDev(prefix, 0);
+2 -3
View File
@@ -11,7 +11,6 @@ package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import java.util.ArrayList; import java.util.ArrayList;
@@ -53,8 +52,8 @@ public class PrintBankCmd extends AbstractDevCmd {
throwbackInfo(pc, "Bank for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')'); throwbackInfo(pc, "Bank for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
for (Item item : list) { for (Item item : list) {
CObjectTemplate template = CObjectTemplate.lookup(item.templateID); ItemTemplate template = ItemTemplate.templates.get(item.templateID);
throwbackInfo(pc, " " + template.getItemBaseName() + ", count: " + item.getNumOfItems()); throwbackInfo(pc, " " + template.item_base_name + ", count: " + item.getNumOfItems());
} }
Item gold = cim.getGoldBank(); Item gold = cim.getGoldBank();
+2 -3
View File
@@ -13,7 +13,6 @@ import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import engine.powers.effectmodifiers.AbstractEffectModifier; import engine.powers.effectmodifiers.AbstractEffectModifier;
public class PrintBonusesCmd extends AbstractDevCmd { public class PrintBonusesCmd extends AbstractDevCmd {
@@ -34,8 +33,8 @@ public class PrintBonusesCmd extends AbstractDevCmd {
if (target instanceof Item) { if (target instanceof Item) {
type = "Item"; type = "Item";
tar = (Item) target; tar = (Item) target;
CObjectTemplate template = CObjectTemplate.lookup(((Item) tar).templateID); ItemTemplate template = ItemTemplate.templates.get(((Item) tar).templateID);
name = template.getItemBaseName(); name = template.item_base_name;
} else if (target instanceof AbstractCharacter) { } else if (target instanceof AbstractCharacter) {
tar = (AbstractCharacter) target; tar = (AbstractCharacter) target;
name = ((AbstractCharacter) tar).getFirstName(); name = ((AbstractCharacter) tar).getFirstName();
+10 -48
View File
@@ -10,15 +10,9 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.mbEnums.GameObjectType;
import engine.objects.AbstractCharacter; import engine.objects.AbstractCharacter;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Effect;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import engine.powers.EffectsBase;
import engine.powers.PowersBase;
import java.util.Map;
/** /**
* *
@@ -36,60 +30,28 @@ public class PrintEffectsCmd extends AbstractDevCmd {
AbstractGameObject target) { AbstractGameObject target) {
AbstractCharacter tar; AbstractCharacter tar;
StringBuilder output;
String newline = "\r\n ";
Effect effect;
EffectsBase effectsBase;
PowersBase power;
if (target == null) if (target != null && target instanceof AbstractCharacter) {
return; tar = (AbstractCharacter) target;
if (target.getObjectType() != GameObjectType.PlayerCharacter && target.getObjectType() != GameObjectType.Mob String newline = "\r\n ";
&& target.getObjectType() != GameObjectType.NPC) String output = "Effects For Character: " + tar.getName() + newline;
return;
tar = (AbstractCharacter) target; for (String effect : tar.effects.keySet()) {
output = new StringBuilder("Effects for " + tar.getName() + " (" + tar.effects.size() + "):" + newline); output += effect + newline;
}
// Keys are the effect UUID for mobbase/rune effects, or the stack type (e.g. PetBuff) for power effects throwbackInfo(pc, output);
for (Map.Entry<String, Effect> entry : tar.effects.entrySet()) {
effect = entry.getValue();
effectsBase = effect.getEffectsBase();
power = effect.getPower();
output.append(entry.getKey()).append(": ");
if (effectsBase != null)
output.append(effectsBase.getIDString()).append(" '").append(effectsBase.getName()).append("'");
else
output.append("no EffectsBase");
output.append(" rank ").append(effect.getTrains());
if (effect.isStatic())
output.append(", static");
else
output.append(", ").append((int) effect.getDuration()).append("s left");
if (power != null)
output.append(", from ").append(power.getIDString()).append(" '").append(power.getName()).append("'");
output.append(newline);
} }
throwbackInfo(pc, output.toString());
} }
@Override @Override
protected String _getHelpString() { protected String _getHelpString() {
return "Lists the target's effects: key, effect id and name, rank, time left and source power"; return "Returns the player's current stats";
} }
@Override @Override
protected String _getUsageString() { protected String _getUsageString() {
return "' /printeffects'"; return "' /printstats'";
} }
} }
+3 -3
View File
@@ -66,7 +66,7 @@ public class PrintEquipCmd extends AbstractDevCmd {
throwbackInfo(pc, "Equip for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')'); throwbackInfo(pc, "Equip for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
for (mbEnums.EquipSlotType slot : tarMob.charItemManager.equipped.keySet()) { for (mbEnums.EquipSlotType slot : tarMob.charItemManager.equipped.keySet()) {
Item equip = tarMob.charItemManager.equipped.get(slot); Item equip = tarMob.charItemManager.equipped.get(slot);
throwbackInfo(pc, equip.templateID + " : " + equip.template.getItemBaseName() + ", slot: " + slot); throwbackInfo(pc, equip.templateID + " : " + equip.template.item_base_name + ", slot: " + slot);
} }
return; return;
} }
@@ -76,7 +76,7 @@ public class PrintEquipCmd extends AbstractDevCmd {
throwbackInfo(pc, "Equip for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')'); throwbackInfo(pc, "Equip for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
for (mbEnums.EquipSlotType slot : tarMob.charItemManager.equipped.keySet()) { for (mbEnums.EquipSlotType slot : tarMob.charItemManager.equipped.keySet()) {
Item equip = tarMob.charItemManager.equipped.get(slot); Item equip = tarMob.charItemManager.equipped.get(slot);
throwbackInfo(pc, equip.templateID + " : " + equip.template.getItemBaseName() + ", slot: " + slot); throwbackInfo(pc, equip.templateID + " : " + equip.template.item_base_name + ", slot: " + slot);
} }
return; return;
} }
@@ -87,7 +87,7 @@ public class PrintEquipCmd extends AbstractDevCmd {
for (mbEnums.EquipSlotType slot : list.keySet()) { for (mbEnums.EquipSlotType slot : list.keySet()) {
Item item = list.get(slot); Item item = list.get(slot);
throwbackInfo(pc, " " + item.template.getItemBaseName() + ", slot: " + slot); throwbackInfo(pc, " " + item.template.item_base_name + ", slot: " + slot);
} }
} }
@@ -12,7 +12,6 @@ package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.mbEnums.ItemType; import engine.mbEnums.ItemType;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
@@ -76,18 +75,18 @@ public class PrintInventoryCmd extends AbstractDevCmd {
int goldCount = 0; int goldCount = 0;
for (Item item : inventory) { for (Item item : inventory) {
CObjectTemplate template = CObjectTemplate.lookup(item.templateID); ItemTemplate template = ItemTemplate.templates.get(item.templateID);
if (item.template.getItemType().equals(ItemType.GOLD) == false) { if (item.template.item_type.equals(ItemType.GOLD) == false) {
String chargeInfo = ""; String chargeInfo = "";
int chargeMax = template.getItemInitialCharges(); int chargeMax = template.item_initial_charges;
if (chargeMax > 0) { if (chargeMax > 0) {
int charges = item.chargesRemaining; int charges = item.chargesRemaining;
chargeInfo = " charges: " + charges + '/' + chargeMax; chargeInfo = " charges: " + charges + '/' + chargeMax;
} }
throwbackInfo(pc, " " + template.getItemBaseName() + ", count: " + item.getNumOfItems() + chargeInfo); throwbackInfo(pc, " " + template.item_base_name + ", count: " + item.getNumOfItems() + chargeInfo);
} else } else
goldCount += item.getNumOfItems(); goldCount += item.getNumOfItems();
} }
+2 -3
View File
@@ -11,7 +11,6 @@ package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import java.util.ArrayList; import java.util.ArrayList;
@@ -51,8 +50,8 @@ public class PrintVaultCmd extends AbstractDevCmd {
ArrayList<Item> list = cim.getVault(); ArrayList<Item> list = cim.getVault();
throwbackInfo(pc, "Vault for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')'); throwbackInfo(pc, "Vault for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
for (Item item : list) { for (Item item : list) {
CObjectTemplate template = CObjectTemplate.lookup(item.templateID); ItemTemplate template = ItemTemplate.templates.get(item.templateID);
throwbackInfo(pc, " " + template.getItemBaseName() + ", count: " + item.getNumOfItems()); throwbackInfo(pc, " " + template.item_base_name + ", count: " + item.getNumOfItems());
} }
Item gold = cim.getGoldVault(); Item gold = cim.getGoldVault();
if (gold != null) if (gold != null)
+3 -4
View File
@@ -5,7 +5,6 @@ import engine.gameManager.LootManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.loot.BootySetEntry; import engine.loot.BootySetEntry;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@@ -35,10 +34,10 @@ public class SimulateBootyCmd extends AbstractDevCmd {
if (mob.bootySet != 0) { if (mob.bootySet != 0) {
for (BootySetEntry entry : LootManager._bootySetMap.get(mob.bootySet)) { for (BootySetEntry entry : LootManager._bootySetMap.get(mob.bootySet)) {
CObjectTemplate template = CObjectTemplate.lookup(entry.templateID); ItemTemplate template = ItemTemplate.templates.get(entry.templateID);
if (template != null) if (template != null)
output += "[" + entry.bootyType + "] " + template.getItemBaseName() + " [Chance] " + entry.dropChance + newline; output += "[" + entry.bootyType + "] " + template.item_base_name + " [Chance] " + entry.dropChance + newline;
} }
} }
@@ -58,7 +57,7 @@ public class SimulateBootyCmd extends AbstractDevCmd {
try { try {
mob.loadInventory(); mob.loadInventory();
for (Item lootItem : mob.charItemManager.getInventory()) { for (Item lootItem : mob.charItemManager.getInventory()) {
switch (lootItem.template.getItemType()) { switch (lootItem.template.item_type) {
case EMPLOYMENTCONTRACT: //CONTRACT case EMPLOYMENTCONTRACT: //CONTRACT
Contracts.add(lootItem); Contracts.add(lootItem);
break; break;
+4 -3
View File
@@ -118,17 +118,18 @@ public class aiInfoCmd extends AbstractDevCmd {
ArrayList<RunePowerEntry> powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID())); ArrayList<RunePowerEntry> powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
// Player guards also cast their captain contract's powers, irrespective of the mobbase used. // Additional powers may come from the contract ID. This is to support
// powers for player guards irrespective of the mobbase used.
if (mob.isPlayerGuard()) { if (mob.isPlayerGuard()) {
ArrayList<RunePowerEntry> contractEntries = new ArrayList<>(); ArrayList<RunePowerEntry> contractEntries = new ArrayList<>();
if (mob.contract != null) if (mob.contract != null)
contractEntries = new ArrayList<>(mbEnums.MinionType.getCaptainPowers(mob.contractUUID)); contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.contractUUID));
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION)) if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION))
contractEntries = new ArrayList<>(mbEnums.MinionType.getCaptainPowers(mob.guardCaptain.contractUUID)); contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.guardCaptain.contractUUID));
powerEntries.addAll(contractEntries); powerEntries.addAll(contractEntries);
+11 -15
View File
@@ -22,7 +22,6 @@ import engine.mbEnums.BuildingGroup;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.ErrorPopupMsg;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -200,31 +199,31 @@ public enum BuildingManager {
return false; return false;
} }
CObjectTemplate template = CObjectTemplate.lookup(1705032); // Elan Stone ItemTemplate template = ItemTemplate.templates.get(1705032); // Elan Stone
if (!player.charItemManager.hasRoomInventory(template.getItemWt())) if (!player.charItemManager.hasRoomInventory(template.item_wt))
return false; return false;
if (!ItemManager.MakeItemForPlayer(template.getTemplateId(), player, amount)) if (!ItemManager.MakeItemForPlayer(template.template_id, player, amount))
return false; return false;
shrine.setFavors(0); shrine.setFavors(0);
break; break;
case WAREHOUSE: case WAREHOUSE:
Warehouse warehouse = Warehouse.destroyedWarehouses.get(building.getObjectUUID()); City city = building.getCity();
if (city == null)
return true;
Warehouse warehouse = city.warehouse;
if (warehouse == null) if (warehouse == null)
return false; return false;
for (mbEnums.ResourceType resourceType : EnumSet.allOf(mbEnums.ResourceType.class)) { for (mbEnums.ResourceType resourceType : EnumSet.allOf(mbEnums.ResourceType.class)) {
CObjectTemplate resourceTemplate = CObjectTemplate.lookup(resourceType.templateID); if (!player.charItemManager.hasRoomInventory(resourceType.template.item_wt)) {
if (resourceTemplate == null)
continue;
if (!player.charItemManager.hasRoomInventory(resourceTemplate.getItemWt())) {
ChatManager.chatSystemInfo(player, "You can not carry any more of that item."); ChatManager.chatSystemInfo(player, "You can not carry any more of that item.");
return false; return false;
} }
@@ -242,9 +241,6 @@ public enum BuildingManager {
} }
} }
if (Warehouse.isEmpty(warehouse))
Warehouse.destroyedWarehouses.remove(building.getObjectUUID());
break; break;
} }
@@ -278,7 +274,7 @@ public enum BuildingManager {
if (building == null) if (building == null)
return; return;
if (!DbManager.BuildingQueries.updateBuildingUpgradeTime(upgradeDateTime, building, rankCost)) { if (!DbManager.BuildingQueries.updateBuildingUpgradeTime(upgradeDateTime.atZone(ZoneId.systemDefault()).toInstant(), building, rankCost)) {
Logger.error("Failed to set upgradeTime for building " + building.getObjectUUID()); Logger.error("Failed to set upgradeTime for building " + building.getObjectUUID());
return; return;
} }
+3 -4
View File
@@ -22,7 +22,6 @@ import engine.net.client.ClientConnection;
import engine.net.client.handlers.ClientAdminCommandMsgHandler; import engine.net.client.handlers.ClientAdminCommandMsgHandler;
import engine.net.client.msg.chat.*; import engine.net.client.msg.chat.*;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import engine.server.world.WorldServer; import engine.server.world.WorldServer;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -536,12 +535,12 @@ public enum ChatManager {
if (item != null) //Steal if (item != null) //Steal
if (success) { if (success) {
String name = ""; String name = "";
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) if (item.template.item_type.equals(mbEnums.ItemType.GOLD))
name = amount + " gold "; name = amount + " gold ";
else { else {
String vowels = "aeiou"; String vowels = "aeiou";
CObjectTemplate template = CObjectTemplate.lookup(item.templateID); ItemTemplate template = ItemTemplate.templates.get(item.templateID);
String iName = template.getItemBaseName(); String iName = template.item_base_name;
if (iName.length() > 0) if (iName.length() > 0)
if (vowels.indexOf(iName.substring(0, 1).toLowerCase()) >= 0) if (vowels.indexOf(iName.substring(0, 1).toLowerCase()) >= 0)
name = "an " + iName + ' '; name = "an " + iName + ' ';
+50 -142
View File
@@ -14,12 +14,9 @@ import engine.jobs.AttackJob;
import engine.jobs.DeferredPowerJob; import engine.jobs.DeferredPowerJob;
import engine.mbEnums; import engine.mbEnums;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.PowerProjectileMsg;
import engine.net.client.msg.TargetedActionMsg; import engine.net.client.msg.TargetedActionMsg;
import engine.net.client.msg.UpdateStateMsg; import engine.net.client.msg.UpdateStateMsg;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import engine.parsers.objects.RuneTemplate;
import engine.powers.DamageShield; import engine.powers.DamageShield;
import engine.powers.effectmodifiers.AbstractEffectModifier; import engine.powers.effectmodifiers.AbstractEffectModifier;
import engine.powers.effectmodifiers.WeaponProcEffectModifier; import engine.powers.effectmodifiers.WeaponProcEffectModifier;
@@ -28,7 +25,6 @@ import org.pmw.tinylog.Logger;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@@ -95,25 +91,25 @@ public enum CombatManager {
return; return;
} }
if (mainWeapon == null && offWeapon != null && !offWeapon.template.getItemSkillUsed().equals("Block")) { if (mainWeapon == null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) {
//swing left hand only //swing left hand only
processAttack(attacker, target, mbEnums.EquipSlotType.LHELD); processAttack(attacker, target, mbEnums.EquipSlotType.LHELD);
return; return;
} }
if (mainWeapon == null && offWeapon != null && offWeapon.template.getItemSkillUsed().equals("Block")) { if (mainWeapon == null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) {
//no weapon equipped with a shield, punch with one hand //no weapon equipped with a shield, punch with one hand
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
return; return;
} }
if (mainWeapon != null && offWeapon != null && offWeapon.template.getItemSkillUsed().equals("Block")) { if (mainWeapon != null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) {
//one weapon equipped with a shield, swing with one hand //one weapon equipped with a shield, swing with one hand
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
return; return;
} }
if (mainWeapon != null && offWeapon != null && !offWeapon.template.getItemSkillUsed().equals("Block")) { if (mainWeapon != null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) {
//two weapons equipped, swing both hands //two weapons equipped, swing both hands
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter))
@@ -149,20 +145,12 @@ public enum CombatManager {
if (bonus != null) if (bonus != null)
rangeMod += bonus.getFloatPercentAll(mbEnums.ModType.WeaponRange, mbEnums.SourceType.None); rangeMod += bonus.getFloatPercentAll(mbEnums.ModType.WeaponRange, mbEnums.SourceType.None);
attackRange += engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range * rangeMod; attackRange += weapon.template.item_weapon_max_range * rangeMod;
} else if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) {
//unarmed mob, add the natural attack range from its rune (0 for most melee mobs)
if (bonus != null)
rangeMod += bonus.getFloatPercentAll(mbEnums.ModType.WeaponRange, mbEnums.SourceType.None);
attackRange += getNaturalAttackRange(attacker, slot) * rangeMod;
} }
if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob))
if (((Mob) attacker).isSiege()) if (((Mob) attacker).isSiege())
attackRange = getSiegeRange((Mob) attacker); attackRange = 300;
float distanceSquared = attacker.loc.distanceSquared(target.loc); float distanceSquared = attacker.loc.distanceSquared(target.loc);
@@ -214,7 +202,7 @@ public enum CombatManager {
if (weapon != null) { if (weapon != null) {
float wepSpeed = (int) (engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed); float wepSpeed = (int) (weapon.template.item_weapon_wepspeed);
if (weapon.getBonusPercent(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None) != 0f) //add weapon speed bonus if (weapon.getBonusPercent(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None) != 0f) //add weapon speed bonus
wepSpeed *= (1 + weapon.getBonus(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None)); wepSpeed *= (1 + weapon.getBonus(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None));
@@ -226,22 +214,6 @@ public enum CombatManager {
wepSpeed = 10; //Old was 10, but it can be reached lower with legit buffs,effects. wepSpeed = 10; //Old was 10, but it can be reached lower with legit buffs,effects.
delay = (long)wepSpeed * 100L; delay = (long)wepSpeed * 100L;
} else {
//unarmed, use the natural attack speed from the mob or race rune
float naturalSpeed = getNaturalAttackSpeed(attacker, slot);
if (naturalSpeed > 0) {
if (attacker.getBonuses() != null && attacker.getBonuses().getFloatPercentAll(mbEnums.ModType.AttackDelay, mbEnums.SourceType.None) != 0f) //add effects speed bonus
naturalSpeed *= (1 + attacker.getBonuses().getFloatPercentAll(mbEnums.ModType.AttackDelay, mbEnums.SourceType.None));
if (naturalSpeed < 10)
naturalSpeed = 10;
delay = (long) naturalSpeed * 100L;
}
} }
if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob))
@@ -260,8 +232,7 @@ public enum CombatManager {
//handle retaliate //handle retaliate
//siege engines only retaliate on damage, see AbstractCharacter.modifyHealth if (AbstractCharacter.IsAbstractCharacter(target)) {
if (AbstractCharacter.IsAbstractCharacter(target) && !(target.getObjectType().equals(mbEnums.GameObjectType.Mob) && ((Mob) target).isSiege())) {
if (((AbstractCharacter) target).combatTarget == null || !((AbstractCharacter) target).combatTarget.isAlive()) { if (((AbstractCharacter) target).combatTarget == null || !((AbstractCharacter) target).combatTarget.isAlive()) {
((AbstractCharacter) target).combatTarget = attacker; ((AbstractCharacter) target).combatTarget = attacker;
if (target.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && ((AbstractCharacter) target).isCombat()) if (target.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && ((AbstractCharacter) target).isCombat())
@@ -273,13 +244,13 @@ public enum CombatManager {
if (weapon != null && !attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) { if (weapon != null && !attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) {
//check if Out of Stamina //check if Out of Stamina
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) { if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) {
if (attacker.getStamina() < (weapon.template.getItemWt() / 3f)) { if (attacker.getStamina() < (weapon.template.item_wt / 3f)) {
//set auto attack job //set auto attack job
setAutoAttackJob(attacker, slot, delay); setAutoAttackJob(attacker, slot, delay);
return; return;
} }
} }
float stam = weapon.template.getItemWt() / 3f; float stam = weapon.template.item_wt / 3f;
stam = (stam < 1) ? 1 : stam; stam = (stam < 1) ? 1 : stam;
attacker.modifyStamina(-(stam), attacker, true); attacker.modifyStamina(-(stam), attacker, true);
} else } else
@@ -348,7 +319,7 @@ public enum CombatManager {
DispatchManager.sendToAllInRange(attacker, msg); DispatchManager.sendToAllInRange(attacker, msg);
//we need to send the animation even if the attacker misses //we need to send the animation even if the attacker misses
TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon == null ? null : weapon.template, null, slot)); TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template, null, slot));
DispatchManager.sendToAllInRange(target, cmm); DispatchManager.sendToAllInRange(target, cmm);
//set auto attack job //set auto attack job
@@ -388,7 +359,7 @@ public enum CombatManager {
DispatchManager.dispatchMsgToInterestArea(target, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(target, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
//we need to send the animation even if the attacker misses //we need to send the animation even if the attacker misses
TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon == null ? null : weapon.template, null, slot)); TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template, null, slot));
DispatchManager.sendToAllInRange(target, cmm); DispatchManager.sendToAllInRange(target, cmm);
//set auto attack job //set auto attack job
setAutoAttackJob(attacker, slot, delay); setAutoAttackJob(attacker, slot, delay);
@@ -419,7 +390,7 @@ public enum CombatManager {
if (((Mob) attacker).isSiege()) if (((Mob) attacker).isSiege())
damageType = mbEnums.DamageType.SIEGE; damageType = mbEnums.DamageType.SIEGE;
} else { } else {
damageType = engine.parsers.objects.ItemTemplate.getWeapon(attacker.charItemManager.getEquipped().get(slot).templateID).weapon_damage.get(0).damage_type; damageType = (mbEnums.DamageType) attacker.charItemManager.getEquipped().get(slot).template.item_weapon_damage.keySet().toArray()[0];
} }
//get resists //get resists
@@ -476,7 +447,7 @@ public enum CombatManager {
if (resists.immuneTo(damageType)) { if (resists.immuneTo(damageType)) {
//set auto attack job //set auto attack job
//we need to send the animation even if the attacker misses //we need to send the animation even if the attacker misses
TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon == null ? null : weapon.template, null, slot)); TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template, null, slot));
DispatchManager.sendToAllInRange(target, cmm); DispatchManager.sendToAllInRange(target, cmm);
setAutoAttackJob(attacker, slot, delay); setAutoAttackJob(attacker, slot, delay);
return; return;
@@ -508,15 +479,6 @@ public enum CombatManager {
} }
TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) damage, attackAnim); TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) damage, attackAnim);
DispatchManager.sendToAllInRange(target, cmm); DispatchManager.sendToAllInRange(target, cmm);
//siege projectile is sent once per hit, not per AI pulse
if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob) && ((Mob) attacker).isSiege()
&& target.getObjectType().equals(mbEnums.GameObjectType.Building)) {
PowerProjectileMsg ppm = new PowerProjectileMsg(attacker, target);
ppm.setRange(50);
DispatchManager.dispatchMsgToInterestArea(attacker, ppm, mbEnums.DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
}
} }
} }
@@ -580,14 +542,13 @@ public enum CombatManager {
target.setCombatTarget(attacker); target.setCombatTarget(attacker);
} }
public static int getSwingAnimation(CObjectTemplate wb, DeferredPowerJob dpj, mbEnums.EquipSlotType slot) { public static int getSwingAnimation(ItemTemplate wb, DeferredPowerJob dpj, mbEnums.EquipSlotType slot) {
//No weapon, return default animation //No weapon, return default animation
if (wb == null) if (wb == null)
return 75; return 75;
int token; int token;
engine.parsers.objects.ItemTemplate.Weapon weapon = engine.parsers.objects.ItemTemplate.getWeapon(wb.getTemplateId());
if (dpj != null) { if (dpj != null) {
@@ -598,30 +559,47 @@ public enum CombatManager {
} }
//Item has no equipment slots and should not try to return an animation, return default instead //Item has no equipment slots and should not try to return an animation, return default instead
if (wb.getItemEqSlotsOr().isEmpty()) { if (wb.item_eq_slots_or == null || wb.item_eq_slots_or.isEmpty()) {
return 75; return 75;
} }
//declare variables //declare variables
mbEnums.EquipSlotType hand; int anim;
ArrayList<int[]> anims; int random;
//Item can only be equipped in one slot, use the animations for that slot //Item can only be equipped in one slot, return animation for that slot
if (wb.getItemEqSlotsOr().size() == 1) if (wb.item_eq_slots_or.size() == 1) {
hand = wb.getItemEqSlotsOr().iterator().next(); if (wb.item_eq_slots_or.iterator().next().equals(mbEnums.EquipSlotType.RHELD)) {
else anim = wb.weapon_attack_anim_right.get(0)[0];
hand = slot; if (dpj != null) {
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_right.size());
anim = wb.weapon_attack_anim_right.get(random)[0];
}
} else {
anim = wb.weapon_attack_anim_left.get(0)[0];
if (dpj != null) {
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_left.size());
anim = wb.weapon_attack_anim_left.get(random)[0];
}
}
return anim;
}
anims = hand.equals(mbEnums.EquipSlotType.RHELD) ? weapon.weapon_attack_anim_right : weapon.weapon_attack_anim_left; //Item can be equipped in either hand, and should have animation sets for each hand
if (slot.equals(mbEnums.EquipSlotType.RHELD)) {
// Many cache weapons have no swing anims; GUESS: the client falls back to the default too anim = wb.weapon_attack_anim_right.get(0)[0];
if (anims.isEmpty()) if (dpj != null) {
return 75; random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_right.size());
anim = wb.weapon_attack_anim_right.get(random)[0];
if (dpj != null) }
return anims.get(ThreadLocalRandom.current().nextInt(anims.size()))[0]; } else {
anim = wb.weapon_attack_anim_left.get(0)[0];
return anims.get(0)[0]; if (dpj != null) {
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_left.size());
anim = wb.weapon_attack_anim_left.get(random)[0];
}
}
return anim;
} }
public static int getPassiveAnimation(mbEnums.PassiveType passiveType) { public static int getPassiveAnimation(mbEnums.PassiveType passiveType) {
@@ -658,76 +636,6 @@ public enum CombatManager {
} }
public static float getNaturalAttackSpeed(AbstractCharacter attacker, mbEnums.EquipSlotType slot) {
// Returns the rune natural attack speed (x100 ms) for this hand, or 0 if the rune has none.
float[] attack = getNaturalAttack(attacker, slot);
if (attack == null || attack.length < 1)
return 0;
return attack[0];
}
public static float getNaturalAttackRange(AbstractCharacter attacker, mbEnums.EquipSlotType slot) {
// Returns the rune natural attack range for this hand, or 0 if the rune has none.
float[] attack = getNaturalAttack(attacker, slot);
if (attack == null || attack.length < 2)
return 0;
return attack[1];
}
public static float getSiegeRange(Mob siegeEngine) {
// Siege engines use the range from their rune natural attack (350 for all three), 300 if the rune has none.
float range = getNaturalAttackRange(siegeEngine, mbEnums.EquipSlotType.RHELD);
if (range <= 0)
return 300;
return range;
}
public static float[] getNaturalAttack(AbstractCharacter attacker, mbEnums.EquipSlotType slot) {
// Returns the rune natural attack entry for this hand, or null if the rune has none.
// Mobs use their mobbase rune, players use their race rune.
int runeID;
RuneTemplate rune;
int hand = slot.equals(mbEnums.EquipSlotType.LHELD) ? 2 : 1;
switch (attacker.getObjectType()) {
case Mob:
runeID = ((Mob) attacker).loadID;
break;
case PlayerCharacter:
runeID = ((PlayerCharacter) attacker).getRaceID();
break;
default:
return null;
}
rune = RuneTemplate._runes.get(runeID);
if (rune == null || rune.rune_naturalattacks.isEmpty())
return null;
for (float[] attack : rune.rune_naturalattacks)
if (attack.length > 3 && (int) attack[3] == hand)
return attack;
// No entry for this hand, fall back to the first natural attack
return rune.rune_naturalattacks.get(0);
}
public static int calculatePetDamage(AbstractCharacter agent) { public static int calculatePetDamage(AbstractCharacter agent) {
//damage calc for pet //damage calc for pet
float range; float range;
+8 -1
View File
@@ -75,7 +75,6 @@ public enum ConfigManager {
// Mobile AI modifiers // Mobile AI modifiers
MB_AI_CAST_FREQUENCY, MB_AI_CAST_FREQUENCY,
MB_AI_AGGRO_RANGE, MB_AI_AGGRO_RANGE,
MB_MINION_SPAWN_TIME,
//drop rates //drop rates
MB_NORMAL_EXP_RATE, MB_NORMAL_EXP_RATE,
@@ -166,6 +165,14 @@ public enum ConfigManager {
regex.put(MB_LOGIN_FNAME_REGEX, Pattern.compile(MB_LOGIN_FNAME_REGEX.getValue())); regex.put(MB_LOGIN_FNAME_REGEX, Pattern.compile(MB_LOGIN_FNAME_REGEX.getValue()));
Logger.info("Loading WPAK data");
// *** Needs powermanager collection
// defined before activation.
// EffectsParser.parseWpakFile();
// PowersParser.parseWpakFile();
// PowerActionParser.parseWpakFile();
return true; return true;
} }
+6
View File
@@ -44,8 +44,10 @@ public enum DbManager {
// Omg refactor this out, somebody! // Omg refactor this out, somebody!
public static final dbCSSessionHandler CSSessionQueries = new dbCSSessionHandler(); public static final dbCSSessionHandler CSSessionQueries = new dbCSSessionHandler();
public static final dbEnchantmentHandler EnchantmentQueries = new dbEnchantmentHandler(); public static final dbEnchantmentHandler EnchantmentQueries = new dbEnchantmentHandler();
public static final dbEffectsResourceCostHandler EffectsResourceCostsQueries = new dbEffectsResourceCostHandler();
public static final dbGuildHandler GuildQueries = new dbGuildHandler(); public static final dbGuildHandler GuildQueries = new dbGuildHandler();
public static final dbItemHandler ItemQueries = new dbItemHandler(); public static final dbItemHandler ItemQueries = new dbItemHandler();
public static final dbKitHandler KitQueries = new dbKitHandler();
public static final dbLootHandler LootQueries = new dbLootHandler(); public static final dbLootHandler LootQueries = new dbLootHandler();
public static final dbMenuHandler MenuQueries = new dbMenuHandler(); public static final dbMenuHandler MenuQueries = new dbMenuHandler();
public static final dbMineHandler MineQueries = new dbMineHandler(); public static final dbMineHandler MineQueries = new dbMineHandler();
@@ -55,6 +57,9 @@ public enum DbManager {
public static final dbPlayerCharacterHandler PlayerCharacterQueries = new dbPlayerCharacterHandler(); public static final dbPlayerCharacterHandler PlayerCharacterQueries = new dbPlayerCharacterHandler();
public static final dbPromotionClassHandler PromotionQueries = new dbPromotionClassHandler(); public static final dbPromotionClassHandler PromotionQueries = new dbPromotionClassHandler();
public static final dbRaceHandler RaceQueries = new dbRaceHandler(); public static final dbRaceHandler RaceQueries = new dbRaceHandler();
public static final dbResistHandler ResistQueries = new dbResistHandler();
public static final dbRuneBaseAttributeHandler RuneBaseAttributeQueries = new dbRuneBaseAttributeHandler();
public static final dbRuneBaseEffectHandler RuneBaseEffectQueries = new dbRuneBaseEffectHandler();
public static final dbRuneBaseHandler RuneBaseQueries = new dbRuneBaseHandler(); public static final dbRuneBaseHandler RuneBaseQueries = new dbRuneBaseHandler();
public static final dbSkillBaseHandler SkillsBaseQueries = new dbSkillBaseHandler(); public static final dbSkillBaseHandler SkillsBaseQueries = new dbSkillBaseHandler();
public static final dbSkillReqHandler SkillReqQueries = new dbSkillReqHandler(); public static final dbSkillReqHandler SkillReqQueries = new dbSkillReqHandler();
@@ -65,6 +70,7 @@ public enum DbManager {
public static final dbShrineHandler ShrineQueries = new dbShrineHandler(); public static final dbShrineHandler ShrineQueries = new dbShrineHandler();
public static final dbRunegateHandler RunegateQueries = new dbRunegateHandler(); public static final dbRunegateHandler RunegateQueries = new dbRunegateHandler();
public static final dbPowerHandler PowerQueries = new dbPowerHandler();
public static final dbPetitionHandler PetitionQueries = new dbPetitionHandler(); public static final dbPetitionHandler PetitionQueries = new dbPetitionHandler();
private static final EnumMap<GameObjectType, ConcurrentHashMap<Integer, AbstractGameObject>> objectCache = new EnumMap<>(GameObjectType.class); private static final EnumMap<GameObjectType, ConcurrentHashMap<Integer, AbstractGameObject>> objectCache = new EnumMap<>(GameObjectType.class);
public static Hasher hasher; public static Hasher hasher;
@@ -101,7 +101,6 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new SetAdminRuneCmd()); DevCmdManager.registerDevCmd(new SetAdminRuneCmd());
DevCmdManager.registerDevCmd(new SetInvulCmd()); DevCmdManager.registerDevCmd(new SetInvulCmd());
DevCmdManager.registerDevCmd(new MakeItemCmd()); DevCmdManager.registerDevCmd(new MakeItemCmd());
DevCmdManager.registerDevCmd(new FillCmd());
DevCmdManager.registerDevCmd(new SetSubRaceCmd()); DevCmdManager.registerDevCmd(new SetSubRaceCmd());
// Admin // Admin
+9 -16
View File
@@ -15,8 +15,8 @@ import engine.mbEnums;
import engine.net.client.msg.ItemProductionMsg; import engine.net.client.msg.ItemProductionMsg;
import engine.objects.City; import engine.objects.City;
import engine.objects.Item; import engine.objects.Item;
import engine.objects.ItemTemplate;
import engine.objects.NPC; import engine.objects.NPC;
import engine.parsers.objects.CObjectTemplate;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -49,9 +49,6 @@ public enum ForgeManager implements Runnable {
public static final ConcurrentHashMap<NPC, ConcurrentHashMap.KeySetView<WorkOrder, Boolean>> vendorWorkOrderLookup = new ConcurrentHashMap<>(); public static final ConcurrentHashMap<NPC, ConcurrentHashMap.KeySetView<WorkOrder, Boolean>> vendorWorkOrderLookup = new ConcurrentHashMap<>();
public static final ConcurrentHashMap<Item, WorkOrder> itemWorkOrderLookup = new ConcurrentHashMap<>(); public static final ConcurrentHashMap<Item, WorkOrder> itemWorkOrderLookup = new ConcurrentHashMap<>();
// Server-only data from static_vendor_items; the client templates have no mod table.
public static HashMap<Integer, Integer> vendorModTables = new HashMap<>();
public static void start() { public static void start() {
Thread forgeManager; Thread forgeManager;
@@ -225,12 +222,12 @@ public enum ForgeManager implements Runnable {
// Calculate production cost for a single run of the workOrder // Calculate production cost for a single run of the workOrder
HashMap<mbEnums.ResourceType, Integer> production_cost = new HashMap<>(); HashMap<mbEnums.ResourceType, Integer> production_cost = new HashMap<>();
CObjectTemplate template = CObjectTemplate.lookup(workOrder.templateID); ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
// Add gold and resource costs from template // Add gold and resource costs from template
production_cost.put(mbEnums.ResourceType.GOLD, template.getItemValue()); production_cost.put(mbEnums.ResourceType.GOLD, template.item_value);
production_cost.putAll(template.getItemResourceCosts()); production_cost.putAll(template.item_resource_cost);
// Calculate cost of prefix and suffix // Calculate cost of prefix and suffix
@@ -251,8 +248,8 @@ public enum ForgeManager implements Runnable {
// Create new virtual item from specified template // Create new virtual item from specified template
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
Item forgedItem = new Item(workOrder.templateID); Item forgedItem = new Item(workOrder.templateID);
int modTable = getVendorModTable(workOrder.templateID);
// forgedItem gets a negative id; a virtual item which is not persisted // forgedItem gets a negative id; a virtual item which is not persisted
@@ -267,13 +264,13 @@ public enum ForgeManager implements Runnable {
// Assign a prefix and suffix to this item if random rolled // Assign a prefix and suffix to this item if random rolled
if (workOrder.prefixToken == 0 && workOrder.vendor.getItemModTable().contains(modTable)) if (workOrder.prefixToken == 0 && workOrder.vendor.getItemModTable().contains((template.modTable)))
forgedItem.prefixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.PREFIX, modTable); forgedItem.prefixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.PREFIX, template.modTable);
else else
forgedItem.prefixToken = workOrder.prefixToken; forgedItem.prefixToken = workOrder.prefixToken;
if (workOrder.suffixToken == 0 && workOrder.vendor.getItemModTable().contains(modTable)) if (workOrder.suffixToken == 0 && workOrder.vendor.getItemModTable().contains((template.modTable)))
forgedItem.suffixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.SUFFIX, modTable); forgedItem.suffixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.SUFFIX, template.modTable);
else else
forgedItem.suffixToken = workOrder.suffixToken; forgedItem.suffixToken = workOrder.suffixToken;
@@ -367,10 +364,6 @@ public enum ForgeManager implements Runnable {
DbManager.WarehouseQueries.WRITE_WORKORDER(workOrder); DbManager.WarehouseQueries.WRITE_WORKORDER(workOrder);
} }
public static int getVendorModTable(int templateID) {
return vendorModTables.getOrDefault(templateID, 0);
}
public static int calcRandomMod(NPC vendor, mbEnums.ItemModType itemModType, int modTable) { public static int calcRandomMod(NPC vendor, mbEnums.ItemModType itemModType, int modTable) {
// Random prefix or suffix token based on item.template.modtable // Random prefix or suffix token based on item.template.modtable
+1 -1
View File
@@ -307,7 +307,7 @@ public enum GroupManager {
return false; return false;
} }
if (!item.template.getItemType().equals(mbEnums.ItemType.GOLD)) //only split goldItem if (!item.template.item_type.equals(mbEnums.ItemType.GOLD)) //only split goldItem
return false; return false;
Group group = getGroup(pc); Group group = getGroup(pc);
+5 -5
View File
@@ -16,7 +16,7 @@ import engine.net.client.ClientConnection;
import engine.net.client.msg.guild.AcceptInviteToGuildMsg; import engine.net.client.msg.guild.AcceptInviteToGuildMsg;
import engine.net.client.msg.guild.GuildInfoMsg; import engine.net.client.msg.guild.GuildInfoMsg;
import engine.objects.*; import engine.objects.*;
import org.joda.time.DateTime; import java.time.Instant;
public enum GuildManager { public enum GuildManager {
@@ -67,8 +67,8 @@ public enum GuildManager {
return false; return false;
if (playerCharacter.getGuild() != null && !playerCharacter.getGuild().isEmptyGuild()) { if (playerCharacter.getGuild() != null && !playerCharacter.getGuild().isEmptyGuild()) {
if (DbManager.GuildQueries.ADD_TO_GUILDHISTORY(playerCharacter.getGuildUUID(), playerCharacter, DateTime.now(), GuildHistoryType.LEAVE)) { if (DbManager.GuildQueries.ADD_TO_GUILDHISTORY(playerCharacter.getGuildUUID(), playerCharacter, Instant.now(), GuildHistoryType.LEAVE)) {
GuildHistory guildHistory = new GuildHistory(playerCharacter.getGuildUUID(), playerCharacter.getGuild().getName(), DateTime.now(), GuildHistoryType.LEAVE); GuildHistory guildHistory = new GuildHistory(playerCharacter.getGuildUUID(), playerCharacter.getGuild().getName(), Instant.now(), GuildHistoryType.LEAVE);
playerCharacter.getGuildHistory().add(guildHistory); playerCharacter.getGuildHistory().add(guildHistory);
} }
} }
@@ -90,8 +90,8 @@ public enum GuildManager {
dispatch = Dispatch.borrow(playerCharacter, msg); dispatch = Dispatch.borrow(playerCharacter, msg);
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
if (DbManager.GuildQueries.ADD_TO_GUILDHISTORY(guild.getObjectUUID(), playerCharacter, DateTime.now(), historyType)) { if (DbManager.GuildQueries.ADD_TO_GUILDHISTORY(guild.getObjectUUID(), playerCharacter, Instant.now(), historyType)) {
GuildHistory guildHistory = new GuildHistory(guild.getObjectUUID(), guild.getName(), DateTime.now(), historyType); GuildHistory guildHistory = new GuildHistory(guild.getObjectUUID(), guild.getName(), Instant.now(), historyType);
playerCharacter.getGuildHistory().add(guildHistory); playerCharacter.getGuildHistory().add(guildHistory);
} }
+54 -35
View File
@@ -2,7 +2,6 @@ package engine.gameManager;
import engine.mbEnums; import engine.mbEnums;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -22,46 +21,66 @@ public enum ItemManager {
public static final AtomicInteger lastNegativeID = new AtomicInteger(0); public static final AtomicInteger lastNegativeID = new AtomicInteger(0);
// restrict true: the set is a blacklist; false: a whitelist. An empty set allows everyone.
public static Boolean ValidRace(Item item, mbEnums.MonsterType race) { public static Boolean ValidRace(Item item, mbEnums.MonsterType race) {
EnumSet<mbEnums.MonsterType> races = item.template.getItemRaceReq(); if (item.template.item_race_req.isEmpty() && item.template.item_race_res.isEmpty())
boolean restrict = item.template.getItemRaceReqRestrict();
if (races.isEmpty())
return true; return true;
return races.contains(race) != restrict; if (item.template.item_race_req.isEmpty() == false)
if (item.template.item_race_req.contains(race))
return true;
if (item.template.item_race_res.isEmpty() == false)
if (item.template.item_race_res.contains(race) == false)
return true;
return false;
} }
public static Boolean ValidClass(Item item, mbEnums.ClassType base, mbEnums.ClassType profession) { public static Boolean ValidClass(Item item, mbEnums.ClassType base, mbEnums.ClassType profession) {
EnumSet<mbEnums.ClassType> classes = item.template.getItemClassReq(); // Early exit if no entry
boolean restrict = item.template.getItemClassReqRestrict();
boolean listed;
if (classes.isEmpty()) if (item.template.item_class_req.isEmpty() && item.template.item_class_res.isEmpty())
return true; return true;
listed = classes.contains(base) || classes.contains(profession); if (item.template.item_class_req.isEmpty() == false)
if (item.template.item_class_req.contains(base) || item.template.item_class_req.contains(profession))
return true;
return listed != restrict; if (item.template.item_class_res.isEmpty() == false)
if (item.template.item_class_res.contains(base) == false && item.template.item_class_res.contains(profession) == false)
return true;
return false;
} }
public static Boolean ValidDiscipline(Item item, EnumSet<mbEnums.DisciplineType> discs) { public static Boolean ValidDiscipline(Item item, EnumSet<mbEnums.DisciplineType> discs) {
EnumSet<mbEnums.DisciplineType> disciplines = item.template.getItemDiscReq(); // Early exit if no entry
boolean restrict = item.template.getItemDiscReqRestrict();
EnumSet<mbEnums.DisciplineType> workSet;
if (disciplines.isEmpty()) if (item.template.item_disc_req.isEmpty() && item.template.item_disc_res.isEmpty())
return true; return true;
workSet = EnumSet.copyOf(discs); EnumSet<mbEnums.DisciplineType> workSet = EnumSet.copyOf(discs);
workSet.retainAll(disciplines);
return workSet.isEmpty() == restrict; if (item.template.item_disc_req.isEmpty() == false) {
workSet.retainAll(item.template.item_disc_req);
if (workSet.isEmpty() == false)
return true;
}
if (item.template.item_disc_res.isEmpty() == false) {
workSet.retainAll(item.template.item_disc_res);
if (workSet.isEmpty() == false)
return true;
}
return false;
} }
public static Boolean canCharacterEquip(Item item, AbstractCharacter character) { public static Boolean canCharacterEquip(Item item, AbstractCharacter character) {
@@ -72,12 +91,12 @@ public enum ItemManager {
CharacterSkill characterSkill; CharacterSkill characterSkill;
if (item.template.getItemSkillReq().isEmpty()) if (item.template.item_skill_required.isEmpty())
return true; return true;
for (String skillRequired : item.template.getItemSkillReq().keySet()) { for (String skillRequired : item.template.item_skill_required.keySet()) {
int required_value = item.template.getItemSkillReq().get(skillRequired); int required_value = item.template.item_skill_required.get(skillRequired);
characterSkill = skills.get(skillRequired); characterSkill = skills.get(skillRequired);
if (characterSkill == null) if (characterSkill == null)
@@ -93,31 +112,31 @@ public enum ItemManager {
public static boolean isTwoHanded(Item item) { public static boolean isTwoHanded(Item item) {
if (!item.template.getItemType().equals(mbEnums.ItemType.WEAPON)) if (!item.template.item_type.equals(mbEnums.ItemType.WEAPON))
return false; return false;
return item.template.getItemEqSlotsAnd().containsAll(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD)); return item.template.item_eq_slots_and.contains(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD));
} }
public static boolean isTwoHanded(CObjectTemplate template) { public static boolean isTwoHanded(ItemTemplate template) {
if (!template.getItemType().equals(mbEnums.ItemType.WEAPON)) if (!template.item_type.equals(mbEnums.ItemType.WEAPON))
return false; return false;
return template.getItemEqSlotsAnd().containsAll(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD)); return template.item_eq_slots_and.contains(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD));
} }
public static boolean isShield(Item item) { public static boolean isShield(Item item) {
if (item.template.getItemSkillReq().containsKey("Block")) if (item.template.item_skill_required.containsKey("Block"))
return true; return true;
return false; return false;
} }
public static boolean isShield(CObjectTemplate template) { public static boolean isShield(ItemTemplate template) {
if (template.getItemSkillReq().containsKey("Block")) if (template.item_skill_required.containsKey("Block"))
return true; return true;
return false; return false;
@@ -131,7 +150,7 @@ public enum ItemManager {
return false; return false;
//Item not valid for slot //Item not valid for slot
if (item.template.getItemEqSlotsOr().contains(slot) == false) if (item.template.item_eq_slots_or.contains(slot) == false)
return false; return false;
// Slot is taken // Slot is taken
@@ -146,7 +165,7 @@ public enum ItemManager {
(slot == mbEnums.EquipSlotType.RHELD && equipped.get(mbEnums.EquipSlotType.LHELD) != null))) (slot == mbEnums.EquipSlotType.RHELD && equipped.get(mbEnums.EquipSlotType.LHELD) != null)))
return false; return false;
if (item.template.getItemType().equals(mbEnums.ItemType.WEAPON)) if (item.template.item_type.equals(mbEnums.ItemType.WEAPON))
if (equipped.get(slot) != null && equipped.get(slot).equals(item) == false) if (equipped.get(slot) != null && equipped.get(slot).equals(item) == false)
return false; return false;
@@ -178,7 +197,7 @@ public enum ItemManager {
//players can't wear 0 value items. //players can't wear 0 value items.
return item.template.getItemValue() != 0 || Kit.IsNoobGear(item.templateID); return item.template.item_value != 0 || Kit.IsNoobGear(item.templateID);
} }
+8 -9
View File
@@ -13,7 +13,6 @@ import engine.mbEnums;
import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.chat.ChatSystemMsg; import engine.net.client.msg.chat.ChatSystemMsg;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
@@ -92,8 +91,8 @@ public enum LootManager {
//lastly, check mobs inventory for godly or disc runes to send a server announcement //lastly, check mobs inventory for godly or disc runes to send a server announcement
for (Item item : mob.getInventory()) { for (Item item : mob.getInventory()) {
if ((item.templateID > 2499 && item.templateID <= 3050) || item.template.getItemBaseName().toLowerCase().contains("of the gods")) { if ((item.templateID > 2499 && item.templateID <= 3050) || item.template.item_base_name.toLowerCase().contains("of the gods")) {
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().zoneName + " has found the " + item.template.getItemBaseName() + ". Are you tough enough to take it?"); ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().zoneName + " has found the " + item.template.item_base_name + ". Are you tough enough to take it?");
chatMsg.setMessageType(10); chatMsg.setMessageType(10);
chatMsg.setChannel(mbEnums.ChatChannelType.SYSTEM.getChannelID()); chatMsg.setChannel(mbEnums.ChatChannelType.SYSTEM.getChannelID());
DispatchManager.dispatchMsgToAll(chatMsg); DispatchManager.dispatchMsgToAll(chatMsg);
@@ -180,12 +179,12 @@ public enum LootManager {
if (itemUUID == 0) if (itemUUID == 0)
return null; return null;
if (CObjectTemplate.lookup(itemUUID).getItemType().equals(mbEnums.ItemType.RESOURCE)) { if (ItemTemplate.templates.get(itemUUID).item_type.equals(mbEnums.ItemType.RESOURCE)) {
int amount = ThreadLocalRandom.current().nextInt(tableRow.minSpawn, tableRow.maxSpawn + 1); int amount = ThreadLocalRandom.current().nextInt(tableRow.minSpawn, tableRow.maxSpawn + 1);
return new MobLoot(mob, CObjectTemplate.lookup(itemUUID), amount, false); return new MobLoot(mob, ItemTemplate.templates.get(itemUUID), amount, false);
} }
outItem = new MobLoot(mob, CObjectTemplate.lookup(itemUUID), false); outItem = new MobLoot(mob, ItemTemplate.templates.get(itemUUID), false);
if (selectedRow.pModTable != 0) if (selectedRow.pModTable != 0)
try { try {
@@ -375,7 +374,7 @@ public enum LootManager {
if (chanceRoll > bse.dropChance) if (chanceRoll > bse.dropChance)
return; return;
MobLoot lootItem = new MobLoot(mob, CObjectTemplate.lookup(bse.templateID), true); MobLoot lootItem = new MobLoot(mob, ItemTemplate.templates.get(bse.templateID), true);
if (lootItem != null) if (lootItem != null)
mob.charItemManager.addItemToInventory(lootItem); mob.charItemManager.addItemToInventory(lootItem);
@@ -423,14 +422,14 @@ public enum LootManager {
//create the item from the table, quantity is always 1 //create the item from the table, quantity is always 1
MobLoot winnings = new MobLoot(playerCharacter, CObjectTemplate.lookup(selectedItem.templateID), 1, false); MobLoot winnings = new MobLoot(playerCharacter, ItemTemplate.templates.get(selectedItem.templateID), 1, false);
if (winnings == null) if (winnings == null)
return; return;
//early exit if the inventory of the player will not old the item //early exit if the inventory of the player will not old the item
if (itemMan.hasRoomInventory(winnings.template.getItemWt()) == false) { if (itemMan.hasRoomInventory(winnings.template.item_wt) == false) {
ErrorPopupMsg.sendErrorPopup(playerCharacter, 21); ErrorPopupMsg.sendErrorPopup(playerCharacter, 21);
return; return;
} }
+28 -70
View File
@@ -19,14 +19,12 @@ import engine.net.client.ClientConnection;
import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.PetMsg; import engine.net.client.msg.PetMsg;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import engine.powers.RuneSkillAdjustEntry; import engine.powers.RuneSkillAdjustEntry;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@@ -317,26 +315,26 @@ public enum NPCManager {
//has main hand weapon //has main hand weapon
Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD); Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD);
if (engine.parsers.objects.ItemTemplate._items.get(weapon.templateID).item_primary_attr == mbEnums.AttributeType.Strength) if (weapon.template.item_primary_attr.equals(mbEnums.AttributeType.Strength))
primaryStat = guard.getStatStrCurrent(); primaryStat = guard.getStatStrCurrent();
else else
primaryStat = guard.getStatDexCurrent(); primaryStat = guard.getStatDexCurrent();
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_min) * rankModifier) + primaryStat; guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + weapon.template.item_weapon_damage.values().iterator().next()[0]) * rankModifier) + primaryStat;
guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_max) * rankModifier) + primaryStat; guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + weapon.template.item_weapon_damage.values().iterator().next()[1]) * rankModifier) + primaryStat;
guard.speedHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed; guard.speedHandOne = weapon.template.item_weapon_wepspeed;
guard.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range; guard.rangeHandOne = weapon.template.item_weapon_max_range;
} else if (guard.charItemManager.equipped.containsKey(mbEnums.EquipSlotType.LHELD) && !ItemManager.isShield(guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template)) { } else if (guard.charItemManager.equipped.containsKey(mbEnums.EquipSlotType.LHELD) && !ItemManager.isShield(guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template)) {
//has off hand weapon //has off hand weapon
Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD); Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD);
if (engine.parsers.objects.ItemTemplate._items.get(weapon.templateID).item_primary_attr == mbEnums.AttributeType.Strength) if (weapon.template.item_primary_attr.equals(mbEnums.AttributeType.Strength))
primaryStat = guard.getStatStrCurrent(); primaryStat = guard.getStatStrCurrent();
else else
primaryStat = guard.getStatDexCurrent(); primaryStat = guard.getStatDexCurrent();
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_min) * rankModifier) + primaryStat; guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + weapon.template.item_weapon_damage.values().iterator().next()[0]) * rankModifier) + primaryStat;
guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_max) * rankModifier) + primaryStat; guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + weapon.template.item_weapon_damage.values().iterator().next()[1]) * rankModifier) + primaryStat;
guard.speedHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed; guard.speedHandOne = weapon.template.item_weapon_wepspeed;
guard.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range; guard.rangeHandOne = weapon.template.item_weapon_max_range;
} else { } else {
primaryStat = guard.getStatStrCurrent(); primaryStat = guard.getStatStrCurrent();
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin()) * rankModifier) + primaryStat; guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin()) * rankModifier) + primaryStat;
@@ -354,8 +352,8 @@ public enum NPCManager {
int baseDef = guard.mobBase.getDefenseRating(); int baseDef = guard.mobBase.getDefenseRating();
int armorDefense = 0; int armorDefense = 0;
for (Item equipped : guard.charItemManager.equipped.values()) for (Item equipped : guard.charItemManager.equipped.values())
if (equipped.template.getItemType().equals(mbEnums.ItemType.ARMOR) || ItemManager.isShield(equipped.template)) if (equipped.template.item_type.equals(mbEnums.ItemType.ARMOR) || ItemManager.isShield(equipped.template))
armorDefense += engine.parsers.objects.ItemTemplate._items.get(equipped.templateID).item_defense_rating; armorDefense += equipped.template.item_defense_rating;
guard.defenseRating = dexterity + baseDef + armorDefense; guard.defenseRating = dexterity + baseDef + armorDefense;
} }
@@ -363,9 +361,9 @@ public enum NPCManager {
int strength = guard.getStatStrCurrent(); int strength = guard.getStatStrCurrent();
int baseAtr = guard.mobBase.getAttackRating(); int baseAtr = guard.mobBase.getAttackRating();
if (guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD) != null) if (guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD) != null)
guard.atrHandOne = baseAtr + (int) ((strength * 0.5f) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD).template.getItemSkillReq().values().toArray()[0] * 4) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD).template.getItemSkillReq().values().toArray()[0] * 3)); guard.atrHandOne = baseAtr + (int) ((strength * 0.5f) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD).template.item_skill_required.values().toArray()[0] * 4) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD).template.item_skill_required.values().toArray()[0] * 3));
else if (guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD) != null && !ItemManager.isShield(guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template)) else if (guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD) != null && !ItemManager.isShield(guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template))
guard.atrHandTwo = baseAtr + (int) ((strength * 0.5f) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template.getItemSkillReq().values().toArray()[0] * 4) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template.getItemSkillReq().values().toArray()[0] * 3)); guard.atrHandTwo = baseAtr + (int) ((strength * 0.5f) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template.item_skill_required.values().toArray()[0] * 4) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template.item_skill_required.values().toArray()[0] * 3));
else else
guard.atrHandOne = baseAtr; guard.atrHandOne = baseAtr;
} }
@@ -436,63 +434,28 @@ public enum NPCManager {
} }
} }
if (mob.isNecroPet())
applyNecroPetStats(mob);
}
// No client data grants NECROPETSTATS, yet NEC-018 and DRU-066 require it on the target; the server adds it to necro pets
private static void applyNecroPetStats(Mob mob) {
EffectsBase necroPetStats = PowersManager.getEffectByIDString("NECROPETSTATS");
String effectKey;
Effect currentEffect;
int rank = -1;
if (necroPetStats == null) {
Logger.error("NECROPETSTATS effect not loaded");
return;
}
// GUESS: rank follows the pet's own level ladder (PET_NECRO / PET_NECRO_HARDHIT, from reqLvl 9), as the old DB rows did
for (MobBaseEffects mbe : mob.mobBase.effectsList)
if (mbe.getReqLvl() > 0 && mbe.getReqLvl() <= (int) mob.level)
rank = Math.max(rank, mbe.getRank());
if (rank < 0)
return;
effectKey = Integer.toString(necroPetStats.getUUID());
currentEffect = mob.effects.get(effectKey);
if (currentEffect != null) {
if (currentEffect.getTrains() >= rank)
return;
currentEffect.cancelJob();
}
mob.addEffectNoTimer(effectKey, necroPetStats, rank, true);
} }
public static void applyEquipmentResists(Mob mob) { public static void applyEquipmentResists(Mob mob) {
EnumMap<mbEnums.DamageType, Float> armorResists;
if (mob.charItemManager.equipped.isEmpty()) if (mob.charItemManager.equipped.isEmpty())
return; return;
for (Item equipped : mob.charItemManager.equipped.values()) { for (Item equipped : mob.charItemManager.equipped.values()) {
if (equipped.template.getItemType().equals(mbEnums.ItemType.ARMOR)) { if (equipped.template.item_type.equals(mbEnums.ItemType.ARMOR)) {
armorResists = equipped.template.getCombatAttackResist(); mob.resists.setResist(mbEnums.DamageType.SLASHING, mob.resists.getResist(mbEnums.DamageType.SLASHING, 0) + equipped.template.combat_attack_resist.get("SLASHING"));
mob.resists.setResist(mbEnums.DamageType.SLASHING, mob.resists.getResist(mbEnums.DamageType.SLASHING, 0) + armorResists.getOrDefault(mbEnums.DamageType.SLASHING, 0f)); mob.resists.setResist(mbEnums.DamageType.CRUSHING, mob.resists.getResist(mbEnums.DamageType.CRUSHING, 0) + equipped.template.combat_attack_resist.get("CRUSHING"));
mob.resists.setResist(mbEnums.DamageType.CRUSHING, mob.resists.getResist(mbEnums.DamageType.CRUSHING, 0) + armorResists.getOrDefault(mbEnums.DamageType.CRUSHING, 0f)); mob.resists.setResist(mbEnums.DamageType.PIERCING, mob.resists.getResist(mbEnums.DamageType.PIERCING, 0) + equipped.template.combat_attack_resist.get("PIERCING"));
mob.resists.setResist(mbEnums.DamageType.PIERCING, mob.resists.getResist(mbEnums.DamageType.PIERCING, 0) + armorResists.getOrDefault(mbEnums.DamageType.PIERCING, 0f));
} }
} }
} }
public static void applyMobbaseSkill(Mob mob) {
SkillsBase baseSkill = DbManager.SkillsBaseQueries.GET_BASE_BY_TOKEN(mob.mobBase.getMobBaseStats().getBaseSkill());
if (baseSkill != null)
mob.getSkills().put(baseSkill.getName(), new CharacterSkill(baseSkill, mob, mob.mobBase.getMobBaseStats().getBaseSkillAmount()));
}
public static void applyRuneSkills(Mob mob, int runeID) { public static void applyRuneSkills(Mob mob, int runeID) {
//load mob skill adjustments from mobbase rune //load mob skill adjustments from mobbase rune
if (PowersManager._allRuneSkillAdjusts.containsKey(runeID)) if (PowersManager._allRuneSkillAdjusts.containsKey(runeID))
@@ -503,7 +466,7 @@ public enum NPCManager {
if (skillBase == null) if (skillBase == null)
continue; continue;
if (entry.level <= mob.level) if (entry.level <= mob.level)
if (mob.skills.containsKey(entry.skill_type) == false) if (mob.skills.containsKey(entry.name) == false)
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank)); mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank));
else else
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank + mob.skills.get(entry.skill_type).getNumTrains())); mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank + mob.skills.get(entry.skill_type).getNumTrains()));
@@ -517,11 +480,6 @@ public enum NPCManager {
npc.runes.add(shopkeeper); npc.runes.add(shopkeeper);
if (NPCManager._runeSetMap.containsKey(npc.runeSetID)) { if (NPCManager._runeSetMap.containsKey(npc.runeSetID)) {
for (int runeID : _runeSetMap.get(npc.runeSetID)) { for (int runeID : _runeSetMap.get(npc.runeSetID)) {
// Shopkeeper is already applied above and most rune sets repeat it
if (runeID == 252620)
continue;
RuneBase rb = RuneBase.getRuneBase(runeID); RuneBase rb = RuneBase.getRuneBase(runeID);
if (rb != null) { if (rb != null) {
CharacterRune toApply = new CharacterRune(rb, npc.getObjectUUID()); CharacterRune toApply = new CharacterRune(rb, npc.getObjectUUID());
@@ -578,14 +536,14 @@ public enum NPCManager {
public static long calcRollingDuration(NPC vendor, int templateID) { public static long calcRollingDuration(NPC vendor, int templateID) {
CObjectTemplate template = CObjectTemplate.lookup(templateID); ItemTemplate template = ItemTemplate.templates.get(templateID);
float rollingDuration; float rollingDuration;
if (template == null) if (template == null)
return 0; return 0;
if (template.getItemBaneRank() > 0) if (template.item_bane_rank > 0)
return (long) (template.getItemBaneRank() * 60 * 60 * 3 * 1000 * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue())); return (long) (template.item_bane_rank * 60 * 60 * 3 * 1000 * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()));
if (vendor.building == null) if (vendor.building == null)
return 600; return 600;
+67 -242
View File
@@ -10,6 +10,9 @@ package engine.gameManager;
import engine.InterestManagement.Terrain; import engine.InterestManagement.Terrain;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.db.handlers.dbEffectsBaseHandler;
import engine.db.handlers.dbPowerHandler;
import engine.db.handlers.dbSkillReqHandler;
import engine.job.AbstractJob; import engine.job.AbstractJob;
import engine.job.AbstractScheduleJob; import engine.job.AbstractScheduleJob;
import engine.job.JobContainer; import engine.job.JobContainer;
@@ -25,12 +28,8 @@ import engine.net.Dispatch;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.*; import engine.net.client.msg.*;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.wpak.EffectTemplate;
import engine.parsers.objects.wpak.PowActionCostTemplate;
import engine.parsers.objects.wpak.PowerActionTemplate;
import engine.parsers.objects.wpak.PowerTemplate;
import engine.powers.*; import engine.powers.*;
import engine.powers.poweractions.*; import engine.powers.poweractions.AbstractPowerAction;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -38,7 +37,6 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@@ -55,6 +53,7 @@ public enum PowersManager {
public static HashMap<String, AbstractPowerAction> powerActionsByIDString = new HashMap<>(); public static HashMap<String, AbstractPowerAction> powerActionsByIDString = new HashMap<>();
public static HashMap<Integer, AbstractPowerAction> powerActionsByID = new HashMap<>(); public static HashMap<Integer, AbstractPowerAction> powerActionsByID = new HashMap<>();
public static HashMap<String, Integer> ActionTokenByIDString = new HashMap<>(); public static HashMap<String, Integer> ActionTokenByIDString = new HashMap<>();
public static HashMap<String, Integer> AnimationOverrides = new HashMap<>();
public static HashMap<Integer, ArrayList<RunePowerEntry>> _allRunePowers; public static HashMap<Integer, ArrayList<RunePowerEntry>> _allRunePowers;
public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> _allRuneSkillAdjusts; public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> _allRuneSkillAdjusts;
public static HashMap<String, HashMap<ResourceType, Integer>> _effect_costMaps = new HashMap<>(); public static HashMap<String, HashMap<ResourceType, Integer>> _effect_costMaps = new HashMap<>();
@@ -91,200 +90,16 @@ public enum PowersManager {
return PowersManager.effectsBaseByToken.get(token); return PowersManager.effectsBaseByToken.get(token);
} }
public static void loadEffectCostMaps() { // This pre-loads only PowersBase for login
for (PowActionCostTemplate costTemplate : PowActionCostTemplate._costs.values())
PowersManager._effect_costMaps.put(costTemplate.id, new HashMap<>(costTemplate.costs));
Logger.info("Loaded " + PowersManager._effect_costMaps.size() + " effect cost maps from PowActionCostInfo.cfg");
}
// Effects.cfg in file order, then the ApplyEffect/ApplyEffects/Invis actions with no Effects.cfg block
private static void loadEffects() {
int effectID = 0;
int actionKeyCount = 0;
PowerActionTemplate powerActionTemplate;
for (EffectTemplate effectTemplate : EffectTemplate._effects.values())
addEffect(new EffectsBase(effectTemplate, ++effectID));
for (String actionID : new TreeSet<>(PowerActionTemplate._powerActions.keySet())) {
if (EffectTemplate._effects.containsKey(actionID))
continue;
powerActionTemplate = PowerActionTemplate._powerActions.get(actionID);
switch (powerActionTemplate.action_type) {
case ApplyEffect:
case ApplyEffects:
case Invis:
addEffect(new EffectsBase(powerActionTemplate, ++effectID));
actionKeyCount++;
break;
}
}
Logger.info("Loaded " + EffectTemplate._effects.size() + " effects from Effects.cfg and "
+ actionKeyCount + " effect keys from PowerActions.cfg");
}
// PowerActions.cfg in id order; ids 1..n, OPENGATE keeps 5000
private static void loadPowerActions() {
int powerActionID = 0;
PowerActionTemplate powerActionTemplate;
AbstractPowerAction powerAction;
AbstractPowerAction openGateAction;
for (String actionID : new TreeSet<>(PowerActionTemplate._powerActions.keySet())) {
powerActionTemplate = PowerActionTemplate._powerActions.get(actionID);
powerAction = buildPowerAction(powerActionTemplate, ++powerActionID);
if (powerAction == null) {
Logger.error("Power action " + actionID + " has unsupported type " + powerActionTemplate.action_type);
continue;
}
PowersManager.ActionTokenByIDString.put(actionID, DbManager.hasher.SBStringHash(actionID));
PowersManager.powerActionsByIDString.put(actionID, powerAction);
PowersManager.powerActionsByID.put(powerAction.getUUID(), powerAction);
}
openGateAction = new OpenGatePowerAction(5000, "OPENGATE", "OpenGate", false);
PowersManager.powerActionsByIDString.put("OPENGATE", openGateAction);
PowersManager.powerActionsByID.put(openGateAction.getUUID(), openGateAction);
Logger.info("Loaded " + PowersManager.powerActionsByIDString.size() + " power actions from PowerActions.cfg (incl. OPENGATE)");
}
private static AbstractPowerAction buildPowerAction(PowerActionTemplate powerActionTemplate, int id) {
HashMap<String, EffectsBase> effects = PowersManager.effectsBaseByIDString;
switch (powerActionTemplate.action_type) {
case ApplyEffect:
return new ApplyEffectPowerAction(powerActionTemplate, id, effects);
case ApplyEffects:
return new ApplyEffectsPowerAction(powerActionTemplate, id, effects);
case Block:
return new BlockPowerAction(powerActionTemplate, id);
case Charm:
// FEAR and CONFUSION Charm actions stay no-ops, as when the DB typed them Confusion
if (powerActionTemplate.effect_ids.get(0).equals("CHARM"))
return new CharmPowerAction(powerActionTemplate, id);
return new ConfusionPowerAction(powerActionTemplate, id);
case ClaimMine:
return new ClaimMinePowerAction(powerActionTemplate, id);
case ClearAggro:
return new ClearAggroPowerAction(powerActionTemplate, id);
case ClearNearbyAggro:
return new ClearNearbyAggroPowerAction(powerActionTemplate, id);
case Confusion:
return new ConfusionPowerAction(powerActionTemplate, id);
case CreateMob:
return new CreateMobPowerAction(powerActionTemplate, id);
case DamageOverTime:
return new DamageOverTimePowerAction(powerActionTemplate, id, effects);
case DeferredPower:
return new DeferredPowerPowerAction(powerActionTemplate, id, effects);
case DirectDamage:
return new DirectDamagePowerAction(powerActionTemplate, id, effects);
case Invis:
return new InvisPowerAction(powerActionTemplate, id, effects);
case MobRecall:
return new MobRecallPowerAction(powerActionTemplate, id);
case Peek:
return new PeekPowerAction(powerActionTemplate, id);
case Recall:
return new RecallPowerAction(powerActionTemplate, id);
case RemoveEffect:
return new RemoveEffectPowerAction(powerActionTemplate, id);
case Resurrect:
return new ResurrectPowerAction(powerActionTemplate, id);
case RunegateTeleport:
return new RunegateTeleportPowerAction(powerActionTemplate, id);
case SetItemFlag:
return new SetItemFlagPowerAction(powerActionTemplate, id);
case SimpleDamage:
return new SimpleDamagePowerAction(powerActionTemplate, id);
case SpireDisable:
return new SpireDisablePowerAction(powerActionTemplate, id);
case Steal:
return new StealPowerAction(powerActionTemplate, id);
case Summon:
return new SummonPowerAction(powerActionTemplate, id);
case Teleport:
return new TeleportPowerAction(powerActionTemplate, id);
case Track:
return new TrackPowerAction(powerActionTemplate, id, effects);
case TransferStat:
return new TransferStatPowerAction(powerActionTemplate, id, effects);
case TransferStatOT:
return new TransferStatOTPowerAction(powerActionTemplate, id, effects);
case Transform:
return new TransformPowerAction(powerActionTemplate, id, effects);
case TreeChoke:
return new TreeChokePowerAction(powerActionTemplate, id);
default:
return null;
}
}
private static void addEffect(EffectsBase effectsBase) {
PowersManager.effectsBaseByToken.put(effectsBase.getToken(), effectsBase);
PowersManager.effectsBaseByIDString.put(effectsBase.getIDString(), effectsBase);
}
// Powers.cfg in file order, ids 1..n (the old static_power_powerbase IDs)
private static void loadPowers() {
int powerID = 0;
PowersBase powersBase;
for (PowerTemplate powerTemplate : PowerTemplate._powers.values()) {
powersBase = new PowersBase(powerTemplate, ++powerID);
PowersManager.powersBaseByIDString.put(powersBase.getIDString(), powersBase);
PowersManager.powersBaseByToken.put(powersBase.getToken(), powersBase);
}
Logger.info("Loaded " + PowersManager.powersBaseByIDString.size() + " powers from Powers.cfg");
}
// ACTION= lines in Powers.cfg order, ids 1..n (offset in ActionsBase), then the OPENGATE actions
private static void loadActionLists() {
int actionID = 0;
PowersBase powersBase;
AbstractPowerAction powerAction;
for (PowerTemplate powerTemplate : PowerTemplate._powers.values()) {
powersBase = PowersManager.powersBaseByIDString.get(powerTemplate.power_id);
for (PowerTemplate.ActionEntry actionEntry : powerTemplate.actions) {
powerAction = PowersManager.powerActionsByIDString.get(actionEntry.action_id);
if (powerAction == null) {
Logger.error("Power " + powerTemplate.power_id + " lists unknown action " + actionEntry.action_id);
continue;
}
powersBase.getActions().add(new ActionsBase(actionEntry, powerTemplate.power_id, ++actionID, powerAction));
}
}
ActionsBase.addOpenGateActions(PowersManager.powersBaseByIDString);
Logger.info("Loaded " + actionID + " power action lines from Powers.cfg");
}
// The login server needs only the token map
public static void InitializeLoginPowers() { public static void InitializeLoginPowers() {
loadPowers();
// get all PowersBase
ArrayList<PowersBase> pbList = dbSkillReqHandler.getAllPowersBase();
for (PowersBase pb : pbList) {
if (pb.getToken() != 0)
PowersManager.powersBaseByToken.put(pb.getToken(), pb);
}
} }
public static ArrayList<RunePowerEntry> getPowersForRune(int rune_id) { public static ArrayList<RunePowerEntry> getPowersForRune(int rune_id) {
@@ -300,13 +115,48 @@ public enum PowersManager {
// This pre-loads all powers and effects // This pre-loads all powers and effects
public static void InitializePowers() { public static void InitializePowers() {
loadEffects(); // Add EffectsBase
ArrayList<EffectsBase> ebList = dbEffectsBaseHandler.getAllEffectsBase();
loadPowerActions(); for (EffectsBase eb : ebList) {
PowersManager.effectsBaseByToken.put(eb.getToken(), eb);
PowersManager.effectsBaseByIDString.put(eb.getIDString(), eb);
loadPowers(); }
// Add Fail Conditions
EffectsBase.getFailConditions(PowersManager.effectsBaseByIDString);
// Add Modifiers to Effects
dbEffectsBaseHandler.cacheAllEffectModifiers();
// Add Source Types to Effects
dbPowerHandler.addAllSourceTypes();
dbPowerHandler.addAllAnimationOverrides();
// Add PowerActions
AbstractPowerAction.getAllPowerActions(PowersManager.powerActionsByIDString, PowersManager.powerActionsByID, PowersManager.effectsBaseByIDString);
// Load valid Item Flags
// AbstractPowerAction.loadValidItemFlags(PowersManager.powerActionsByIDString);
// get all PowersBase
ArrayList<PowersBase> pbList = dbSkillReqHandler.getAllPowersBase();
for (PowersBase pb : pbList) {
if (pb.getToken() != 0) {
PowersManager.powersBaseByIDString.put(pb.getIDString(), pb);
PowersManager.powersBaseByToken.put(pb.getToken(), pb);
}
}
// Add Power Prereqs
PowerPrereq.getAllPowerPrereqs(PowersManager.powersBaseByIDString);
// Add Fail Conditions
dbSkillReqHandler.getFailConditions(PowersManager.powersBaseByIDString);
// Add Actions Base
ActionsBase.getActionsBase(PowersManager.powersBaseByIDString,
PowersManager.powerActionsByIDString);
loadActionLists();
} }
public static EffectsBase setEffectToken(int ID, int token) { public static EffectsBase setEffectToken(int ID, int token) {
@@ -1405,27 +1255,6 @@ public enum PowersManager {
return false; return false;
} }
// MONSTERTYPERESTRICTS: mobs use their race rune's monster type, players their RaceType's
private static boolean isRestrictedMonsterType(AbstractWorldObject target, PowersBase pb) {
MonsterType monsterType = null;
PlayerCharacter player;
if (target == null || pb.monsterTypeRestrictions.isEmpty())
return false;
if (target.getObjectType() == GameObjectType.Mob && ((Mob) target).getMobBase() != null)
monsterType = ((Mob) target).getMobBase().monsterType;
else if (target.getObjectType() == GameObjectType.PlayerCharacter) {
player = (PlayerCharacter) target;
if (player.race != null && player.race.getRaceType() != null)
monsterType = player.race.getRaceType().getMonsterType();
}
return monsterType != null && pb.monsterTypeRestrictions.contains(monsterType);
}
public static void sendRecyclePower(int token, ClientConnection origin) { public static void sendRecyclePower(int token, ClientConnection origin) {
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(token); RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(token);
@@ -1751,6 +1580,9 @@ public enum PowersManager {
//Pet only //Pet only
allTargets = WorldGrid.getObjectsInRangePartial( allTargets = WorldGrid.getObjectsInRangePartial(
targetLoc, pb.getRadius(), MBServerStatics.MASK_PET); targetLoc, pb.getRadius(), MBServerStatics.MASK_PET);
else if (pb.targetNecroPet())
allTargets = WorldGrid.getObjectsInRangePartialNecroPets(
targetLoc, pb.getRadius());
else else
allTargets = WorldGrid.getObjectsInRangePartial( allTargets = WorldGrid.getObjectsInRangePartial(
targetLoc, pb.getRadius(), 0); targetLoc, pb.getRadius(), 0);
@@ -1862,11 +1694,6 @@ public enum PowersManager {
continue; continue;
} }
if (isRestrictedMonsterType(awo, pb)) {
awolist.remove();
continue;
}
if (awo != null && awo.getObjectType().equals(GameObjectType.PlayerCharacter)) { if (awo != null && awo.getObjectType().equals(GameObjectType.PlayerCharacter)) {
// Remove players who are in safe mode // Remove players who are in safe mode
@@ -1952,6 +1779,9 @@ public enum PowersManager {
//Pet only //Pet only
allTargets = WorldGrid.getObjectsInRangePartial( allTargets = WorldGrid.getObjectsInRangePartial(
targetLoc, pb.getRadius(), MBServerStatics.MASK_PET); targetLoc, pb.getRadius(), MBServerStatics.MASK_PET);
else if (pb.targetNecroPet())
allTargets = WorldGrid.getObjectsInRangePartialNecroPets(
targetLoc, pb.getRadius());
else else
allTargets = WorldGrid.getObjectsInRangePartial( allTargets = WorldGrid.getObjectsInRangePartial(
targetLoc, pb.getRadius(), 0); targetLoc, pb.getRadius(), 0);
@@ -2016,11 +1846,6 @@ public enum PowersManager {
continue; continue;
} }
if (isRestrictedMonsterType(awo, pb)) {
awolist.remove();
continue;
}
if (awo != null && awo.getObjectType().equals(GameObjectType.PlayerCharacter)) { if (awo != null && awo.getObjectType().equals(GameObjectType.PlayerCharacter)) {
// Remove players who are in safe mode // Remove players who are in safe mode
PlayerCharacter pcc = (PlayerCharacter) awo; PlayerCharacter pcc = (PlayerCharacter) awo;
@@ -2413,14 +2238,14 @@ public enum PowersManager {
String outmsg = "Invalid Target"; String outmsg = "Invalid Target";
ChatManager.chatSystemInfo(pc, outmsg); ChatManager.chatSystemInfo(pc, outmsg);
return false; // can't target player, stop here return false; // can't target player, stop here
} // target is pet; pets also carry MASK_MOB, so test them first. A pet is still a Mobile (client 0x49E440) } // target is mob
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_PET) != 0)
return pb.targetPet() || pb.targetMob();
// target is mob
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_MOB) != 0) else if ((target.getObjectTypeMask() & MBServerStatics.MASK_MOB) != 0)
return pb.targetMob(); return pb.targetMob();
// target is pet
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_PET) != 0)
return pb.targetPet();
// target is Building // target is Building
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_BUILDING) != 0) else if ((target.getObjectTypeMask() & MBServerStatics.MASK_BUILDING) != 0)
return pb.targetBuilding(); return pb.targetBuilding();
@@ -2430,12 +2255,12 @@ public enum PowersManager {
if (pb.targetItem()) if (pb.targetItem())
return true; return true;
// TODO add these checks later // TODO add these checks later
else if (pb.targetArmor() && item.template.getItemType().equals(ItemType.ARMOR)) else if (pb.targetArmor() && item.template.item_type.equals(ItemType.ARMOR))
return true; return true;
else if (pb.targetJewelry() && item.template.getItemType().equals(ItemType.JEWELRY)) else if (pb.targetJewelry() && item.template.item_type.equals(ItemType.JEWELRY))
return true; return true;
else else
return pb.targetWeapon() && item.template.getItemType().equals(ItemType.WEAPON); return pb.targetWeapon() && item.template.item_type.equals(ItemType.WEAPON);
} // How did we get here? all valid targets have been covered } // How did we get here? all valid targets have been covered
else else
return false; return false;
+3 -6
View File
@@ -11,7 +11,7 @@ package engine.jobs;
import engine.job.AbstractScheduleJob; import engine.job.AbstractScheduleJob;
import engine.objects.Bane; import engine.objects.Bane;
import org.joda.time.DateTime; import java.time.LocalDateTime;
public class BaneDefaultTimeJob extends AbstractScheduleJob { public class BaneDefaultTimeJob extends AbstractScheduleJob {
@@ -31,11 +31,8 @@ public class BaneDefaultTimeJob extends AbstractScheduleJob {
return; return;
} }
DateTime defaultTime = new DateTime(this.bane.getPlacementDate()); LocalDateTime defaultTime = this.bane.getPlacementDate()
defaultTime = defaultTime.plusDays(2); .plusDays(2).withHour(22).withMinute(0).withSecond(0).withNano(0);
defaultTime = defaultTime.hourOfDay().setCopy(22);
defaultTime = defaultTime.minuteOfHour().setCopy(0);
defaultTime = defaultTime.secondOfMinute().setCopy(0);
this.bane.setLiveDate(defaultTime); this.bane.setLiveDate(defaultTime);
} }
+5 -1
View File
@@ -82,7 +82,11 @@ public class ChantJob extends AbstractEffectJob {
} }
if (AbstractWorldObject.IsAbstractCharacter(source)) if (AbstractWorldObject.IsAbstractCharacter(source))
((AbstractCharacter) this.source).setLastChant((int) (this.power.getChantDuration()) * 1000, this); //handle invul
if (power.getUUID() != 334)
((AbstractCharacter) this.source).setLastChant((int) (this.power.getChantDuration()) * 1000, this);
else
((AbstractCharacter) this.source).setLastChant((int) (this.power.getChantDuration()) * 1000, this);
} else { } else {
PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains); PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains);
if (AbstractWorldObject.IsAbstractCharacter(source)) { if (AbstractWorldObject.IsAbstractCharacter(source)) {
+2 -5
View File
@@ -25,7 +25,6 @@ public class DamageOverTimeJob extends AbstractEffectJob {
private final DamageOverTimePowerAction dot; private final DamageOverTimePowerAction dot;
private int iteration = 0; private int iteration = 0;
private int liveCounter = 0; private int liveCounter = 0;
private final int tickLength;
public DamageOverTimeJob(AbstractWorldObject source, AbstractWorldObject target, String stackType, int trains, ActionsBase action, PowersBase power, EffectsBase eb, DamageOverTimePowerAction dot) { public DamageOverTimeJob(AbstractWorldObject source, AbstractWorldObject target, String stackType, int trains, ActionsBase action, PowersBase power, EffectsBase eb, DamageOverTimePowerAction dot) {
super(source, target, stackType, trains, action, power, eb); super(source, target, stackType, trains, action, power, eb);
@@ -34,9 +33,7 @@ public class DamageOverTimeJob extends AbstractEffectJob {
if (this.target != null && AbstractWorldObject.IsAbstractCharacter(target)) if (this.target != null && AbstractWorldObject.IsAbstractCharacter(target))
this.liveCounter = ((AbstractCharacter) target).getLiveCounter(); this.liveCounter = ((AbstractCharacter) target).getLiveCounter();
// PowerActions.cfg gives the tick count; the ticks split the action's duration this.iteration = action.getDurationInSeconds(trains) / this.dot.getNumIterations();
this.iteration = this.dot.getNumIterations();
this.tickLength = action.getDuration(trains) / Math.max(1, this.dot.getNumIterations());
} }
@Override @Override
@@ -85,7 +82,7 @@ public class DamageOverTimeJob extends AbstractEffectJob {
} }
public int getTickLength() { public int getTickLength() {
return this.tickLength; return this.dot.getNumIterations() * 1000;
} }
public int inc() { public int inc() {
+2 -6
View File
@@ -21,15 +21,11 @@ public class TransferStatOTJob extends AbstractEffectJob {
private final TransferStatOTPowerAction dot; private final TransferStatOTPowerAction dot;
private int iteration = 0; private int iteration = 0;
private final int tickLength;
public TransferStatOTJob(AbstractWorldObject source, AbstractWorldObject target, String stackType, int trains, ActionsBase action, PowersBase power, EffectsBase eb, TransferStatOTPowerAction dot) { public TransferStatOTJob(AbstractWorldObject source, AbstractWorldObject target, String stackType, int trains, ActionsBase action, PowersBase power, EffectsBase eb, TransferStatOTPowerAction dot) {
super(source, target, stackType, trains, action, power, eb); super(source, target, stackType, trains, action, power, eb);
this.dot = dot; this.dot = dot;
this.iteration = action.getDurationInSeconds(trains) / this.dot.getNumIterations();
// PowerActions.cfg gives the tick count; the ticks split the action's duration
this.iteration = this.dot.getNumIterations();
this.tickLength = action.getDuration(trains) / Math.max(1, this.dot.getNumIterations());
} }
@Override @Override
@@ -68,7 +64,7 @@ public class TransferStatOTJob extends AbstractEffectJob {
} }
public int getTickLength() { public int getTickLength() {
return this.tickLength; return this.dot.getNumIterations() * 1000;
} }
public int inc() { public int inc() {
+4 -4
View File
@@ -12,9 +12,9 @@ import engine.gameManager.DbManager;
import engine.gameManager.ForgeManager; import engine.gameManager.ForgeManager;
import engine.mbEnums; import engine.mbEnums;
import engine.objects.Item; import engine.objects.Item;
import engine.objects.ItemTemplate;
import engine.objects.NPC; import engine.objects.NPC;
import engine.objects.Warehouse; import engine.objects.Warehouse;
import engine.parsers.objects.CObjectTemplate;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
@@ -127,16 +127,16 @@ public class WorkOrder implements Delayed {
int validation_result = 0; int validation_result = 0;
CObjectTemplate template = CObjectTemplate.lookup(workOrder.templateID); ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
if (workOrder.vendor.getBuilding() == null) if (workOrder.vendor.getBuilding() == null)
return 58; //58: The formula is beyond the means of this facility return 58; //58: The formula is beyond the means of this facility
if (!workOrder.vendor.charItemManager.hasRoomInventory(template.getItemWt())) if (!workOrder.vendor.charItemManager.hasRoomInventory(template.item_wt))
return 30; //30: That person cannot carry that item return 30; //30: That person cannot carry that item
if ((workOrder.prefixToken != 0 || workOrder.suffixToken != 0) && if ((workOrder.prefixToken != 0 || workOrder.suffixToken != 0) &&
!workOrder.vendor.getItemModTable().contains(ForgeManager.getVendorModTable(workOrder.templateID))) !workOrder.vendor.getItemModTable().contains((template.modTable)))
return 59; //59: This hireling does not have this formula return 59; //59: This hireling does not have this formula
if (!Warehouse.calcCostOverrun(workOrder).isEmpty()) if (!Warehouse.calcCostOverrun(workOrder).isEmpty())
+30
View File
@@ -583,6 +583,36 @@ final public class FastMath {
return ret.normalize(); return ret.normalize();
} }
/**
* Turns a String into an Integer hash that the client will recognize.
*
* @param s The String to hash
* @return the Integer hash
*/
public static int hash(String s) {
int out = 0, pad = 0;
for (char c : s.toCharArray()) {
if (c == ' ' || c == '\\') {
pad += 5;
continue;
}
if (c > 0x40 && c < 0x60)
out ^= _rotl((byte) 0x60, pad);
out ^= _rotl((byte) (c & 0xDF), pad);
pad += 5;
}
return out;
}
/**
* Utility function for making hashes
*/
private static int _rotl(int value, int shift) {
if ((shift &= 31) == 0)
return value;
return (value << shift) | (value >> (32 - shift));
}
/** /**
* Gets number of seconds until next hours * Gets number of seconds until next hours
*/ */
+40 -91
View File
@@ -15,10 +15,10 @@ import engine.math.Vector2f;
import engine.math.Vector3f; import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.objects.AbstractCharacter; import engine.objects.AbstractCharacter;
import engine.objects.ItemTemplate;
import engine.objects.Shrine; import engine.objects.Shrine;
import engine.objects.Zone; import engine.objects.Zone;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import engine.powers.RunePowerEntry;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
@@ -824,7 +824,6 @@ public class mbEnums {
ACID, ACID,
DISEASE, DISEASE,
UNKNOWN, UNKNOWN,
ANTISIEGE,
// these added for immunities // these added for immunities
ATTACK, ATTACK,
POWERS, POWERS,
@@ -843,26 +842,34 @@ public class mbEnums {
public static DamageType getDamageType(String modName) { public static DamageType getDamageType(String modName) {
String name;
if (modName.isEmpty()) if (modName.isEmpty())
return DamageType.NONE; return DamageType.NONE;
// Client and DB strings vary in case and punctuation ("Fire", "Anti-Siege") if(modName.toLowerCase().equals("blind"))
modName = "BLINDNESS";
name = modName.replaceAll("[\\s,-]", "").toUpperCase(); if(modName.toLowerCase().equals("powerblock"))
modName = "POWERINHIBITOR";
if (name.equals("BLIND")) //validity check for not looking up damage type that doesn't exist
name = "BLINDNESS"; boolean valid = false;
for(DamageType type : DamageType.values()){
if(type.name().equals(modName))
valid = true;
}
if (name.equals("POWERBLOCK")) if(!valid)
name = "POWERINHIBITOR"; return DamageType.NONE;
for (DamageType type : DamageType.values()) DamageType damageType;
if (type.name().equals(name))
return type;
return DamageType.NONE; try {
damageType = DamageType.valueOf(modName.replace(",", "").toUpperCase());
} catch (Exception e) {
Logger.error(e);
return DamageType.NONE;
}
return damageType;
} }
} }
@@ -1097,28 +1104,11 @@ public class mbEnums {
public static EffectSourceType GetEffectSourceType(String modName) { public static EffectSourceType GetEffectSourceType(String modName) {
EffectSourceType returnMod; EffectSourceType returnMod;
String name;
if (modName.isEmpty()) if (modName.isEmpty())
return EffectSourceType.None; return EffectSourceType.None;
name = modName.replace(",", "").replace("-", "").trim();
// Effects.cfg SOURCE blocks use the short damage names
switch (name) {
case "Crush":
name = "Crushing";
break;
case "Pierce":
name = "Piercing";
break;
case "Slash":
name = "Slashing";
break;
}
try { try {
returnMod = EffectSourceType.valueOf(name); returnMod = EffectSourceType.valueOf(modName.replace(",", ""));
} catch (Exception e) { } catch (Exception e) {
Logger.error(e); Logger.error(e);
return EffectSourceType.None; return EffectSourceType.None;
@@ -1148,7 +1138,6 @@ public class mbEnums {
BMHealing, BMHealing,
Charm, Charm,
ClassBoon, ClassBoon,
ColdDeBuff,
Confusion, Confusion,
DamageAbsorber, DamageAbsorber,
DamageDebuff, DamageDebuff,
@@ -1163,7 +1152,6 @@ public class mbEnums {
ElementalDeBuff, ElementalDeBuff,
EnchantWeapon, EnchantWeapon,
Fear, Fear,
FireDeBuff,
Flight, Flight,
Frenzy, Frenzy,
GroupHeal, GroupHeal,
@@ -1171,16 +1159,12 @@ public class mbEnums {
HealOverTime, HealOverTime,
HealResBuff, HealResBuff,
HealthPotion, HealthPotion,
HolyDeBuff,
IgnoreStack, IgnoreStack,
Invisible, Invisible,
LightningDeBuff,
MagicDeBuff,
ManaPotion, ManaPotion,
MangonelFire, MangonelFire,
MeleeDamageDeBuff, MeleeDamageDeBuff,
MeleeDeBuff, MeleeDeBuff,
MentalDeBuff,
MoveBuff, MoveBuff,
MoveDebuff, MoveDebuff,
NoFear, NoFear,
@@ -1193,9 +1177,6 @@ public class mbEnums {
NoTrack, NoTrack,
PassiveDefense, PassiveDefense,
PersAttrSPRBuff, PersAttrSPRBuff,
PersonalAttrCONBuff,
PersonalAttrDEXBuff,
PersonalAttrSTRBuff,
PetBuff, PetBuff,
PierceResistanceDebuff, PierceResistanceDebuff,
PoisonBuchinine, PoisonBuchinine,
@@ -1218,6 +1199,7 @@ public class mbEnums {
RecoveryStaminaDeBuff, RecoveryStaminaDeBuff,
ResistanceBuff, ResistanceBuff,
ResistanceDeBuff, ResistanceDeBuff,
ResistanceDebuff,
Root, Root,
SafeMode, SafeMode,
SelfOneAttrBuff, SelfOneAttrBuff,
@@ -1241,7 +1223,6 @@ public class mbEnums {
Stun, Stun,
Track, Track,
Transform, Transform,
UnholyDeBuff,
WeaponMove; WeaponMove;
public static StackType GetStackType(String modName) { public static StackType GetStackType(String modName) {
@@ -1528,15 +1509,6 @@ public class mbEnums {
} }
} }
// rune_type values from the client cache data (COBJECTS/RUNE)
public enum RuneType {
CLASS,
DISCIPLINE,
RACE,
TALENT
}
public enum ShrineType { public enum ShrineType {
Aelfborn(1701900, -75506007, true), Aelfborn(1701900, -75506007, true),
@@ -2660,61 +2632,55 @@ public class mbEnums {
public enum MinionType { public enum MinionType {
AELFBORNGUARD(951, 1637, MinionClass.MELEE, "Guard", "Aelfborn"), AELFBORNGUARD(951, 1637, MinionClass.MELEE, "Guard", "Aelfborn"),
AELFBORNMAGE(952, 1635, MinionClass.MAGE, "Adept", "Aelfborn", "WIZ-016", "WIZ-061", "WIZ-025", "WIZ-020"), AELFBORNMAGE(952, 1635, MinionClass.MAGE, "Adept", "Aelfborn"),
AMAZONGUARD(1500, 1670, MinionClass.MELEE, "Guard", "Amazon"), AMAZONGUARD(1500, 1670, MinionClass.MELEE, "Guard", "Amazon"),
AMAZONMAGE(1502, 1638, MinionClass.MAGE, "Fury", "Amazon", "FUR-003", "FUR-011", "FUR-009", "FUR-005"), AMAZONMAGE(1502, 1638, MinionClass.MAGE, "Fury", "Amazon"),
ARACOIXGUARD(1600, 1672, MinionClass.MELEE, "Guard", "Aracoix"), //used guard captain equipset. ARACOIXGUARD(1600, 1672, MinionClass.MELEE, "Guard", "Aracoix"), //used guard captain equipset.
ARACOIXMAGE(1602, 885, MinionClass.MAGE, "Adept", "Aracoix", "WLR-029", "WLR-019", "WLR-027", "WLR-012"), ARACOIXMAGE(1602, 885, MinionClass.MAGE, "Adept", "Aracoix"),
CENTAURGUARD(1650, 1642, MinionClass.MELEE, "Guard", "Centaur"), CENTAURGUARD(1650, 1642, MinionClass.MELEE, "Guard", "Centaur"),
CENTAURMAGE(1652, 1640, MinionClass.MAGE, "Druid", "Centaur", "PRL-017", "PRL-046", "PRL-033", "PRL-009"), CENTAURMAGE(1652, 1640, MinionClass.MAGE, "Druid", "Centaur"),
DWARVENARCHER(845, 1644, MinionClass.ARCHER, "Marksman", "Dwarven"), DWARVENARCHER(845, 1644, MinionClass.ARCHER, "Marksman", "Dwarven"),
DWARVENGUARD(1050, 1666, MinionClass.MELEE, "Guard", "Dwarven"), DWARVENGUARD(1050, 1666, MinionClass.MELEE, "Guard", "Dwarven"),
DWARVENMAGE(1052, 1643, MinionClass.MAGE, "War Priest", "Dwarven", "PRL-017", "PRL-046", "PRL-033", "PRL-009"), DWARVENMAGE(1052, 1643, MinionClass.MAGE, "War Priest", "Dwarven"),
ELFGUARD(1180, 1671, MinionClass.MELEE, "Guard", "Elven"), //old 1645 ELFGUARD(1180, 1671, MinionClass.MELEE, "Guard", "Elven"), //old 1645
ELFMAGE(1182, 1667, MinionClass.MAGE, "Adept", "Elven", "WIZ-020", "WIZ-025", "WIZ-016", "WIZ-061"), ELFMAGE(1182, 1667, MinionClass.MAGE, "Adept", "Elven"),
FORESTGUARD(1550, 1668, MinionClass.MELEE, "Guard", "Forest"), //captain changed to guard equipset FORESTGUARD(1550, 1668, MinionClass.MELEE, "Guard", "Forest"), //captain changed to guard equipset
FORESTMAGE(1552, 436, MinionClass.MAGE, "Adept", "Forest", "DRU-009", "DRU-023", "DRU-036", "DRU-015"), FORESTMAGE(1552, 436, MinionClass.MAGE, "Adept", "Forest"),
HOLYGUARD(1525, 1658, MinionClass.MELEE, "Guard", "Holy Church"), HOLYGUARD(1525, 1658, MinionClass.MELEE, "Guard", "Holy Church"),
HOLYMAGE(1527, 1646, MinionClass.MAGE, "Prelate", "Holy Church", "PRL-017", "PRL-046", "PRL-033", "PRL-009"), HOLYMAGE(1527, 1646, MinionClass.MAGE, "Prelate", "Holy Church"),
HUMANARCHER(846, 1654, MinionClass.ARCHER, "Archer", "Human"), HUMANARCHER(846, 1654, MinionClass.ARCHER, "Archer", "Human"),
HUMANGUARD(840, 1665, MinionClass.MELEE, "Guard", "Human"), HUMANGUARD(840, 1665, MinionClass.MELEE, "Guard", "Human"),
HUMANMAGE(848, 1655, MinionClass.MAGE, "Adept", "Human", "WIZ-016", "WIZ-025", "WIZ-020", "WIZ-061"), HUMANMAGE(848, 1655, MinionClass.MAGE, "Adept", "Human"),
IREKEIGUARD(1350, 1659, MinionClass.MELEE, "Guard", "Irekei"), IREKEIGUARD(1350, 1659, MinionClass.MELEE, "Guard", "Irekei"),
IREKEIMAGE(1352, 1660, MinionClass.MAGE, "Adept", "Irekei", "WIZ-061", "WIZ-016", "WIZ-025", "WIZ-020"), IREKEIMAGE(1352, 1660, MinionClass.MAGE, "Adept", "Irekei"),
MINOTAURARCHER(1701, 0, MinionClass.ARCHER, "Archer", "Minotaur"), MINOTAURARCHER(1701, 0, MinionClass.ARCHER, "Archer", "Minotaur"),
MINOTAURGUARD(1700, 1673, MinionClass.MELEE, "Guard", "Minotaur"), MINOTAURGUARD(1700, 1673, MinionClass.MELEE, "Guard", "Minotaur"),
NORTHMANGUARD(1250, 1669, MinionClass.MELEE, "Guard", "Northman"), NORTHMANGUARD(1250, 1669, MinionClass.MELEE, "Guard", "Northman"),
NORTHMANMAGE(1252, 1650, MinionClass.MAGE, "Runecaster", "Northman", "WIZ-061", "WIZ-016", "WIZ-025", "WIZ-020"), NORTHMANMAGE(1252, 1650, MinionClass.MAGE, "Runecaster", "Northman"),
SHADEGUARD(1450, 1662, MinionClass.MELEE, "Guard", "Shade"), SHADEGUARD(1450, 1662, MinionClass.MELEE, "Guard", "Shade"),
SHADEMAGE(1452, 1664, MinionClass.MAGE, "Adept", "Shade", "NEC-001", "NEC-003", "MAG-013", "MAG-025"), SHADEMAGE(1452, 1664, MinionClass.MAGE, "Adept", "Shade"),
TEMPLARGUARD(841, 1564, MinionClass.MELEE, "Marksman", "Templar"), TEMPLARGUARD(841, 1564, MinionClass.MELEE, "Marksman", "Templar"),
TEMPLEGUARD(1575, 1652, MinionClass.MELEE, "Guard", "Temple"), TEMPLEGUARD(1575, 1652, MinionClass.MELEE, "Guard", "Temple"),
TEMPLEMAGE(1577, 1656, MinionClass.MAGE, "Confessor", "Temple", "CON-048", "CON-015", "CON-012", "CON-051"), TEMPLEMAGE(1577, 1656, MinionClass.MAGE, "Confessor", "Temple"),
UNDEADGUARD(980100, 1674, MinionClass.MELEE, "Guard", "Undead"), UNDEADGUARD(980100, 1674, MinionClass.MELEE, "Guard", "Undead"),
UNDEADMAGE(980102, 1675, MinionClass.MAGE, "Adept", "Undead", "NEC-001", "NEC-003", "MAG-013", "MAG-025"), UNDEADMAGE(980102, 1675, MinionClass.MAGE, "Adept", "Undead"),
WEREWOLFGUARD(980104, 0, MinionClass.MELEE, "Guard", "Werewolf"), WEREWOLFGUARD(980104, 0, MinionClass.MELEE, "Guard", "Werewolf"),
WEREBEARGUARD(980103, 0, MinionClass.MELEE, "Guard", "Werebear"); WEREBEARGUARD(980103, 0, MinionClass.MELEE, "Guard", "Werebear");
public static HashMap<Integer, MinionType> ContractToMinionMap = new HashMap<>(); public static HashMap<Integer, MinionType> ContractToMinionMap = new HashMap<>();
private static final int CAPTAIN_POWER_RANK = 40;
private final int captainContractID; private final int captainContractID;
private final int equipSetID; private final int equipSetID;
private final MinionClass minionClass; private final MinionClass minionClass;
private final String name; private final String name;
private final String race; private final String race;
private final ArrayList<RunePowerEntry> captainPowers;
// Captain powers were hand-made by the server team; no client rune or deed lists them MinionType(int captainContractID, int equipSetID, MinionClass minionClass, String name, String race) {
MinionType(int captainContractID, int equipSetID, MinionClass minionClass, String name, String race, String... captainPowerTypes) {
this.captainContractID = captainContractID; this.captainContractID = captainContractID;
this.equipSetID = equipSetID; this.equipSetID = equipSetID;
this.minionClass = minionClass; this.minionClass = minionClass;
this.name = name; this.name = name;
this.race = race; this.race = race;
this.captainPowers = new ArrayList<>();
for (String powerType : captainPowerTypes)
this.captainPowers.add(new RunePowerEntry(race + " " + name, powerType, CAPTAIN_POWER_RANK));
} }
public static void InitializeMinions() { public static void InitializeMinions() {
@@ -2723,17 +2689,6 @@ public class mbEnums {
ContractToMinionMap.put(minionType.captainContractID, minionType); ContractToMinionMap.put(minionType.captainContractID, minionType);
} }
// The powers a guard captain's contract casts, shared by its minions; empty for non-caster contracts
public static ArrayList<RunePowerEntry> getCaptainPowers(int captainContractID) {
MinionType minionType = ContractToMinionMap.get(captainContractID);
if (minionType == null)
return new ArrayList<>();
return minionType.captainPowers;
}
public String getName() { public String getName() {
return name; return name;
} }
@@ -2806,6 +2761,7 @@ public class mbEnums {
public static HashMap<Integer, ResourceType> templateHashLookup = new HashMap<>(); public static HashMap<Integer, ResourceType> templateHashLookup = new HashMap<>();
public static HashMap<Integer, ResourceType> resourceHashLookup = new HashMap<>(); public static HashMap<Integer, ResourceType> resourceHashLookup = new HashMap<>();
public int templateID; public int templateID;
public ItemTemplate template;
public int resourceHash; public int resourceHash;
public int templateHash; public int templateHash;
public int deposit_limit; public int deposit_limit;
@@ -2813,6 +2769,7 @@ public class mbEnums {
ResourceType(int templateID, int resourceHash, int templateHash, int deposit_limit, int mine_production) { ResourceType(int templateID, int resourceHash, int templateHash, int deposit_limit, int mine_production) {
this.templateID = templateID; this.templateID = templateID;
this.template = ItemTemplate.templates.get(this.templateID);
this.resourceHash = resourceHash; this.resourceHash = resourceHash;
this.templateHash = templateHash; this.templateHash = templateHash;
this.deposit_limit = deposit_limit; this.deposit_limit = deposit_limit;
@@ -2951,14 +2908,6 @@ public class mbEnums {
EMPTY_NEWITEM; EMPTY_NEWITEM;
} }
// Cache JSON names. UNKNOWN is raw 0, which the client treats as no slot (sb.exe 0x4AC810).
public enum SheathSlot {
UNKNOWN,
BACK,
WAIST,
NONE
}
public enum AttributeType { public enum AttributeType {
None, None,
Strength, Strength,
+89 -79
View File
@@ -14,12 +14,13 @@ import engine.gameManager.*;
import engine.math.Vector3f; import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.DispatchChannel;
import engine.mobileAI.Threads.MobAIThread; import engine.mobileAI.Threads.MobAIThread;
import engine.mobileAI.Threads.ReSpawner; import engine.mobileAI.Threads.ReSpawner;
import engine.mobileAI.utilities.MovementUtilities; import engine.mobileAI.utilities.MovementUtilities;
import engine.net.client.msg.PerformActionMsg; import engine.net.client.msg.PerformActionMsg;
import engine.net.client.msg.PowerProjectileMsg;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.RuneTemplate;
import engine.powers.ActionsBase; import engine.powers.ActionsBase;
import engine.powers.PowersBase; import engine.powers.PowersBase;
import engine.powers.RunePowerEntry; import engine.powers.RunePowerEntry;
@@ -45,13 +46,6 @@ public class MobAI {
// //
// CombatManager.class implements shared combat routines for all avatars. // CombatManager.class implements shared combat routines for all avatars.
// Pet aggro scan in checkForAggro stays off until it checks rune enemy lists,
// filters its targets and keeps pet targets (MBDATA/docs/plan-mask-pet.md steps 2-4).
private static final boolean PET_AGGRO_ENABLED = false;
private static final int STANDING_GUARD_RUNE_ID = 252623;
private static void attackTarget(Mob mob, AbstractWorldObject target) { private static void attackTarget(Mob mob, AbstractWorldObject target) {
try { try {
@@ -99,7 +93,7 @@ public class MobAI {
mob.updateLocation(); mob.updateLocation();
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
} }
} }
@@ -118,9 +112,7 @@ public class MobAI {
if (mob.behaviourType.callsForHelp) if (mob.behaviourType.callsForHelp)
mobCallForHelp(mob); mobCallForHelp(mob);
// siege engines drop targets on their own attack range in determineAction if (!MovementUtilities.inRangeDropAggro(mob, target)) {
if (!mob.isSiege() && !MovementUtilities.inRangeDropAggro(mob, target)) {
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
} }
@@ -141,7 +133,7 @@ public class MobAI {
target.getPet().setCombatTarget(mob); target.getPet().setCombatTarget(mob);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackPlayer"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackPlayer" + " " + e.getMessage());
} }
} }
@@ -163,10 +155,20 @@ public class MobAI {
if (guard.getCombatTarget() == null && !guard.getGuild().equals(mob.getGuild())) if (guard.getCombatTarget() == null && !guard.getGuild().equals(mob.getGuild()))
guard.setCombatTarget(mob); guard.setCombatTarget(mob);
if (mob.isSiege())
MovementManager.sendRWSSMsg(mob);
CombatManager.combatCycle(mob, target); CombatManager.combatCycle(mob, target);
if (mob.isSiege()) {
PowerProjectileMsg ppm = new PowerProjectileMsg(mob, target);
ppm.setRange(50);
DispatchManager.dispatchMsgToInterestArea(mob, ppm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
}
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackBuilding"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackBuilding" + " " + e.getMessage());
} }
} }
@@ -184,7 +186,7 @@ public class MobAI {
CombatManager.combatCycle(mob, target); CombatManager.combatCycle(mob, target);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackMob"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackMob" + " " + e.getMessage());
} }
} }
@@ -246,7 +248,7 @@ public class MobAI {
MovementUtilities.aiMove(mob, mob.destination, true); MovementUtilities.aiMove(mob, mob.destination, true);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: Patrol"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
} }
} }
@@ -279,7 +281,7 @@ public class MobAI {
// Mobile has no powers defined in mobbase or contract.. // Mobile has no powers defined in mobbase or contract..
if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() && mbEnums.MinionType.getCaptainPowers(contractID).isEmpty()) if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() && PowersManager.getPowersForRune(contractID).isEmpty())
return false; return false;
if (mob.nextCastTime == 0) if (mob.nextCastTime == 0)
@@ -288,7 +290,7 @@ public class MobAI {
return mob.nextCastTime <= System.currentTimeMillis(); return mob.nextCastTime <= System.currentTimeMillis();
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: canCast"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: canCast" + " " + e.getMessage());
} }
return false; return false;
} }
@@ -312,17 +314,18 @@ public class MobAI {
powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID())); powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
purgeEntries = new ArrayList<>(); purgeEntries = new ArrayList<>();
// Player guards also cast their captain contract's powers, irrespective of the mobbase used. // Additional powers may come from the contract ID. This is to support
// powers for player guards irrespective of the mobbase used.
if (mob.isPlayerGuard()) { if (mob.isPlayerGuard()) {
ArrayList<RunePowerEntry> contractEntries = new ArrayList<>(); ArrayList<RunePowerEntry> contractEntries = new ArrayList<>();
if (mob.contract != null) if (mob.contract != null)
contractEntries = mbEnums.MinionType.getCaptainPowers(mob.contractUUID); contractEntries = PowersManager.getPowersForRune(mob.contractUUID);
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION)) if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION))
contractEntries = mbEnums.MinionType.getCaptainPowers(mob.guardCaptain.contractUUID); contractEntries = PowersManager.getPowersForRune(mob.guardCaptain.contractUUID);
powerEntries.addAll(contractEntries); powerEntries.addAll(contractEntries);
@@ -359,7 +362,7 @@ public class MobAI {
int powerRank = runePowerEntry.rank; int powerRank = runePowerEntry.rank;
if (mob.isPlayerGuard()) if (mob.isPlayerGuard())
powerRank = getGuardPowerRank(mob, mobPower); powerRank = getGuardPowerRank(mob);
// Cast the spell // Cast the spell
@@ -384,32 +387,38 @@ public class MobAI {
return true; return true;
} }
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
} }
return false; return false;
} }
// Client power rank adds every POWERSADJ step at or below the level (0x4B34B0). The Standing Guard rune's public static int getGuardPowerRank(Mob mob) {
// Wizard steps are the curve for every captain spell, capped at MaxLevel as player casts are. int powerRank = 1;
public static int getGuardPowerRank(Mob mob, PowersBase power) {
RuneTemplate guardRune = RuneTemplate._runes.get(STANDING_GUARD_RUNE_ID); switch (mob.getRank()) {
ArrayList<int[]> rankSteps; case 1:
int powerRank = 0; powerRank = 10;
break;
if (guardRune == null || guardRune.item_power_action.isEmpty()) case 2:
return 1; powerRank = 15;
break;
rankSteps = guardRune.item_power_action.get(power.getIDString()); case 3:
powerRank = 20;
if (rankSteps == null) break;
rankSteps = guardRune.item_power_action.values().iterator().next(); case 4:
powerRank = 25;
for (int[] rankStep : rankSteps) break;
if (rankStep[1] <= mob.getLevel()) case 5:
powerRank += rankStep[0]; powerRank = 30;
break;
return Math.max(1, Math.min(powerRank, power.getMaxTrains())); case 6:
powerRank = 35;
break;
case 7:
powerRank = 40;
break;
}
return powerRank;
} }
public static void mobCallForHelp(Mob mob) { public static void mobCallForHelp(Mob mob) {
@@ -443,7 +452,7 @@ public class MobAI {
mob.nextCallForHelp = System.currentTimeMillis() + 60000; mob.nextCallForHelp = System.currentTimeMillis() + 60000;
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCallForHelp"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCallForHelp" + " " + e.getMessage());
} }
} }
@@ -466,7 +475,7 @@ public class MobAI {
//trebuchet spawn handler //trebuchet spawn handler
if (mob.despawned && mob.getMobBase().getObjectUUID() == 13171) { if (mob.despawned && mob.getMobBase().getLoadID() == 13171) {
checkForRespawn(mob); checkForRespawn(mob);
return; return;
} }
@@ -509,16 +518,7 @@ public class MobAI {
boolean bypassLoadedPlayerCheck = false; boolean bypassLoadedPlayerCheck = false;
if (mob.isPlayerGuard() || mob.isSiege()) { if (mob.isPlayerGuard() || mob.isSiege()) {
bypassLoadedPlayerCheck = true; bypassLoadedPlayerCheck = true;
if (mob.combatTarget != null && mob.combatTarget.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter))
if (mob.isSiege()) {
// siege engines hold a character target until it dies or leaves their attack range
if (mob.combatTarget != null && AbstractCharacter.IsAbstractCharacter(mob.combatTarget))
if (mob.combatTarget.loc.distanceSquared(mob.loc) > mob.getRange() * mob.getRange())
mob.setCombatTarget(null);
} else if (mob.combatTarget != null && mob.combatTarget.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter))
if (mob.combatTarget.loc.distanceSquared(mob.loc) > 10000) if (mob.combatTarget.loc.distanceSquared(mob.loc) > 10000)
mob.setCombatTarget(null); mob.setCombatTarget(null);
} }
@@ -544,7 +544,7 @@ public class MobAI {
PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget(); PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget();
if (!mob.isSiege() && !mob.playerAgroMap.containsKey(target.getObjectUUID())) { if (!mob.playerAgroMap.containsKey(target.getObjectUUID())) {
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
} }
@@ -575,7 +575,7 @@ public class MobAI {
break; break;
} }
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: DetermineAction"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DetermineAction" + " " + e.getMessage());
} }
} }
@@ -630,7 +630,7 @@ public class MobAI {
} }
} }
if (PET_AGGRO_ENABLED && aiAgent.getCombatTarget() == null) { if (aiAgent.getCombatTarget() == null) {
//look for pets to aggro if no players found to aggro //look for pets to aggro if no players found to aggro
@@ -649,7 +649,7 @@ public class MobAI {
} }
} }
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForAggro"); Logger.info(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForAggro" + " " + e.getMessage());
} }
} }
@@ -702,7 +702,7 @@ public class MobAI {
} }
} }
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckMobMovement"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckMobMovement" + " " + e.getMessage());
} }
} }
@@ -746,7 +746,7 @@ public class MobAI {
ReSpawner.respawnQueue.put(aiAgent); ReSpawner.respawnQueue.put(aiAgent);
} }
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForRespawn"); Logger.info(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForRespawn" + " " + e.getMessage());
} }
} }
@@ -761,7 +761,7 @@ public class MobAI {
if (mob.getCombatTarget() == null) if (mob.getCombatTarget() == null)
return; return;
if (mob.getCombatTarget().getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && !MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) && !mob.agentType.equals(mbEnums.AIAgentType.PET) && !mob.isSiege()) { if (mob.getCombatTarget().getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && !MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) && !mob.agentType.equals(mbEnums.AIAgentType.PET)) {
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
@@ -769,7 +769,7 @@ public class MobAI {
attackTarget(mob, mob.getCombatTarget()); attackTarget(mob, mob.getCombatTarget());
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForAttack"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForAttack" + " " + e.getMessage());
} }
} }
@@ -812,7 +812,7 @@ public class MobAI {
mob.playerAgroMap.replaceAll((e, v) -> 0f); mob.playerAgroMap.replaceAll((e, v) -> 0f);
} }
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage());
} }
} }
@@ -851,7 +851,7 @@ public class MobAI {
mob.updateMovementState(); mob.updateMovementState();
mob.updateLocation(); mob.updateLocation();
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: chaseTarget"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: chaseTarget" + " " + e.getMessage());
} }
} }
@@ -877,17 +877,13 @@ public class MobAI {
if (aggroMob.agentType.equals(mbEnums.AIAgentType.PET)) if (aggroMob.agentType.equals(mbEnums.AIAgentType.PET))
continue; continue;
//don't attack siege engines
if (aggroMob.isSiege())
continue;
if (mob.getLoc().distanceSquared2D(aggroMob.getLoc()) > sqr(50)) if (mob.getLoc().distanceSquared2D(aggroMob.getLoc()) > sqr(50))
continue; continue;
mob.setCombatTarget(aggroMob); mob.setCombatTarget(aggroMob);
} }
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: SafeGuardAggro"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: SafeGuardAggro" + " " + e.getMessage());
} }
} }
@@ -917,7 +913,7 @@ public class MobAI {
checkForAttack(mob); //only check to attack if combat target is not null checkForAttack(mob); //only check to attack if combat target is not null
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardLogic"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardLogic" + " " + e.getMessage());
} }
} }
@@ -950,7 +946,7 @@ public class MobAI {
mob.setHealth(mob.getHealthMax()); mob.setHealth(mob.getHealthMax());
} }
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: PetLogic"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: PetLogic" + " " + e.getMessage());
} }
} }
@@ -974,7 +970,7 @@ public class MobAI {
} }
checkForAttack(mob); checkForAttack(mob);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: HamletGuardLogic"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: HamletGuardLogic" + " " + e.getMessage());
} }
} }
@@ -1047,7 +1043,7 @@ public class MobAI {
checkForAttack(mob); checkForAttack(mob);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: DefaultLogic"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DefaultLogic" + " " + e.getMessage());
} }
} }
@@ -1103,11 +1099,25 @@ public class MobAI {
return; return;
} }
} }
if (mob.getCombatTarget() == null) {
// guards never auto-aggro siege engines; they only respond when one damages a city building //look for siege equipment to aggro if no players found to aggro
HashSet<AbstractWorldObject> awoList = WorldGrid.getObjectsInRangePartial(mob, MobAIThread.AI_BASE_AGGRO_RANGE, MBServerStatics.MASK_SIEGE);
for (AbstractWorldObject awoMob : awoList) {
Mob aggroMob = (Mob) awoMob;
if (guardCanAggro(mob, aggroMob)) {
mob.setCombatTarget(aggroMob);
return;
}
}
}
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForPlayerGuardAggro"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForPlayerGuardAggro" + e.getMessage());
} }
} }
@@ -1170,7 +1180,7 @@ public class MobAI {
} }
} }
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCanAggro"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCanAggro" + " " + e.getMessage());
} }
return false; return false;
} }
@@ -1222,7 +1232,7 @@ public class MobAI {
} }
} }
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints" + " " + e);
} }
} }
@@ -1257,7 +1267,7 @@ public class MobAI {
} }
return mostHatedTarget; return mostHatedTarget;
} catch (Exception e) { } catch (Exception e) {
Logger.error(e, mob.getObjectUUID() + " " + mob.getName() + " Failed At: ChangeTargetFromMostHated"); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: ChangeTargetFromMostHated" + " " + e.getMessage());
} }
return null; return null;
} }
+9 -8
View File
@@ -12,7 +12,8 @@ package engine.net;
import engine.math.Vector3f; import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.util.ByteBufferUtils; import engine.util.ByteBufferUtils;
import org.joda.time.DateTime; import java.time.Instant;
import java.time.ZoneId;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@@ -57,13 +58,13 @@ public class ByteBufferWriter {
this.bb.putLong(x); this.bb.putLong(x);
} }
public synchronized void putDateTime(DateTime dateTime) { public synchronized void putDateTime(Instant dateTime) {
this.put((byte) dateTime.getDayOfMonth()); this.put((byte) dateTime.atZone(ZoneId.systemDefault()).toLocalDate().getDayOfMonth());
this.put((byte) ((byte) dateTime.getMonthOfYear() - 1)); this.put((byte) ((byte) dateTime.atZone(ZoneId.systemDefault()).toLocalDate().getMonthValue() - 1));
this.putInt(dateTime.getYear() - 1900); this.putInt(dateTime.atZone(ZoneId.systemDefault()).toLocalDate().getYear() - 1900);
this.put((byte) dateTime.getHourOfDay()); this.put((byte) dateTime.atZone(ZoneId.systemDefault()).toLocalTime().getHour());
this.put((byte) dateTime.getMinuteOfHour()); this.put((byte) dateTime.atZone(ZoneId.systemDefault()).toLocalTime().getMinute());
this.put((byte) dateTime.getSecondOfDay()); this.put((byte) dateTime.atZone(ZoneId.systemDefault()).toLocalTime().getSecond());
} }
public synchronized void putLocalDateTime(LocalDateTime dateTime) { public synchronized void putLocalDateTime(LocalDateTime dateTime) {
+2 -2
View File
@@ -14,7 +14,7 @@ import engine.gameManager.ChatManager;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.joda.time.DateTime; import java.time.Instant;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
@@ -85,7 +85,7 @@ public class NetMsgFactory {
if (protocolMsg == Protocol.NONE) { if (protocolMsg == Protocol.NONE) {
String errorString = DateTime.now().toString() + origin.lastProtocol.name(); String errorString = Instant.now().toString() + origin.lastProtocol.name();
int errorCode = errorString.hashCode(); int errorCode = errorString.hashCode();
@@ -22,7 +22,7 @@ import engine.net.client.msg.guild.GuildInfoMsg;
import engine.objects.Guild; import engine.objects.Guild;
import engine.objects.GuildHistory; import engine.objects.GuildHistory;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import org.joda.time.DateTime; import java.time.Instant;
public class AcceptInviteToGuildHandler extends AbstractClientMsgHandler { public class AcceptInviteToGuildHandler extends AbstractClientMsgHandler {
@@ -90,8 +90,8 @@ public class AcceptInviteToGuildHandler extends AbstractClientMsgHandler {
//Add to guild History //Add to guild History
if (player.getGuild() != null) { if (player.getGuild() != null) {
if (DbManager.GuildQueries.ADD_TO_GUILDHISTORY(player.getGuildUUID(), player, DateTime.now(), GuildHistoryType.JOIN)) { if (DbManager.GuildQueries.ADD_TO_GUILDHISTORY(player.getGuildUUID(), player, Instant.now(), GuildHistoryType.JOIN)) {
GuildHistory guildHistory = new GuildHistory(player.getGuildUUID(), player.getGuild().getName(), DateTime.now(), GuildHistoryType.JOIN); GuildHistory guildHistory = new GuildHistory(player.getGuildUUID(), player.getGuild().getName(), Instant.now(), GuildHistoryType.JOIN);
player.getGuildHistory().add(guildHistory); player.getGuildHistory().add(guildHistory);
} }
} }
@@ -46,7 +46,7 @@ public class ActivateNPCMsgHandler extends AbstractClientMsgHandler {
// Filter hirelings by slot type // Filter hirelings by slot type
for (Item hirelings : player.getInventory()) { for (Item hirelings : player.getInventory()) {
if (hirelings.template.getItemType().equals(ItemType.EMPLOYMENTCONTRACT)) { if (hirelings.template.item_type.equals(ItemType.EMPLOYMENTCONTRACT)) {
contract = DbManager.ContractQueries.GET_CONTRACT(hirelings.templateID); contract = DbManager.ContractQueries.GET_CONTRACT(hirelings.templateID);
@@ -78,7 +78,7 @@ public class AddItemToTradeWindowMsgHandler extends AbstractClientMsgHandler {
if (!item.validForInventory(source.getClientConnection(), source, source.charItemManager)) if (!item.validForInventory(source.getClientConnection(), source, source.charItemManager))
return false; return false;
if (!tradingWith.hasRoomTrade(item.template.getItemWt())) { if (!tradingWith.hasRoomTrade(item.template.item_wt)) {
dispatch = Dispatch.borrow(source, msg); dispatch = Dispatch.borrow(source, msg);
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
return false; return false;
@@ -25,7 +25,7 @@ import engine.objects.Guild;
import engine.objects.GuildHistory; import engine.objects.GuildHistory;
import engine.objects.GuildStatusController; import engine.objects.GuildStatusController;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import org.joda.time.DateTime; import java.time.Instant;
public class BanishUnbanishHandler extends AbstractClientMsgHandler { public class BanishUnbanishHandler extends AbstractClientMsgHandler {
@@ -95,8 +95,8 @@ public class BanishUnbanishHandler extends AbstractClientMsgHandler {
//Set guild history //Set guild history
if (DbManager.GuildQueries.ADD_TO_GUILDHISTORY(guild.getObjectUUID(), toBanish, DateTime.now(), GuildHistoryType.BANISHED)) { if (DbManager.GuildQueries.ADD_TO_GUILDHISTORY(guild.getObjectUUID(), toBanish, Instant.now(), GuildHistoryType.BANISHED)) {
GuildHistory guildHistory = new GuildHistory(toBanish.getGuildUUID(), toBanish.getGuild().getName(), DateTime.now(), GuildHistoryType.BANISHED); GuildHistory guildHistory = new GuildHistory(toBanish.getGuildUUID(), toBanish.getGuild().getName(), Instant.now(), GuildHistoryType.BANISHED);
toBanish.getGuildHistory().add(guildHistory); toBanish.getGuildHistory().add(guildHistory);
} }
} }
@@ -97,13 +97,9 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler {
if (city == null) if (city == null)
return true; return true;
Warehouse.destroyedWarehouses.remove(building.getObjectUUID()); DbManager.WarehouseQueries.DELETE_WAREHOUSE(city.warehouse);
// Rubble no longer owns city.warehouse, which may be null or a newly placed warehouse city.warehouse = null;
if (city.warehouse != null && building.getRank() != -1) {
DbManager.WarehouseQueries.DELETE_WAREHOUSE(city.warehouse);
city.warehouse = null;
}
} }
@@ -24,7 +24,6 @@ import engine.net.client.msg.guild.GuildInfoMsg;
import engine.objects.Guild; import engine.objects.Guild;
import engine.objects.Item; import engine.objects.Item;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import engine.parsers.objects.DeedTemplate;
import engine.util.StringUtils; import engine.util.StringUtils;
public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler { public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
@@ -43,7 +42,6 @@ public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
Guild playerGuild; Guild playerGuild;
Item charter; Item charter;
DeedTemplate charterDeed;
Dispatch dispatch; Dispatch dispatch;
msg = (GuildCreationFinalizeMsg) baseMsg; msg = (GuildCreationFinalizeMsg) baseMsg;
@@ -67,9 +65,7 @@ public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
// Item must be a valid charterType (type 10 in db) // Item must be a valid charterType (type 10 in db)
charterDeed = DeedTemplate._deeds.get(charter.templateID); if (charter == null || (charter.template.item_type.equals(ItemType.CHARTER) == false)) {
if (charterDeed == null || (charterDeed.item_type.equals(ItemType.CHARTER) == false)) {
ErrorPopupMsg.sendErrorPopup(player, GuildManager.NO_CHARTER_FOUND); ErrorPopupMsg.sendErrorPopup(player, GuildManager.NO_CHARTER_FOUND);
return true; return true;
} }
@@ -238,10 +238,10 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
if (targetItem == null) if (targetItem == null)
return; return;
if (targetItem.template.getItemType().equals(ItemType.GOLD)) if (targetItem.template.item_type.equals(ItemType.GOLD))
return; return;
if (!vendor.charItemManager.hasRoomInventory(targetItem.template.getItemWt())) { if (!vendor.charItemManager.hasRoomInventory(targetItem.template.item_wt)) {
ErrorPopupMsg.sendErrorPopup(player, 21); ErrorPopupMsg.sendErrorPopup(player, 21);
return; return;
} }
@@ -319,7 +319,7 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
if (targetItem == null) if (targetItem == null)
continue; continue;
if (targetItem.template.getItemType().equals(ItemType.GOLD)) if (targetItem.template.item_type.equals(ItemType.GOLD))
return; return;
if (!vendor.charItemManager.doesCharOwnThisItem(targetItem.getObjectUUID())) if (!vendor.charItemManager.doesCharOwnThisItem(targetItem.getObjectUUID()))
@@ -328,14 +328,14 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
if (!vendor.charItemManager.inventoryContains(targetItem)) if (!vendor.charItemManager.inventoryContains(targetItem))
continue; continue;
itemValue = targetItem.template.getItemValue(); itemValue = targetItem.template.item_value;
if (vendor.getBuilding().getStrongboxValue() + itemValue > vendor.getBuilding().getMaxGold()) { if (vendor.getBuilding().getStrongboxValue() + itemValue > vendor.getBuilding().getMaxGold()) {
ErrorPopupMsg.sendErrorPopup(player, 201); ErrorPopupMsg.sendErrorPopup(player, 201);
break; break;
} }
switch (targetItem.template.getItemType()) { switch (targetItem.template.item_type) {
case EMPLOYMENTCONTRACT: case EMPLOYMENTCONTRACT:
case CHARTER: case CHARTER:
case DEED: case DEED:
@@ -465,13 +465,13 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
if (targetItem == null) if (targetItem == null)
return; return;
if (targetItem.template.getItemType().equals(ItemType.GOLD)) if (targetItem.template.item_type.equals(ItemType.GOLD))
return; return;
if (!vendor.charItemManager.inventoryContains(targetItem)) if (!vendor.charItemManager.inventoryContains(targetItem))
return; return;
if (!player.charItemManager.hasRoomInventory(targetItem.template.getItemWt())) if (!player.charItemManager.hasRoomInventory(targetItem.template.item_wt))
return; return;
player.charItemManager.buyFromNPC(targetItem, vendor); player.charItemManager.buyFromNPC(targetItem, vendor);
@@ -161,7 +161,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
if (itemRet == null) if (itemRet == null)
return true; return true;
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) { if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
// this is done to prevent the temporary goldItem item // this is done to prevent the temporary goldItem item
// (from the mob) from appearing in player's inventory. // (from the mob) from appearing in player's inventory.
// It also updates the goldItem quantity display // It also updates the goldItem quantity display
@@ -187,7 +187,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
//TODO send group loot message if player is grouped and visible //TODO send group loot message if player is grouped and visible
Group group = GroupManager.getGroup(player); Group group = GroupManager.getGroup(player);
if (group != null && group.getSplitGold() && (item.template.getItemType().equals(mbEnums.ItemType.GOLD) == false)) { if (group != null && group.getSplitGold() && (item.template.item_type.equals(mbEnums.ItemType.GOLD) == false)) {
String name = item.getName(); String name = item.getName();
String text = player.getFirstName() + " has looted " + name + '.'; String text = player.getFirstName() + " has looted " + name + '.';
ChatManager.chatGroupInfoCanSee(player, text); ChatManager.chatGroupInfoCanSee(player, text);
@@ -202,7 +202,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
if (itemRet == null) if (itemRet == null)
return true; return true;
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) { if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
// this is done to prevent the temporary goldItem item // this is done to prevent the temporary goldItem item
// (from the mob) from appearing in player's inventory. // (from the mob) from appearing in player's inventory.
// It also updates the goldItem quantity display // It also updates the goldItem quantity display
@@ -241,7 +241,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
//TODO send group loot message if player is grouped and visible //TODO send group loot message if player is grouped and visible
Group group = GroupManager.getGroup(player); Group group = GroupManager.getGroup(player);
if (group != null && group.getSplitGold() && (item.template.getItemType().equals(mbEnums.ItemType.GOLD) == false)) { if (group != null && group.getSplitGold() && (item.template.item_type.equals(mbEnums.ItemType.GOLD) == false)) {
String name = item.getName(); String name = item.getName();
String text = player.getFirstName() + " has looted " + name + '.'; String text = player.getFirstName() + " has looted " + name + '.';
ChatManager.chatGroupInfoCanSee(player, text); ChatManager.chatGroupInfoCanSee(player, text);
@@ -15,7 +15,7 @@ import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.ManageCityAssetsMsg; import engine.net.client.msg.ManageCityAssetsMsg;
import engine.net.client.msg.PlaceAssetMsg; import engine.net.client.msg.PlaceAssetMsg;
import engine.objects.*; import engine.objects.*;
import org.joda.time.DateTime; import java.time.LocalDateTime;
/* /*
* @Author: * @Author:
@@ -141,9 +141,17 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
return true; return true;
} }
Warehouse warehouse = Warehouse.destroyedWarehouses.get(building.getObjectUUID()); City city = building.getCity();
if (warehouse == null || Warehouse.isEmpty(warehouse)) { if (city == null)
return true;
Warehouse warehouse = city.warehouse;
if (warehouse == null)
return true;
if (Warehouse.isEmpty(warehouse)) {
ErrorPopupMsg.sendErrorPopup(player, 167); // no more resources. ErrorPopupMsg.sendErrorPopup(player, 167); // no more resources.
return true; return true;
} }
@@ -243,11 +251,10 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
return true; return true;
} }
DateTime baneLive = new DateTime(bane.getPlacementDate()); LocalDateTime baneLive = bane.getPlacementDate();
baneLive = baneHour == 24 ? baneLive.plusDays(3) : baneLive.plusDays(2); baneLive = baneHour == 24 ? baneLive.plusDays(3) : baneLive.plusDays(2);
baneLive = baneHour == 24 ? baneLive.hourOfDay().setCopy(0) : baneLive.hourOfDay().setCopy(baneHour); baneLive = baneHour == 24 ? baneLive.withHour(0) : baneLive.withHour(baneHour);
baneLive = baneLive.minuteOfHour().setCopy(0); baneLive = baneLive.withMinute(0).withSecond(1).withNano(0);
baneLive = baneLive.secondOfMinute().setCopy(1);
bane.setLiveDate(baneLive); bane.setLiveDate(baneLive);
outMsg.actionType = 18; outMsg.actionType = 18;
@@ -8,7 +8,6 @@ import engine.net.Dispatch;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.*; import engine.net.client.msg.*;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.DeedTemplate;
import engine.powers.PowersBase; import engine.powers.PowersBase;
import java.util.ArrayList; import java.util.ArrayList;
@@ -79,7 +78,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
int uuid = item.templateID; int uuid = item.templateID;
switch (item.template.getItemType()) { switch (item.template.item_type) {
case DEED: //buildings case DEED: //buildings
//Call add building screen here, ib.getUseID() get's building ID //Call add building screen here, ib.getUseID() get's building ID
@@ -100,7 +99,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
pam.setX(loc.getX() + 64); //offset grid from tol pam.setX(loc.getX() + 64); //offset grid from tol
pam.setY(loc.getY()); pam.setY(loc.getY());
pam.setZ(loc.getZ() + 64); //offset grid from tol pam.setZ(loc.getZ() + 64); //offset grid from tol
pam.addPlacementInfo(DeedTemplate._deeds.get(item.templateID).deed_structure_id); pam.addPlacementInfo(item.template.deed_structure_id);
dispatch = Dispatch.borrow(player, pam); dispatch = Dispatch.borrow(player, pam);
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
@@ -188,14 +187,14 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
if (uuid > 680069 && uuid < 680074) //Handle Charter, Deed, Petition, Warrant here if (uuid > 680069 && uuid < 680074) //Handle Charter, Deed, Petition, Warrant here
break; break;
if (item.template.getItemBaneRank() > 0) { if (item.template.item_bane_rank > 0) {
// Only one banestone at a time // Only one banestone at a time
lock.writeLock().lock(); lock.writeLock().lock();
try { try {
if (Bane.summonBanestone(player, origin, item.template.getItemBaneRank()) == true) if (Bane.summonBanestone(player, origin, item.template.item_bane_rank) == true)
itemMan.consume(item); itemMan.consume(item);
} finally { } finally {
lock.writeLock().unlock(); lock.writeLock().unlock();
@@ -226,7 +225,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
// Bypass for waterbuckets // Bypass for waterbuckets
if (item.template.getItemType().equals(mbEnums.ItemType.BUCKET)) { if (item.template.item_type.equals(mbEnums.ItemType.BUCKET)) {
// test for valid target type // test for valid target type
if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter) if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter)
@@ -251,9 +250,10 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
} }
if (waterbucketBypass == false) { if (waterbucketBypass == false) {
engine.parsers.objects.PowerGrant powerGrant = item.template.getItemPowerGrant().get(0); String powerString = item.template.item_power_grant.keySet().iterator().next();
PowersBase powerAction = PowersManager.powersBaseByIDString.get(powerGrant.power_type); PowersBase powerAction = PowersManager.powersBaseByIDString.get(powerString);
PowersManager.applyPower(player, target, Vector3fImmutable.ZERO, powerAction.getToken(), powerGrant.power_value, true); int powerValue = item.template.item_power_grant.get(powerString);
PowersManager.applyPower(player, target, Vector3fImmutable.ZERO, powerAction.getToken(), powerValue, true);
} }
itemMan.consume(item); itemMan.consume(item);
} else //just remove the item at this point } else //just remove the item at this point
@@ -266,8 +266,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
case RUNE: case RUNE:
if(ApplyRuneMsg.applyRune(uuid, origin, player)) { if(ApplyRuneMsg.applyRune(uuid, origin, player)) {
itemMan.consume(item); itemMan.consume(item);
} else }
ErrorPopupMsg.sendErrorPopup(player, 161);
break; break;
default: //shouldn't be here, consume item default: //shouldn't be here, consume item
dispatch = Dispatch.borrow(player, msg); dispatch = Dispatch.borrow(player, msg);
@@ -18,9 +18,8 @@ import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.PlaceAssetMsg; import engine.net.client.msg.PlaceAssetMsg;
import engine.net.client.msg.PlaceAssetMsg.PlacementInfo; import engine.net.client.msg.PlaceAssetMsg.PlacementInfo;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.DeedTemplate;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.joda.time.DateTime; import java.time.Instant;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@@ -136,8 +135,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
private static boolean validateBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo placementInfo) { private static boolean validateBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo placementInfo) {
Bane bane;
if (serverZone.guild_zone == false) { if (serverZone.guild_zone == false) {
PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName()); PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName());
return false; return false;
@@ -208,15 +205,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
return false; return false;
} }
// Siege equipment has its own validation and never reaches here
bane = city.getBane();
if (bane != null) {
PlaceAssetMsg.sendPlaceAssetError(origin, 74, ""); //"Only buildings of war may be placed during a bane"
return false;
}
if (placementCollisionCheck(serverZone, origin, placementInfo)) { if (placementCollisionCheck(serverZone, origin, placementInfo)) {
PlaceAssetMsg.sendPlaceAssetError(origin, 3, ""); // Conflict between proposed assets PlaceAssetMsg.sendPlaceAssetError(origin, 3, ""); // Conflict between proposed assets
return false; return false;
@@ -357,8 +345,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
Item contract = null; Item contract = null;
for (Item inventoryItem : playerCharacter.getInventory()) { for (Item inventoryItem : playerCharacter.getInventory()) {
if (inventoryItem.template.getItemType().equals(ItemType.DEED) && if (inventoryItem.template.item_type.equals(ItemType.DEED) &&
DeedTemplate._deeds.get(inventoryItem.templateID).deed_structure_id == buildingList.getBlueprintUUID()) { inventoryItem.template.deed_structure_id == buildingList.getBlueprintUUID()) {
contract = inventoryItem; contract = inventoryItem;
break; break;
} }
@@ -1154,7 +1142,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
Blueprint blueprint; Blueprint blueprint;
Building newMesh; Building newMesh;
DateTime completionDate; Instant completionDate;
float vendorRotation; float vendorRotation;
float buildingRotation; float buildingRotation;
@@ -1169,9 +1157,9 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
if ((blueprint.getBuildingGroup().equals(BuildingGroup.SIEGETENT)) if ((blueprint.getBuildingGroup().equals(BuildingGroup.SIEGETENT))
|| (blueprint.getBuildingGroup().equals(BuildingGroup.BULWARK))) || (blueprint.getBuildingGroup().equals(BuildingGroup.BULWARK)))
completionDate = DateTime.now().plusMinutes(15); completionDate = Instant.now().plusSeconds(15 * 60);
else else
completionDate = DateTime.now().plusHours(blueprint.getRankTime(1)); completionDate = Instant.now().plusSeconds(blueprint.getRankTime(1) * 3600);
Vector3fImmutable localLoc = new Vector3fImmutable(ZoneManager.worldToLocal(buildingInfo.getLoc(), currentZone)); Vector3fImmutable localLoc = new Vector3fImmutable(ZoneManager.worldToLocal(buildingInfo.getLoc(), currentZone));
@@ -1240,7 +1228,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
ArrayList<AbstractGameObject> shrineObjects = DbManager.ShrineQueries.CREATE_SHRINE( ArrayList<AbstractGameObject> shrineObjects = DbManager.ShrineQueries.CREATE_SHRINE(
currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0), currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.PROTECTED, 0, 0, localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.PROTECTED, 0, 0,
DateTime.now().plusHours(blueprint.getRankTime(1)), blueprint.getMeshForRank(0), vendorRotation, buildingRotation, shrineType.name()); Instant.now().plusSeconds(blueprint.getRankTime(1) * 3600), blueprint.getMeshForRank(0), vendorRotation, buildingRotation, shrineType.name());
if (shrineObjects == null) { if (shrineObjects == null) {
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
@@ -1300,7 +1288,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
float buildingRotation = buildingInfo.getRot().y; float buildingRotation = buildingInfo.getRot().y;
float vendorRotation = buildingInfo.getW(); float vendorRotation = buildingInfo.getW();
DateTime completionDate = DateTime.now().plusHours(blueprint.getRankTime(1)); Instant completionDate = Instant.now().plusSeconds(blueprint.getRankTime(1) * 3600);
newMesh = DbManager.BuildingQueries.CREATE_BUILDING( newMesh = DbManager.BuildingQueries.CREATE_BUILDING(
@@ -1345,7 +1333,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
warehouseBuilding = DbManager.BuildingQueries.CREATE_BUILDING( warehouseBuilding = DbManager.BuildingQueries.CREATE_BUILDING(
currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0), currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0),
localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.NONE, 0, 0, localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.NONE, 0, 0,
DateTime.now().plusHours(blueprint.getRankTime(1)), blueprint.getMeshForRank(0), vendorRotation, buildingRotation); Instant.now().plusSeconds(blueprint.getRankTime(1) * 3600), blueprint.getMeshForRank(0), vendorRotation, buildingRotation);
if (warehouseBuilding == null) { if (warehouseBuilding == null) {
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
@@ -1353,7 +1341,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
} }
Warehouse warehouse = new Warehouse(warehouseBuilding); Warehouse warehouse = new Warehouse(warehouseBuilding);
Warehouse.destroyedWarehouses.values().removeIf(destroyed -> destroyed.city == city);
city.warehouse = warehouse; city.warehouse = warehouse;
DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse); DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse);
@@ -13,7 +13,6 @@ import engine.mbEnums;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.RefineMsg; import engine.net.client.msg.RefineMsg;
import engine.net.client.msg.RefinerScreenMsg; import engine.net.client.msg.RefinerScreenMsg;
import engine.objects.*; import engine.objects.*;
@@ -89,9 +88,6 @@ public class RefineMsgHandler extends AbstractClientMsgHandler {
public static boolean refineSkill(ClientConnection origin, PlayerCharacter pc, int token, RefineMsg msg) { public static boolean refineSkill(ClientConnection origin, PlayerCharacter pc, int token, RefineMsg msg) {
CharacterSkill skill = null; CharacterSkill skill = null;
ConcurrentHashMap<String, CharacterSkill> skills = pc.getSkills(); ConcurrentHashMap<String, CharacterSkill> skills = pc.getSkills();
int refinedAmount;
int requiredAmount;
for (CharacterSkill sk : skills.values()) { for (CharacterSkill sk : skills.values()) {
if (sk == null) if (sk == null)
continue; continue;
@@ -110,16 +106,17 @@ public class RefineMsgHandler extends AbstractClientMsgHandler {
//TODO verify if any skills have this as prereq //TODO verify if any skills have this as prereq
// Dropping below a trained power's skill requirement would make calculatePowers delete the power and its trains //TODO verify if any powers have this as a prereq
refinedAmount = Math.round(skill.getBaseAmountBeforeMods() + skill.calculateAmountAfterTrains(skill.getNumTrains() - 1)); //get all players powers
for (CharacterPower power : pc.getPowers().values()) { for (CharacterPower power : pc.getPowers().values()) {
if (power.getTrains() < 1) ArrayList<PowerReq> reqs = PowerReq.getPowerReqsForRune(power.getPowerID());
continue; for (PowerReq req : reqs) {
requiredAmount = getRequiredSkillAmount(pc, power.getPower().getToken(), token); ConcurrentHashMap<String, CharacterSkill> playerSkills = pc.getSkills();
if (refinedAmount < requiredAmount) { CharacterSkill playerSkill = playerSkills.get(token);
ErrorPopupMsg.sendErrorMsg(pc, "You must refine " + power.getPower().getName() + " to 0 before refining any more from this skill."); int currentSkillLevel = playerSkill.getTotalSkillPercet();
return false; if (token == req.getToken() && req.getLevel() == currentSkillLevel) {
return false;
}
} }
} }
@@ -127,36 +124,6 @@ public class RefineMsgHandler extends AbstractClientMsgHandler {
return skill.refine(pc); return skill.refine(pc);
} }
private static int getRequiredSkillAmount(PlayerCharacter pc, int powerToken, int skillToken) {
int requiredAmount = 0;
if (pc.race != null)
requiredAmount = Math.max(requiredAmount, getRequiredSkillAmount(pc.race.getPowersGranted(), powerToken, skillToken));
if (pc.baseClass != null)
requiredAmount = Math.max(requiredAmount, getRequiredSkillAmount(pc.baseClass.getPowersGranted(), powerToken, skillToken));
if (pc.promotionClass != null)
requiredAmount = Math.max(requiredAmount, getRequiredSkillAmount(pc.promotionClass.getPowersGranted(), powerToken, skillToken));
if (pc.getRunes() != null)
for (CharacterRune rune : pc.getRunes())
requiredAmount = Math.max(requiredAmount, getRequiredSkillAmount(rune.getPowersGranted(), powerToken, skillToken));
return requiredAmount;
}
private static int getRequiredSkillAmount(ArrayList<PowerReq> powersGranted, int powerToken, int skillToken) {
Byte requiredAmount;
for (PowerReq powerReq : powersGranted) {
if (powerReq.getToken() != powerToken)
continue;
requiredAmount = powerReq.getSkillReqs().get(skillToken);
if (requiredAmount != null)
return requiredAmount;
}
return 0;
}
public static boolean refinePower(ClientConnection origin, PlayerCharacter pc, int token, RefineMsg msg) { public static boolean refinePower(ClientConnection origin, PlayerCharacter pc, int token, RefineMsg msg) {
CharacterPower power = null; CharacterPower power = null;
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers(); ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
@@ -85,7 +85,7 @@ public class RepairMsgHandler extends AbstractClientMsgHandler {
//make sure item is damaged and not destroyed //make sure item is damaged and not destroyed
short dur = (short) toRepair.combat_health_current; short dur = (short) toRepair.combat_health_current;
short max = (short) toRepair.template.getCombatHealthFull(); short max = (short) toRepair.template.combat_health_full;
//account for durability modifications //account for durability modifications
@@ -68,7 +68,7 @@ public class TransferItemFromBankMsgHandler extends AbstractClientMsgHandler {
return true; return true;
; ;
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) { if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
if (!itemManager.moveGoldToInventory(item, msg.getNumItems())) if (!itemManager.moveGoldToInventory(item, msg.getNumItems()))
return true; return true;
@@ -85,7 +85,7 @@ public class TransferItemFromBankMsgHandler extends AbstractClientMsgHandler {
// Not gold, process update here // Not gold, process update here
if (!itemManager.hasRoomInventory(item.template.getItemWt())) if (!itemManager.hasRoomInventory(item.template.item_wt))
return true; return true;
if (itemManager.moveItemToInventory(item) == false) if (itemManager.moveItemToInventory(item) == false)
@@ -65,7 +65,7 @@ public class TransferItemToBankMsgHandler extends AbstractClientMsgHandler {
return true; return true;
if (item.containerType == mbEnums.ItemContainerType.INVENTORY && itemManager.isBankOpen()) if (item.containerType == mbEnums.ItemContainerType.INVENTORY && itemManager.isBankOpen())
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) { if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
if (!itemManager.moveGoldToBank(item, msg.getNumItems())) if (!itemManager.moveGoldToBank(item, msg.getNumItems()))
return true; return true;
UpdateGoldMsg goldMes = new UpdateGoldMsg(player); UpdateGoldMsg goldMes = new UpdateGoldMsg(player);
@@ -76,7 +76,7 @@ public class TransferItemToBankMsgHandler extends AbstractClientMsgHandler {
} else { } else {
if (!itemManager.hasRoomBank(item.template.getItemWt())) if (!itemManager.hasRoomBank(item.template.item_wt))
return true; return true;
if (!itemManager.moveItemToBank(item)) if (!itemManager.moveItemToBank(item))
@@ -86,7 +86,7 @@ public class VendorBuyMsgHandler extends AbstractClientMsgHandler {
if (me.objectUUID == vendorBuyMsg.getItemID()) { if (me.objectUUID == vendorBuyMsg.getItemID()) {
//test room available for item //test room available for item
if (!itemMan.hasRoomInventory(me.template.getItemWt())) if (!itemMan.hasRoomInventory(me.template.item_wt))
return true; return true;
int cost = me.getValue(); int cost = me.getValue();
@@ -148,10 +148,10 @@ public class VendorBuyMsgHandler extends AbstractClientMsgHandler {
//test room available for item //test room available for item
if (!itemMan.hasRoomInventory(vendorItem.template.getItemWt())) if (!itemMan.hasRoomInventory(vendorItem.template.item_wt))
return true; return true;
int cost = vendorItem.template.getItemValue(); int cost = vendorItem.template.item_value;
if (vendorItem.flags.contains(mbEnums.ItemFlags.Identified) || vendorItem.isCustomValue()) if (vendorItem.flags.contains(mbEnums.ItemFlags.Identified) || vendorItem.isCustomValue())
cost = vendorItem.magicValue; cost = vendorItem.magicValue;
@@ -94,7 +94,7 @@ public class VendorSellMsgHandler extends AbstractClientMsgHandler {
return true; return true;
if (npc.getParentZone() != null && npc.getParentZone().playerCityUUID != 0) if (npc.getParentZone() != null && npc.getParentZone().playerCityUUID != 0)
if (!npc.charItemManager.hasRoomInventory(sell.template.getItemWt())) { if (!npc.charItemManager.hasRoomInventory(sell.template.item_wt)) {
ErrorPopupMsg.sendErrorPopup(player, 21); ErrorPopupMsg.sendErrorPopup(player, 21);
return true; return true;
} }
@@ -104,7 +104,7 @@ public class VendorSellMsgHandler extends AbstractClientMsgHandler {
//get goldItem cost to sell //get goldItem cost to sell
cost = (int) (sell.template.getItemValue() * (sell.combat_health_current / sell.template.getCombatHealthFull())); cost = (int) (sell.template.item_value * (sell.combat_health_current / sell.template.combat_health_full));
float bargain = player.getBargain(); float bargain = player.getBargain();
float profit = npc.getBuyPercent(player) + bargain; float profit = npc.getBuyPercent(player) + bargain;
+72 -73
View File
@@ -22,17 +22,10 @@ import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.concurrent.ConcurrentHashMap;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class ApplyRuneMsg extends ClientNetMsg { public class ApplyRuneMsg extends ClientNetMsg {
// Client ArcCharacter_AddRune (0x4695D0)
private static final int MAX_TALENTS = 8;
private int targetType; private int targetType;
private int targetID; private int targetID;
private int removeRuneBase; private int removeRuneBase;
@@ -85,28 +78,67 @@ public class ApplyRuneMsg extends ClientNetMsg {
return false; return false;
} }
//Check race is met
ConcurrentHashMap<Integer, Boolean> races = rb.getRace();
if (races.size() > 0) {
int raceID = playerCharacter.getRaceID();
boolean valid = false;
for (int validID : races.keySet()) {
if (validID == raceID) {
valid = true;
break;
}
}
if (!valid) {
return false;
}
}
//Check base class is met
ConcurrentHashMap<Integer, Boolean> baseClasses = rb.getBaseClass();
if (baseClasses.size() > 0) {
int baseClassID = playerCharacter.getBaseClassID();
boolean valid = false;
for (int validID : baseClasses.keySet()) {
if (validID == baseClassID) {
valid = true;
break;
}
}
if (!valid) {
return false;
}
}
//Check promotion class is met
ConcurrentHashMap<Integer, Boolean> promotionClasses = rb.getPromotionClass();
if (promotionClasses.size() > 0) {
int promotionClassID = playerCharacter.getPromotionClassID();
boolean valid = false;
for (int validID : promotionClasses.keySet()) {
if (validID == promotionClassID) {
valid = true;
break;
}
}
if (!valid) {
return false;
}
}
//Check disciplines are met
ArrayList<CharacterRune> runes = playerCharacter.getRunes(); ArrayList<CharacterRune> runes = playerCharacter.getRunes();
HashSet<Integer> classIDs = new HashSet<>(); ConcurrentHashMap<Integer, Boolean> disciplines = rb.getDiscipline();
HashSet<Integer> heldDiscIDs = new HashSet<>(); if (disciplines.size() > 0) {
for (CharacterRune cr : runes) {
// Client ArcCharacter_MeetsItemReqs (0x475F40) int runeBaseID = cr.getRuneBaseID();
if (!meetsListReq(rb.getRace().keySet(), rb.isRaceRestrict(), Collections.singleton(playerCharacter.getRaceID()))) for (Integer prohID : disciplines.keySet()) {
return false; if (runeBaseID == prohID) {
return false; //Prohibited rune
// A listed base class covers its promotions: base or promotion listed is enough }
classIDs.addAll(rb.getBaseClass().keySet()); }
classIDs.addAll(rb.getPromotionClass().keySet()); }
}
if (!meetsListReq(classIDs, rb.isClassRestrict(), Arrays.asList(playerCharacter.getBaseClassID(), playerCharacter.getPromotionClassID())))
return false;
// Only the new rune's list is checked, not the held discs' lists
for (CharacterRune cr : runes)
if (isDiscipline(cr.getRuneBaseID()))
heldDiscIDs.add(cr.getRuneBaseID());
if (!meetsListReq(rb.getDiscipline().keySet(), rb.isDiscRestrict(), heldDiscIDs))
return false;
int discCount = 0; int discCount = 0;
for (CharacterRune cr : runes) { for (CharacterRune cr : runes) {
@@ -126,32 +158,6 @@ public class ApplyRuneMsg extends ClientNetMsg {
return false; return false;
} }
// Client 0x4768D0 refuses a talent unless its rank beats the held one with the same sub type (rank 0 included);
// AddRune (0x4695D0) then replaces the held talent
CharacterRune replacedRune = null;
if (rb.getRuneType() == mbEnums.RuneType.TALENT) {
int talentCount = 0;
for (CharacterRune cr : runes) {
RuneBase heldRuneBase = cr.getRuneBase();
if (heldRuneBase == null || heldRuneBase.getRuneType() != mbEnums.RuneType.TALENT)
continue;
talentCount++;
if (rb.getSubTypeToken() != 0 && heldRuneBase.getSubTypeToken() == rb.getSubTypeToken())
replacedRune = cr;
}
if (replacedRune != null) {
if (rb.getRank() <= replacedRune.getRuneBase().getRank())
return false;
} else if (talentCount >= MAX_TALENTS)
return false;
}
int strTotal = 0; int strTotal = 0;
int dexTotal = 0; int dexTotal = 0;
int conTotal = 0; int conTotal = 0;
@@ -221,6 +227,11 @@ public class ApplyRuneMsg extends ClientNetMsg {
} }
} }
//Check if max number runes already reached
if (runes.size() > 12) {
return false;
}
//if discipline, check number applied //if discipline, check number applied
if (isDiscipline(runeID)) { if (isDiscipline(runeID)) {
if (playerCharacter.getLevel() < 70) { if (playerCharacter.getLevel() < 70) {
@@ -248,10 +259,13 @@ public class ApplyRuneMsg extends ClientNetMsg {
return false; return false;
} }
//remove the replaced talent from player //remove any overridden runes from player
ArrayList<Integer> overwrite = rb.getOverwrite();
CharacterRune toRemove = null; CharacterRune toRemove = null;
if (replacedRune != null) { if (overwrite.size() > 0) {
toRemove = playerCharacter.removeRune(replacedRune.getRuneBaseID()); for (int overwriteID : overwrite) {
toRemove = playerCharacter.removeRune(overwriteID);
}
} }
//add rune to player //add rune to player
@@ -317,21 +331,6 @@ public class ApplyRuneMsg extends ClientNetMsg {
return runeID > 3000 && runeID < 3050; return runeID > 3000 && runeID < 3050;
} }
// Client ArcItemRestrict_Check (0x4BAC60). An empty list has no requirement; no rune has an empty whitelist.
private static boolean meetsListReq(Set<Integer> listedIDs, boolean restrict, Collection<Integer> heldIDs) {
boolean listed = false;
if (listedIDs.isEmpty())
return true;
for (int heldID : heldIDs)
if (listedIDs.contains(heldID))
listed = true;
return listed != restrict;
}
/** /**
* Serializes the subclass specific items to the supplied NetMsgWriter. * Serializes the subclass specific items to the supplied NetMsgWriter.
*/ */
@@ -17,8 +17,9 @@ import engine.net.Protocol;
import engine.objects.Building; import engine.objects.Building;
import engine.objects.Guild; import engine.objects.Guild;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.joda.time.DateTime; import java.time.Instant;
import org.joda.time.Seconds; import java.time.Duration;
import java.time.temporal.ChronoField;
public class ArcMineWindowAvailableTimeMsg extends ClientNetMsg { public class ArcMineWindowAvailableTimeMsg extends ClientNetMsg {
@@ -26,8 +27,8 @@ public class ArcMineWindowAvailableTimeMsg extends ClientNetMsg {
private Building treeOfLife; private Building treeOfLife;
private int currentMineHour; private int currentMineHour;
private Seconds secondsLeft; private Duration secondsLeft;
private DateTime lateTime; private Instant lateTime;
private int late; private int late;
/** /**
@@ -72,15 +73,15 @@ public class ArcMineWindowAvailableTimeMsg extends ClientNetMsg {
currentMineHour = guild.getMineTime(); currentMineHour = guild.getMineTime();
late = MBServerStatics.MINE_LATE_WINDOW; late = MBServerStatics.MINE_LATE_WINDOW;
lateTime = DateTime.now(); lateTime = Instant.now();
if (late == 0) if (late == 0)
lateTime = lateTime.plusDays(1); lateTime = lateTime.plus(Duration.ofDays(1));
lateTime = lateTime.hourOfDay().setCopy(late); lateTime = lateTime.with(ChronoField.HOUR_OF_DAY, late);
late = ((late > 23) ? (late - 24) : late); late = ((late > 23) ? (late - 24) : late);
secondsLeft = Seconds.secondsBetween(DateTime.now(), lateTime); secondsLeft = Duration.between(Instant.now(), lateTime);
} }
/** /**
@@ -106,4 +107,4 @@ public class ArcMineWindowAvailableTimeMsg extends ClientNetMsg {
public void setBuildingUUID(int buildingUUID) { public void setBuildingUUID(int buildingUUID) {
this.buildingUUID = buildingUUID; this.buildingUUID = buildingUUID;
} }
} }
@@ -18,9 +18,6 @@ import engine.net.ByteBufferReader;
import engine.net.ByteBufferWriter; import engine.net.ByteBufferWriter;
import engine.net.Protocol; import engine.net.Protocol;
import engine.objects.*; import engine.objects.*;
import org.joda.time.DateTime;
import org.joda.time.Period;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.Set; import java.util.Set;
@@ -397,37 +394,33 @@ public class ManageCityAssetsMsg extends ClientNetMsg {
else else
writer.put((byte) 0); writer.put((byte) 0);
DateTime placedOn = bane.getLiveDate(); LocalDateTime placedOn = bane.getLiveDate();
if (placedOn == null) if (placedOn == null)
placedOn = new DateTime(DateTime.now()); placedOn = LocalDateTime.now();
//set Calander to date of bane live. //set Calander to date of bane live.
DateTime now = DateTime.now(); LocalDateTime now = LocalDateTime.now();
DateTime defaultTime = new DateTime(bane.getPlacementDate()); LocalDateTime defaultTime = bane.getPlacementDate();
DateTime playerEnterWorldTime = new DateTime(this.assetManager.getTimeStamp("EnterWorld")); LocalDateTime playerEnterWorldTime = LocalDateTime.ofInstant(java.time.Instant.ofEpochMilli(this.assetManager.getTimeStamp("EnterWorld")), ZoneId.systemDefault());
Period period = new Period(playerEnterWorldTime.getMillis(), now.getMillis()); int hoursLoggedIn = (int) java.time.Duration.between(playerEnterWorldTime, now).toHours();
int hoursLoggedIn = period.getHours();
hoursLoggedIn = hoursLoggedIn < 0 ? 0 : hoursLoggedIn; hoursLoggedIn = hoursLoggedIn < 0 ? 0 : hoursLoggedIn;
defaultTime = defaultTime.plusDays(2); defaultTime = defaultTime.plusDays(2).withHour(22).withMinute(0).withSecond(0).withNano(0);
defaultTime = defaultTime.hourOfDay().setCopy(22);
defaultTime = defaultTime.minuteOfHour().setCopy(0);
defaultTime = defaultTime.secondOfMinute().setCopy(0);
long curTime = now.getMillis(); long curTime = now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
long timeLeft = 0; long timeLeft = 0;
if (bane.getLiveDate() != null) if (bane.getLiveDate() != null)
timeLeft = bane.getLiveDate().getMillis() - curTime; timeLeft = bane.getLiveDate().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - curTime;
else else
timeLeft = defaultTime.getMillis() - curTime + 1000; timeLeft = defaultTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - curTime + 1000;
//DO not touch these. They are static formula's until i get the correct converter for SB Time. //DO not touch these. They are static formula's until i get the correct converter for SB Time.
writer.put((byte) placedOn.dayOfMonth().get()); writer.put((byte) placedOn.getDayOfMonth());
writer.put((byte) placedOn.monthOfYear().get()); writer.put((byte) placedOn.getMonthValue());
writer.putInt(placedOn.year().get() - 1900); writer.putInt(placedOn.getYear() - 1900);
writer.put((byte) 0); writer.put((byte) 0);
writer.put((byte) 0); writer.put((byte) 0);
writer.put((byte) 0); writer.put((byte) 0);
+27 -33
View File
@@ -19,10 +19,8 @@ import engine.net.ByteBufferReader;
import engine.net.ByteBufferWriter; import engine.net.ByteBufferWriter;
import engine.net.Protocol; import engine.net.Protocol;
import engine.objects.*; import engine.objects.*;
import engine.parsers.objects.CObjectTemplate; import java.time.Duration;
import org.joda.time.DateTime; import java.time.LocalDateTime;
import org.joda.time.Period;
import org.joda.time.Seconds;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
@@ -138,7 +136,6 @@ public class ManageNPCMsg extends ClientNetMsg {
@Override @Override
protected void _serialize(ByteBufferWriter writer) { protected void _serialize(ByteBufferWriter writer) {
Period upgradePeriod;
int upgradePeriodInSeconds; int upgradePeriodInSeconds;
try { try {
@@ -200,21 +197,20 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(npc.getUpgradeCost()); writer.putInt(npc.getUpgradeCost());
if (npc.isRanking() && npc.getUpgradeDateTime().isAfter(DateTime.now())) long upgradeTotalSecs = 0;
upgradePeriod = new Period(DateTime.now(), npc.getUpgradeDateTime()); if (npc.isRanking() && npc.getUpgradeDateTime().isAfter(LocalDateTime.now()))
else upgradeTotalSecs = Duration.between(LocalDateTime.now(), npc.getUpgradeDateTime()).getSeconds();
upgradePeriod = new Period(0);
writer.put((byte) upgradePeriod.getDays()); //for timer writer.put((byte) (int) (upgradeTotalSecs / 86400)); //for timer
writer.put((byte) unknown26);//unknown writer.put((byte) unknown26);//unknown
writer.putInt(100); //unknown writer.putInt(100); //unknown
writer.put((byte) upgradePeriod.getHours()); //for timer writer.put((byte) (int) ((upgradeTotalSecs % 86400) / 3600)); //for timer
writer.put((byte) upgradePeriod.getMinutes()); //for timer writer.put((byte) (int) ((upgradeTotalSecs % 3600) / 60)); //for timer
writer.put((byte) upgradePeriod.getSeconds()); //for timer writer.put((byte) (int) (upgradeTotalSecs % 60)); //for timer
if (npc.isRanking() && npc.getUpgradeDateTime().isAfter(DateTime.now())) if (npc.isRanking() && npc.getUpgradeDateTime().isAfter(LocalDateTime.now()))
upgradePeriodInSeconds = Seconds.secondsBetween(DateTime.now(), npc.getUpgradeDateTime()).getSeconds(); upgradePeriodInSeconds = (int) upgradeTotalSecs;
else else
upgradePeriodInSeconds = 0; upgradePeriodInSeconds = 0;
@@ -421,18 +417,17 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(rollableSet.size()); writer.putInt(rollableSet.size());
for (int templateID : rollableSet) { for (int templateID : rollableSet) {
CObjectTemplate template = CObjectTemplate.lookup(templateID); ItemTemplate template = ItemTemplate.templates.get(templateID);
int modTable = ForgeManager.getVendorModTable(templateID);
writer.put((byte) 1); writer.put((byte) 1);
writer.putInt(0); writer.putInt(0);
writer.putInt(templateID); //itemID writer.putInt(templateID); //itemID
writer.putInt(template.getItemValue()); writer.putInt(template.item_value);
writer.putInt(600); writer.putInt(600);
writer.put((byte) 1); writer.put((byte) 1);
writer.put((byte) modTable); writer.put((byte) template.modTable);
writer.put((byte) modTable); writer.put((byte) template.modTable);
writer.put((byte) modTable); writer.put((byte) template.modTable);
writer.put((byte) modTable);//EffectItemType writer.put((byte) template.modTable);//EffectItemType
} }
ArrayList<Item> cooking = NPCManager.getAllCookingForVendor(npc); ArrayList<Item> cooking = NPCManager.getAllCookingForVendor(npc);
@@ -446,7 +441,7 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(0); writer.putInt(0);
writer.putInt(item.templateID); writer.putInt(item.templateID);
writer.putInt(item.template.getItemValue()); writer.putInt(item.template.item_value);
long timeLife = item.getDateToUpgrade() - System.currentTimeMillis(); long timeLife = item.getDateToUpgrade() - System.currentTimeMillis();
@@ -591,21 +586,20 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(Mob.getUpgradeCost(mobA)); writer.putInt(Mob.getUpgradeCost(mobA));
if (mobA.isRanking() && mobA.getUpgradeDateTime().isAfter(DateTime.now())) long upgradeTotalSecs = 0;
upgradePeriod = new Period(DateTime.now(), mobA.getUpgradeDateTime()); if (mobA.isRanking() && mobA.getUpgradeDateTime().isAfter(LocalDateTime.now()))
else upgradeTotalSecs = Duration.between(LocalDateTime.now(), mobA.getUpgradeDateTime()).getSeconds();
upgradePeriod = new Period(0);
writer.put((byte) upgradePeriod.getDays()); //for timer writer.put((byte) (int) (upgradeTotalSecs / 86400)); //for timer
writer.put((byte) unknown26);//unknown writer.put((byte) unknown26);//unknown
writer.putInt(100); //unknown writer.putInt(100); //unknown
writer.put((byte) upgradePeriod.getHours()); //for timer writer.put((byte) (int) ((upgradeTotalSecs % 86400) / 3600)); //for timer
writer.put((byte) upgradePeriod.getMinutes()); //for timer writer.put((byte) (int) ((upgradeTotalSecs % 3600) / 60)); //for timer
writer.put((byte) upgradePeriod.getSeconds()); //for timer writer.put((byte) (int) (upgradeTotalSecs % 60)); //for timer
if (mobA.isRanking() && mobA.getUpgradeDateTime().isAfter(DateTime.now())) if (mobA.isRanking() && mobA.getUpgradeDateTime().isAfter(LocalDateTime.now()))
upgradePeriodInSeconds = Seconds.secondsBetween(DateTime.now(), mobA.getUpgradeDateTime()).getSeconds(); upgradePeriodInSeconds = (int) upgradeTotalSecs;
else else
upgradePeriodInSeconds = 0; upgradePeriodInSeconds = 0;
@@ -54,7 +54,7 @@ public class UpdateInventoryMsg extends ClientNetMsg {
for (Item item : list) { for (Item item : list) {
if (item.template.getItemType().equals(ItemType.GOLD)) { if (item.template.item_type.equals(ItemType.GOLD)) {
if (item.getNumOfItems() == 0) if (item.getNumOfItems() == 0)
continue; continue;
} }
+1 -6
View File
@@ -16,7 +16,6 @@ import engine.net.ByteBufferWriter;
import engine.net.Protocol; import engine.net.Protocol;
import engine.objects.Item; import engine.objects.Item;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import engine.parsers.objects.DeedTemplate;
public class UseCharterMsg extends ClientNetMsg { public class UseCharterMsg extends ClientNetMsg {
@@ -62,13 +61,9 @@ public class UseCharterMsg extends ClientNetMsg {
public void configure() { public void configure() {
DeedTemplate charterDeed;
if (close) { if (close) {
for (Item i : player.getInventory()) { for (Item i : player.getInventory()) {
charterDeed = DeedTemplate._deeds.get(i.templateID); if (i.template.item_type.equals(ItemType.CHARTER)) {
if (charterDeed != null && charterDeed.item_type.equals(ItemType.CHARTER)) {
charterUUID = i.getObjectUUID(); charterUUID = i.getObjectUUID();
break; break;
} }
@@ -156,7 +156,7 @@ public class VendorBuyWindowMsg extends ClientNetMsg {
for (Item item : inventory) { for (Item item : inventory) {
if (item.getOwnerID() != ownerID) if (item.getOwnerID() != ownerID)
continue; continue;
if (item.template.getItemType().equals(ItemType.GOLD)) { if (item.template.item_type.equals(ItemType.GOLD)) {
if (item.getNumOfItems() == 0) if (item.getNumOfItems() == 0)
continue; continue;
} }
@@ -17,7 +17,7 @@ import engine.net.ByteBufferWriter;
import engine.net.Protocol; import engine.net.Protocol;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
import engine.objects.*; import engine.objects.*;
import org.joda.time.DateTime; import java.time.Instant;
public class GuildInfoMsg extends ClientNetMsg { public class GuildInfoMsg extends ClientNetMsg {
@@ -306,7 +306,7 @@ class GuildInfoMessageType4 extends GuildInfoMessageType {
writer.putString(guildLeaderName); writer.putString(guildLeaderName);
writer.putString(pc.getName()); writer.putString(pc.getName());
writer.putDateTime(DateTime.now()); writer.putDateTime(Instant.now());
writer.put((byte) 1); writer.put((byte) 1);
writer.put((byte) 1); writer.put((byte) 1);
writer.put((byte) 1); writer.put((byte) 1);
@@ -401,7 +401,7 @@ class GuildInfoMessageType5 extends GuildInfoMessageType {
writer.putString("Guild Leader"); writer.putString("Guild Leader");
writer.putString(""); //Nation Leader - I believe writer.putString(""); //Nation Leader - I believe
DateTime now = DateTime.now(); Instant now = Instant.now();
writer.putDateTime(now); writer.putDateTime(now);
writer.put((byte) 1); writer.put((byte) 1);
+51 -130
View File
@@ -29,8 +29,6 @@ import engine.net.Dispatch;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ApplyRuneMsg; import engine.net.client.msg.ApplyRuneMsg;
import engine.net.client.msg.UpdateStateMsg; import engine.net.client.msg.UpdateStateMsg;
import engine.parsers.objects.CObjectTemplate;
import engine.parsers.objects.RuneTemplate;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import engine.powers.PowersBase; import engine.powers.PowersBase;
import engine.powers.effectmodifiers.AbstractEffectModifier; import engine.powers.effectmodifiers.AbstractEffectModifier;
@@ -654,34 +652,16 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
AssignDefenseValue(abstractCharacter); AssignDefenseValue(abstractCharacter);
// calculate atr and damage for each hand // calculate atr and damage for each hand
ConcurrentHashMap<EquipSlotType, Item> equipped = abstractCharacter.charItemManager.getEquipped(); ConcurrentHashMap<EquipSlotType, Item> equipped = abstractCharacter.charItemManager.getEquipped();
AssignDamageAtrForPlayers(abstractCharacter, equipped.get(EquipSlotType.RHELD), true, equipped.get(EquipSlotType.LHELD)); AssignDamageAtrForPlayers(abstractCharacter, equipped.get(EquipSlotType.RHELD), true, equipped.get(EquipSlotType.RHELD));
AssignDamageAtrForPlayers(abstractCharacter, equipped.get(EquipSlotType.LHELD), false, equipped.get(EquipSlotType.RHELD)); AssignDamageAtrForPlayers(abstractCharacter, equipped.get(EquipSlotType.LHELD), false, equipped.get(EquipSlotType.LHELD));
if (abstractCharacter.getObjectType().equals(GameObjectType.Mob)) { if (abstractCharacter.getObjectType().equals(GameObjectType.Mob)) {
Mob mob = (Mob) abstractCharacter; Mob mob = (Mob) abstractCharacter;
RuneTemplate rune = RuneTemplate._runes.get(mob.loadID); abstractCharacter.minDamageHandOne = (int) mob.mobBase.getDamageMin();
float minDamage = mob.mobBase.getDamageMin(); abstractCharacter.minDamageHandTwo = (int) mob.mobBase.getDamageMin();
float maxDamage = mob.mobBase.getDamageMax(); abstractCharacter.maxDamageHandOne = (int) mob.mobBase.getDamageMax();
int attackRating = mob.mobBase.getAttackRating(); abstractCharacter.maxDamageHandTwo = (int) mob.mobBase.getDamageMax();
abstractCharacter.atrHandOne = mob.mobBase.getAttackRating();
// The client (ArcMobile, 0x46D200) takes mob damage straight from the rune MINDAMAGE/MAXDAMAGE, abstractCharacter.atrHandTwo = mob.mobBase.getAttackRating();
// with no stat scaling. Use the rune when it has damage, otherwise keep the mobbase value.
if (rune != null && rune.rune_max_damage > 0) {
minDamage = rune.rune_min_damage;
maxDamage = rune.rune_max_damage;
}
// Likewise ATR comes straight from the rune ATTACK for mobiles (0x466570).
if (rune != null && rune.rune_attack > 0)
attackRating = rune.rune_attack;
abstractCharacter.minDamageHandOne = (int) minDamage;
abstractCharacter.minDamageHandTwo = (int) minDamage;
abstractCharacter.maxDamageHandOne = (int) maxDamage;
abstractCharacter.maxDamageHandTwo = (int) maxDamage;
abstractCharacter.atrHandOne = attackRating;
abstractCharacter.atrHandTwo = attackRating;
abstractCharacter.defenseRating = mob.mobBase.getDefenseRating(); abstractCharacter.defenseRating = mob.mobBase.getDefenseRating();
} }
} }
@@ -693,17 +673,16 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
// make sure weapon exists // make sure weapon exists
boolean noWeapon = false; boolean noWeapon = false;
CObjectTemplate weaponTemplate = null; ItemTemplate weaponTemplate = null;
engine.parsers.objects.ItemTemplate.Damage damage;
if (weapon == null) if (weapon == null)
noWeapon = true; noWeapon = true;
else { else {
CObjectTemplate itemTemplate = weapon.template; ItemTemplate itemTemplate = weapon.template;
if (itemTemplate == null) if (itemTemplate == null)
noWeapon = true; noWeapon = true;
else if (!weapon.template.getItemType().equals(ItemType.WEAPON)) { else if (!weapon.template.item_type.equals(ItemType.WEAPON)) {
defaultAtrAndDamage(abstractCharacter, mainHand); defaultAtrAndDamage(abstractCharacter, mainHand);
return; return;
} else } else
@@ -720,7 +699,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
if (noWeapon) { if (noWeapon) {
if (mainHand) { if (mainHand) {
Item off = abstractCharacter.charItemManager.getEquipped().get(EquipSlotType.LHELD); Item off = abstractCharacter.charItemManager.getEquipped().get(EquipSlotType.LHELD);
if (off != null && off.template != null && off.template.getItemType().equals(ItemType.WEAPON)) if (off != null && off.template != null && off.template.item_type.equals(ItemType.WEAPON))
abstractCharacter.rangeHandOne = 10 * (1 + (abstractCharacter.statStrBase / 600)); // Set abstractCharacter.rangeHandOne = 10 * (1 + (abstractCharacter.statStrBase / 600)); // Set
// to // to
// no // no
@@ -738,24 +717,15 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
mastDam = CharacterSkill.getQuickMastery(abstractCharacter, "Unarmed Combat Mastery"); mastDam = CharacterSkill.getQuickMastery(abstractCharacter, "Unarmed Combat Mastery");
else else
mastDam = masteryPercentage; mastDam = masteryPercentage;
// Base fist damage from the race rune natural attack (1-4 for all races), scaled below like a weapon. // TODO Correct these
// Matches the client's unarmed damage calc (0x46D200). min = 1;
max = 3;
float[] naturalAttack = CombatManager.getNaturalAttack(abstractCharacter, mainHand ? EquipSlotType.RHELD : EquipSlotType.LHELD);
if (naturalAttack != null && naturalAttack.length > 9) {
min = (int) naturalAttack[8];
max = (int) naturalAttack[9];
} else {
min = 1;
max = 3;
}
} else { } else {
if (mainHand) if (mainHand)
abstractCharacter.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range * (1 + (abstractCharacter.statStrBase / 600)); abstractCharacter.rangeHandOne = weapon.template.item_weapon_max_range * (1 + (abstractCharacter.statStrBase / 600));
else else
abstractCharacter.rangeHandTwo = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range * (1 + (abstractCharacter.statStrBase / 600)); abstractCharacter.rangeHandTwo = weapon.template.item_weapon_max_range * (1 + (abstractCharacter.statStrBase / 600));
if (abstractCharacter.bonuses != null) { if (abstractCharacter.bonuses != null) {
float range_bonus = 1 + abstractCharacter.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.None); float range_bonus = 1 + abstractCharacter.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.None);
@@ -767,20 +737,20 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
skillPercentage = getModifiedAmount(abstractCharacter.skills.get(weapon.template.getItemSkillUsed())); skillPercentage = getModifiedAmount(abstractCharacter.skills.get(weapon.template.item_skill_used));
masteryPercentage = getModifiedAmount(abstractCharacter.skills.get(weaponTemplate.getItemSkillMasteryUsed())); masteryPercentage = getModifiedAmount(abstractCharacter.skills.get(weaponTemplate.item_skill_mastery_used));
if (masteryPercentage == 0f) if (masteryPercentage == 0f)
mastDam = 0f; mastDam = 0f;
// mastDam = CharacterSkill.getQuickMastery(this, wb.getMastery()); // mastDam = CharacterSkill.getQuickMastery(this, wb.getMastery());
else else
mastDam = masteryPercentage; mastDam = masteryPercentage;
damage = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0); int[] damages = (int[]) weaponTemplate.item_weapon_damage.values().toArray()[0];
min = damage.damage_min; min = damages[0];
max = damage.damage_max; max = damages[1];
strBased = engine.parsers.objects.ItemTemplate._items.get(weapon.templateID).item_primary_attr == AttributeType.Strength; strBased = weaponTemplate.item_primary_attr.equals(AttributeType.Strength);
} }
if (abstractCharacter.effects != null && abstractCharacter.effects.containsKey("DeathShroud")) if (abstractCharacter.effects != null && abstractCharacter.effects.containsKey("DeathShroud"))
@@ -829,7 +799,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
//calculate speed //calculate speed
if (weaponTemplate != null) if (weaponTemplate != null)
speed = engine.parsers.objects.ItemTemplate.getWeapon(weaponTemplate.getTemplateId()).weapon_wepspeed; speed = weaponTemplate.item_weapon_wepspeed;
else else
speed = 20f; //unarmed attack speed speed = 20f; //unarmed attack speed
if (weapon != null) if (weapon != null)
@@ -884,12 +854,15 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
max *= percentMaxDamage; max *= percentMaxDamage;
} }
// Client (0x466EB0 sets char+0xD0C, 0x46D200 applies it): 30% cut only when both hands hold a WEAPON. //if duel wielding, cut damage by 30%
if (!noWeapon && otherHand != null && otherHand.template != null if (otherHand != null) {
&& otherHand.template.getItemType().equals(ItemType.WEAPON)) { ItemTemplate ibo = otherHand.template;
min *= 0.7f;
max *= 0.7f; if (ibo != null && otherHand.template.equals(ItemType.WEAPON)) {
min *= 0.7f;
max *= 0.7f;
}
} }
// calculate damage // calculate damage
@@ -955,7 +928,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
if (ItemManager.isShield(shield) == false) if (ItemManager.isShield(shield) == false)
return 0; return 0;
CObjectTemplate template = shield.template; ItemTemplate template = shield.template;
if (template == null) if (template == null)
return 0; return 0;
@@ -969,7 +942,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} else } else
skillMod = blockSkill.getModifiedAmount(); skillMod = blockSkill.getModifiedAmount();
float def = engine.parsers.objects.ItemTemplate._items.get(shield.templateID).item_defense_rating; float def = template.item_defense_rating;
//apply item defense bonuses //apply item defense bonuses
@@ -991,30 +964,29 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
if (armor == null) if (armor == null)
return 0; return 0;
CObjectTemplate template = armor.template; ItemTemplate template = armor.template;
if (template == null) if (template == null)
return 0; return 0;
if (!armor.template.getItemType().equals(ItemType.ARMOR)) if (!armor.template.item_type.equals(ItemType.ARMOR))
return 0; return 0;
// "Cloth" is a placeholder in Skills.cfg (token 0) that no character learns if (armor.template.item_skill_used.isEmpty())
if (armor.template.getItemSkillUsed().isEmpty() || armor.template.getItemSkillUsed().equals("Cloth")) return template.item_defense_rating;
return engine.parsers.objects.ItemTemplate._items.get(armor.templateID).item_defense_rating;
CharacterSkill armorSkill = abstractCharacter.skills.get(armor.template.getItemSkillUsed()); CharacterSkill armorSkill = abstractCharacter.skills.get(armor.template.item_skill_used);
if (abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter) && armorSkill == null) { if (abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter) && armorSkill == null) {
Logger.error("Player " + abstractCharacter.getObjectUUID() Logger.error("Player " + abstractCharacter.getObjectUUID()
+ " has armor equipped without the nescessary skill to equip it"); + " has armor equipped without the nescessary skill to equip it");
return engine.parsers.objects.ItemTemplate._items.get(armor.templateID).item_defense_rating; return template.item_defense_rating;
} }
if (armorSkill == null) if (armorSkill == null)
return engine.parsers.objects.ItemTemplate._items.get(armor.templateID).item_defense_rating; // Mobiles do not have armor skills @TODO return template.item_defense_rating; // Mobiles do not have armor skills @TODO
float def = engine.parsers.objects.ItemTemplate._items.get(armor.templateID).item_defense_rating; float def = template.item_defense_rating;
//apply item defense bonuses //apply item defense bonuses
@@ -1032,7 +1004,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
private static float getWeaponDefense(AbstractCharacter abstractCharacter, ConcurrentHashMap<EquipSlotType, Item> equipped) { private static float getWeaponDefense(AbstractCharacter abstractCharacter, ConcurrentHashMap<EquipSlotType, Item> equipped) {
Item weapon = equipped.get(EquipSlotType.RHELD); Item weapon = equipped.get(EquipSlotType.RHELD);
CObjectTemplate weaponTemplate = null; ItemTemplate weaponTemplate = null;
CharacterSkill skill, mastery; CharacterSkill skill, mastery;
float val = 0; float val = 0;
boolean unarmed = false; boolean unarmed = false;
@@ -1053,8 +1025,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
skill = abstractCharacter.skills.get("Unarmed Combat"); skill = abstractCharacter.skills.get("Unarmed Combat");
mastery = abstractCharacter.skills.get("Unarmed Combat Mastery"); mastery = abstractCharacter.skills.get("Unarmed Combat Mastery");
} else { } else {
skill = abstractCharacter.skills.get(weapon.template.getItemSkillUsed()); skill = abstractCharacter.skills.get(weapon.template.item_skill_used);
mastery = abstractCharacter.skills.get(weaponTemplate.getItemSkillMasteryUsed()); mastery = abstractCharacter.skills.get(weaponTemplate.item_skill_mastery_used);
} }
if (skill != null) if (skill != null)
@@ -1089,7 +1061,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
for (Item item : equipped.values()) { for (Item item : equipped.values()) {
CObjectTemplate ib = item.template; ItemTemplate ib = item.template;
if (ib == null) if (ib == null)
continue; continue;
@@ -1257,6 +1229,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
public final Resists getResists() { public final Resists getResists() {
if (this.resists == null)
return Resists.getResists(0);
return this.resists; return this.resists;
} }
@@ -1502,22 +1476,13 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
Mob mob = (Mob) this; Mob mob = (Mob) this;
if (mob.isSiege()) { if (mob.isSiege()) {
return CombatManager.getSiegeRange(mob); return 300;
} }
float range = 8; float range = 8;
if ((this).charItemManager.equipped.get(EquipSlotType.RHELD) != null) { if ((this).charItemManager.equipped.get(EquipSlotType.RHELD) != null) {
range = engine.parsers.objects.ItemTemplate.getWeapon(((Mob) this).charItemManager.equipped.get(EquipSlotType.RHELD).templateID).weapon_max_range; range = ((Mob) this).charItemManager.equipped.get(EquipSlotType.RHELD).template.item_weapon_max_range;
} else if (((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD) != null) { } else if (((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD) != null) {
range = engine.parsers.objects.ItemTemplate.getWeapon(((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD).templateID).weapon_max_range; range = ((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD).template.item_weapon_max_range;
} else {
// Unarmed: use the rune natural attack range when it has one (e.g. Gasser 150), not clamped.
// Most melee runes have 0, so they keep the default of 8.
float naturalRange = CombatManager.getNaturalAttackRange(mob, EquipSlotType.RHELD);
if (naturalRange > 0)
return naturalRange;
} }
// TODO Is this clamp from live? // TODO Is this clamp from live?
@@ -1862,15 +1827,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
if (this.getObjectType().equals(GameObjectType.Mob)) { if (this.getObjectType().equals(GameObjectType.Mob)) {
//handle hate value addition //handle hate value addition
Mob target = (Mob) this; Mob target = (Mob) this;
// Siege engines switch to whoever damages them, players and pets alike.
// Misses and non-damaging powers do not pull them.
if (target.isSiege() && value < 0f && attacker != null && !attacker.equals(target)) {
target.setCombatTarget(attacker);
flagSiegeAttackerHostile(target, attacker);
}
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter)) { if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter)) {
if (target.playerAgroMap.containsKey(attacker.getObjectUUID())) if (target.playerAgroMap.containsKey(attacker.getObjectUUID()))
@@ -1904,41 +1860,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
return 0; return 0;
} }
private static void flagSiegeAttackerHostile(Mob siegeEngine, AbstractCharacter attacker) {
// Damaging a siege engine on a city grid flags the player hostile to that
// city, unless they belong to the city's nation or an allied nation.
// Pets flag their owner.
City city;
AbstractCharacter flagged;
Guild cityNation;
city = ZoneManager.getCityAtLocation(siegeEngine.loc);
if (city == null)
return;
flagged = attacker;
if (attacker.getObjectType().equals(GameObjectType.Mob))
flagged = ((Mob) attacker).guardCaptain;
if (flagged == null || !flagged.getObjectType().equals(GameObjectType.PlayerCharacter))
return;
cityNation = city.getGuild().getNation();
if (flagged.getGuild().getNation().equals(cityNation))
return;
if (cityNation.getAllyList().contains(flagged.getGuild().getNation()))
return;
if (!city.cityOutlaws.contains(flagged.getObjectUUID()))
city.cityOutlaws.add(flagged.getObjectUUID());
}
public float getCurrentHitpoints() { public float getCurrentHitpoints() {
return this.health.get(); return this.health.get();
} }
@@ -148,20 +148,9 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
public void dismiss() { public void dismiss() {
boolean isSiegeEngine;
isSiegeEngine = this.getObjectType() == GameObjectType.Mob && ((Mob) this).isSiege();
if (this.isPet()) { if (this.isPet()) {
if (isSiegeEngine) { if ((this.agentType.equals(mbEnums.AIAgentType.PET))) { //delete summoned pet
// Released siege engines stay in place, alive, and keep firing at
// their current target until a Rod of Command takes them again.
this.agentType = mbEnums.AIAgentType.MOBILE;
} else if ((this.agentType.equals(mbEnums.AIAgentType.PET))) { //delete summoned pet
WorldGrid.RemoveWorldObject(this); WorldGrid.RemoveWorldObject(this);
@@ -178,8 +167,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
// clear owner and set not alive // clear owner and set not alive
if (!isSiegeEngine) this.isAlive.set(false);
this.isAlive.set(false);
PlayerCharacter owner = (PlayerCharacter) this.guardCaptain; PlayerCharacter owner = (PlayerCharacter) this.guardCaptain;
@@ -200,8 +188,6 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
this.guardCaptain = null; this.guardCaptain = null;
} }
if (isSiegeEngine && this.isAlive())
WorldGrid.updateObject(this);
} }
} }
+3 -3
View File
@@ -172,7 +172,7 @@ public class Account extends AbstractGameObject {
this.vault = DbManager.ItemQueries.GET_ITEMS_FOR_ACCOUNT(this.getObjectUUID()); this.vault = DbManager.ItemQueries.GET_ITEMS_FOR_ACCOUNT(this.getObjectUUID());
for (Item item : this.vault) { for (Item item : this.vault) {
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) { if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
this.vaultGold = item; this.vaultGold = item;
} }
} }
@@ -216,7 +216,7 @@ public class Account extends AbstractGameObject {
return; return;
if (item.containerType == mbEnums.ItemContainerType.INVENTORY && player.charItemManager.isVaultOpen()) { if (item.containerType == mbEnums.ItemContainerType.INVENTORY && player.charItemManager.isVaultOpen()) {
if (!player.charItemManager.hasRoomVault(item.template.getItemWt())) { if (!player.charItemManager.hasRoomVault(item.template.item_wt)) {
ItemToVaultMsgHandler.forceTransferFromVaultToInventory(msg, origin, "There is no room in your vault."); ItemToVaultMsgHandler.forceTransferFromVaultToInventory(msg, origin, "There is no room in your vault.");
return; return;
} }
@@ -262,7 +262,7 @@ public class Account extends AbstractGameObject {
return; return;
if (item.containerType == mbEnums.ItemContainerType.VAULT && itemManager.isVaultOpen()) { if (item.containerType == mbEnums.ItemContainerType.VAULT && itemManager.isVaultOpen()) {
if (!itemManager.hasRoomInventory(item.template.getItemWt())) { if (!itemManager.hasRoomInventory(item.template.item_wt)) {
ItemFromVaultMsgHandler.forceTransferFromInventoryToVault(msg, origin, "There is no room in your inventory."); ItemFromVaultMsgHandler.forceTransferFromInventoryToVault(msg, origin, "There is no room in your inventory.");
return; return;
} }
+18 -22
View File
@@ -25,7 +25,8 @@ import engine.net.client.ClientConnection;
import engine.net.client.msg.PlaceAssetMsg; import engine.net.client.msg.PlaceAssetMsg;
import engine.net.client.msg.chat.ChatSystemMsg; import engine.net.client.msg.chat.ChatSystemMsg;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.joda.time.DateTime; import java.time.LocalDateTime;
import java.time.ZoneId;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.ResultSet; import java.sql.ResultSet;
@@ -40,8 +41,8 @@ public final class Bane {
private final int cityUUID; private final int cityUUID;
private final int stoneUUID; private final int stoneUUID;
private int ownerUUID; private int ownerUUID;
private DateTime placementDate = null; private LocalDateTime placementDate = null;
private DateTime liveDate = null; private LocalDateTime liveDate = null;
private BaneDefaultTimeJob defaultTimeJob; private BaneDefaultTimeJob defaultTimeJob;
// Internal cache for banes // Internal cache for banes
@@ -62,12 +63,12 @@ public final class Bane {
sqlDateTime = rs.getTimestamp("placementDate"); sqlDateTime = rs.getTimestamp("placementDate");
if (sqlDateTime != null) if (sqlDateTime != null)
this.placementDate = new DateTime(sqlDateTime); this.placementDate = LocalDateTime.ofInstant(sqlDateTime.toInstant(), ZoneId.systemDefault());
sqlDateTime = rs.getTimestamp("liveDate"); sqlDateTime = rs.getTimestamp("liveDate");
if (sqlDateTime != null) if (sqlDateTime != null)
this.liveDate = new DateTime(sqlDateTime); this.liveDate = LocalDateTime.ofInstant(sqlDateTime.toInstant(), ZoneId.systemDefault());
switch (this.getSiegePhase()) { switch (this.getSiegePhase()) {
@@ -81,7 +82,7 @@ public final class Bane {
this.activateBaneJob.cancelJob(); this.activateBaneJob.cancelJob();
abtj = new ActivateBaneJob(cityUUID); abtj = new ActivateBaneJob(cityUUID);
JobScheduler.getInstance().scheduleJob(abtj, this.liveDate.getMillis()); JobScheduler.getInstance().scheduleJob(abtj, this.liveDate.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
this.activateBaneJob = abtj; this.activateBaneJob = abtj;
break; break;
@@ -93,7 +94,7 @@ public final class Bane {
this.activateBaneJob.cancelJob(); this.activateBaneJob.cancelJob();
abtj = new ActivateBaneJob(cityUUID); abtj = new ActivateBaneJob(cityUUID);
JobScheduler.getInstance().scheduleJob(abtj, this.liveDate.getMillis()); JobScheduler.getInstance().scheduleJob(abtj, this.liveDate.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
this.activateBaneJob = abtj; this.activateBaneJob = abtj;
break; break;
@@ -353,7 +354,7 @@ public final class Bane {
return phase; return phase;
} }
if (DateTime.now().isAfter(this.liveDate)) { if (LocalDateTime.now().isAfter(this.liveDate)) {
phase = SiegePhase.WAR; //war phase = SiegePhase.WAR; //war
return phase; return phase;
} }
@@ -368,15 +369,10 @@ public final class Bane {
private void setDefaultTime() { private void setDefaultTime() {
DateTime timeToSetDefault = new DateTime(this.placementDate); LocalDateTime timeToSetDefault = this.placementDate.plusDays(1);
timeToSetDefault = timeToSetDefault.plusDays(1);
DateTime currentTime = DateTime.now(); LocalDateTime currentTime = LocalDateTime.now();
DateTime defaultTime = new DateTime(this.placementDate); LocalDateTime defaultTime = this.placementDate.plusDays(2).withHour(22).withMinute(0).withSecond(0);
defaultTime = defaultTime.plusDays(2);
defaultTime = defaultTime.hourOfDay().setCopy(22);
defaultTime = defaultTime.minuteOfHour().setCopy(0);
defaultTime = defaultTime.secondOfMinute().setCopy(0);
if (currentTime.isAfter(timeToSetDefault)) if (currentTime.isAfter(timeToSetDefault))
this.setLiveDate(defaultTime); this.setLiveDate(defaultTime);
@@ -386,7 +382,7 @@ public final class Bane {
this.defaultTimeJob.cancelJob(); this.defaultTimeJob.cancelJob();
BaneDefaultTimeJob bdtj = new BaneDefaultTimeJob(this); BaneDefaultTimeJob bdtj = new BaneDefaultTimeJob(this);
JobScheduler.getInstance().scheduleJob(bdtj, timeToSetDefault.getMillis()); JobScheduler.getInstance().scheduleJob(bdtj, timeToSetDefault.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
this.defaultTimeJob = bdtj; this.defaultTimeJob = bdtj;
} }
} }
@@ -453,7 +449,7 @@ public final class Bane {
return true; return true;
} }
public final DateTime getPlacementDate() { public final LocalDateTime getPlacementDate() {
return placementDate; return placementDate;
} }
@@ -462,14 +458,14 @@ public final class Bane {
return (this.getSiegePhase() != SiegePhase.CHALLENGE); return (this.getSiegePhase() != SiegePhase.CHALLENGE);
} }
public final DateTime getLiveDate() { public final LocalDateTime getLiveDate() {
return liveDate; return liveDate;
} }
public void setLiveDate(DateTime baneTime) { public void setLiveDate(LocalDateTime baneTime) {
if (DbManager.BaneQueries.SET_BANE_TIME(baneTime, this.getCity().getObjectUUID())) { if (DbManager.BaneQueries.SET_BANE_TIME(baneTime, this.getCity().getObjectUUID())) {
this.liveDate = new DateTime(baneTime); this.liveDate = baneTime;
// Push event to warehouse // Push event to warehouse
@@ -511,7 +507,7 @@ public final class Bane {
ActivateBaneJob abtj = new ActivateBaneJob(cityUUID); ActivateBaneJob abtj = new ActivateBaneJob(cityUUID);
JobScheduler.getInstance().scheduleJob(abtj, this.liveDate.getMillis()); JobScheduler.getInstance().scheduleJob(abtj, this.liveDate.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
this.activateBaneJob = abtj; this.activateBaneJob = abtj;
} else { } else {
Logger.debug("error with city " + this.getCity().getName()); Logger.debug("error with city " + this.getCity().getName());
+28 -33
View File
@@ -10,12 +10,10 @@
package engine.objects; package engine.objects;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.mbEnums;
import engine.net.ByteBufferWriter; import engine.net.ByteBufferWriter;
import engine.parsers.objects.RuneTemplate;
import engine.util.Hasher;
import org.pmw.tinylog.Logger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -84,41 +82,30 @@ public class BaseClass extends AbstractGameObject {
/** /**
* Rune Template Constructor * ResultSet Constructor
*/ */
public BaseClass(RuneTemplate rune) { public BaseClass(ResultSet rs) throws SQLException {
super(rune.template_id); super(rs);
this.name = rune.obj_name; this.name = rs.getString("name");
this.description = rune.rune_dsc; this.description = rs.getString("description");
this.strMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Strength, 0).byteValue(); this.strMod = rs.getByte("strMod");
this.dexMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Dexterity, 0).byteValue(); this.dexMod = rs.getByte("dexMod");
this.conMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Constitution, 0).byteValue(); this.conMod = rs.getByte("conMod");
this.intMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Intelligence, 0).byteValue(); this.intMod = rs.getByte("intMod");
this.spiMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Spirit, 0).byteValue(); this.spiMod = rs.getByte("spiMod");
this.token = Hasher.SBStringHash(rune.rune_sub_type); this.token = rs.getInt("token");
this.healthMod = rune.rune_health; this.healthMod = rs.getInt("healthMod");
this.manaMod = rune.rune_mana; this.manaMod = rs.getInt("manaMod");
this.staminaMod = rune.rune_stamina; this.staminaMod = rs.getInt("staminaMod");
this.skillsGranted = SkillReq.getSkillReqsForRune(this.getObjectUUID()); this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.getObjectUUID());
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID()); this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
this.effectsList = MobBaseEffects.getEffectsForRune(this.getObjectUUID()); this.effectsList = (DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID()));
} }
public static void LoadAllBaseClasses() { public static void LoadAllBaseClasses() {
DbManager.BaseClassQueries.GET_ALL_BASE_CLASSES();
int loadedCount = 0;
// Promotion classes and the Pet class are also CLASS runes, but not standard creation runes
for (RuneTemplate rune : RuneTemplate._runes.values()) {
if (rune.rune_type != mbEnums.RuneType.CLASS || !rune.rune_is_standard_character_creation)
continue;
DbManager.addToCache(new BaseClass(rune));
loadedCount++;
}
Logger.info("Loaded " + loadedCount + " base classes from runes");
} }
public static void serializeForClientMsg(BaseClass baseClass, ByteBufferWriter writer) { public static void serializeForClientMsg(BaseClass baseClass, ByteBufferWriter writer) {
@@ -200,6 +187,10 @@ public class BaseClass extends AbstractGameObject {
return this.powersGranted; return this.powersGranted;
} }
public ArrayList<RuneBaseEffect> getEffectsGranted() {
return RuneBaseEffect.RuneIDBaseEffectMap.get(this.getObjectUUID());
}
/* /*
* Utils * Utils
*/ */
@@ -208,6 +199,10 @@ public class BaseClass extends AbstractGameObject {
if (this.getRuneList().contains(rb.getObjectUUID())) if (this.getRuneList().contains(rb.getObjectUUID()))
return true; return true;
if (RuneBase.AllowedBaseClassRunesMap.containsKey(111111)) {
if (RuneBase.AllowedBaseClassRunesMap.get(111111).contains(rb.getObjectUUID()))
return true;
}
return false; return false;
} }
+1 -4
View File
@@ -395,10 +395,8 @@ public class Building extends AbstractWorldObject {
//friendly building has been attacked, add attacker to city outlaw list //friendly building has been attacked, add attacker to city outlaw list
if (!playerCity.cityOutlaws.contains(attacker.getObjectUUID()) && attacker.getObjectType().equals(GameObjectType.PlayerCharacter)) if (!playerCity.cityOutlaws.contains(attacker.getObjectUUID()) && attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
playerCity.cityOutlaws.add(attacker.getObjectUUID()); playerCity.cityOutlaws.add(attacker.getObjectUUID());
//only city guards respond; siege engines and pets in the zone are left alone
for (Mob guard : playerCity.getParent().zoneMobSet) for (Mob guard : playerCity.getParent().zoneMobSet)
if (guard.isPlayerGuard() && guard.combatTarget == null) if (guard.combatTarget == null)
guard.setCombatTarget(attacker); guard.setCombatTarget(attacker);
} }
} }
@@ -433,7 +431,6 @@ public class Building extends AbstractWorldObject {
// Special handling of warehouses // Special handling of warehouses
if (blueprint.getBuildingGroup() == BuildingGroup.WAREHOUSE) { if (blueprint.getBuildingGroup() == BuildingGroup.WAREHOUSE) {
Warehouse.destroyedWarehouses.put(this.getObjectUUID(), city.warehouse);
DbManager.WarehouseQueries.DELETE_WAREHOUSE(city.warehouse); DbManager.WarehouseQueries.DELETE_WAREHOUSE(city.warehouse);
city.warehouse = null; city.warehouse = null;
} }
+33 -34
View File
@@ -17,7 +17,6 @@ import engine.mbEnums.ItemType;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.*; import engine.net.client.msg.*;
import engine.parsers.objects.CObjectTemplate;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -131,19 +130,19 @@ public class CharacterItemManager {
this.equipped.put(i.equipSlot, i); this.equipped.put(i.equipSlot, i);
break; break;
case BANK: case BANK:
if (i.template.getItemType().equals(ItemType.GOLD)) if (i.template.item_type.equals(ItemType.GOLD))
this.goldBank = i; this.goldBank = i;
else if (this.bank.contains(i) == false) else if (this.bank.contains(i) == false)
this.bank.add(i); this.bank.add(i);
break; break;
case INVENTORY: case INVENTORY:
if (i.template.getItemType().equals(ItemType.GOLD)) if (i.template.item_type.equals(ItemType.GOLD))
this.goldInventory = i; this.goldInventory = i;
else if (this.inventory.contains(i) == false) else if (this.inventory.contains(i) == false)
this.inventory.add(i); this.inventory.add(i);
break; break;
case VAULT: case VAULT:
if (i.template.getItemType().equals(ItemType.GOLD)) if (i.template.item_type.equals(ItemType.GOLD))
this.goldVault = i; this.goldVault = i;
else if (this.vault.contains(i) == false) else if (this.vault.contains(i) == false)
this.vault.add(i); this.vault.add(i);
@@ -176,13 +175,13 @@ public class CharacterItemManager {
this.equipped.put(i.equipSlot, i); this.equipped.put(i.equipSlot, i);
break; break;
case BANK: case BANK:
if (i.template.getItemType().equals(ItemType.GOLD)) if (i.template.item_type.equals(ItemType.GOLD))
this.goldBank = i; this.goldBank = i;
else if (this.bank.contains(i) == false) else if (this.bank.contains(i) == false)
this.bank.add(i); this.bank.add(i);
break; break;
case INVENTORY: case INVENTORY:
if (i.template.getItemType().equals(ItemType.GOLD)) if (i.template.item_type.equals(ItemType.GOLD))
this.goldInventory = i; this.goldInventory = i;
else if (this.inventory.contains(i) == false) else if (this.inventory.contains(i) == false)
this.inventory.add(i); this.inventory.add(i);
@@ -512,7 +511,7 @@ public class CharacterItemManager {
if (i == null) if (i == null)
return false; return false;
if (i.template.getItemType().equals(ItemType.GOLD)) { if (i.template.item_type.equals(ItemType.GOLD)) {
if (this.getGoldInventory() != null) { if (this.getGoldInventory() != null) {
if (i.getObjectUUID() == this.getGoldInventory().getObjectUUID()) if (i.getObjectUUID() == this.getGoldInventory().getObjectUUID())
this.goldInventory = null; this.goldInventory = null;
@@ -542,7 +541,7 @@ public class CharacterItemManager {
} }
private synchronized boolean junk(Item i, boolean updateInventory) { private synchronized boolean junk(Item i, boolean updateInventory) {
if (i.template.getItemType().equals(ItemType.GOLD)) { if (i.template.item_type.equals(ItemType.GOLD)) {
if (this.getGoldInventory().getObjectUUID() == i.getObjectUUID()) if (this.getGoldInventory().getObjectUUID() == i.getObjectUUID())
if (DbManager.ItemQueries.UPDATE_GOLD(i, 0)) { if (DbManager.ItemQueries.UPDATE_GOLD(i, 0)) {
this.getGoldInventory().setNumOfItems(0); this.getGoldInventory().setNumOfItems(0);
@@ -597,7 +596,7 @@ public class CharacterItemManager {
if (equippedContains(item)) { if (equippedContains(item)) {
fromEquip = true; fromEquip = true;
if (item.template.getItemType().equals(ItemType.GOLD)) if (item.template.item_type.equals(ItemType.GOLD))
this.absCharacter.cancelOnUnEquip(); this.absCharacter.cancelOnUnEquip();
} }
@@ -815,7 +814,7 @@ public class CharacterItemManager {
// This removes ingame item from inventory for loot. // This removes ingame item from inventory for loot.
private synchronized boolean removeItemFromInventory(Item i) { private synchronized boolean removeItemFromInventory(Item i) {
if (i.template.getItemType().equals(ItemType.GOLD)) { if (i.template.item_type.equals(ItemType.GOLD)) {
if (i.getObjectUUID() != this.getGoldInventory().getObjectUUID()) if (i.getObjectUUID() != this.getGoldInventory().getObjectUUID())
return false; return false;
if (!DbManager.ItemQueries.UPDATE_GOLD(this.goldInventory, 0)) { if (!DbManager.ItemQueries.UPDATE_GOLD(this.goldInventory, 0)) {
@@ -838,7 +837,7 @@ public class CharacterItemManager {
// This adds item to inventory for loot. Validity checks already handled // This adds item to inventory for loot. Validity checks already handled
public synchronized boolean addItemToInventory(Item i) { public synchronized boolean addItemToInventory(Item i) {
if (i.template.getItemType().equals(ItemType.GOLD)) if (i.template.item_type.equals(ItemType.GOLD))
if (this.absCharacter.getObjectType() == GameObjectType.Mob) { if (this.absCharacter.getObjectType() == GameObjectType.Mob) {
if (this.goldInventory == null) if (this.goldInventory == null)
loadGoldItems(); loadGoldItems();
@@ -857,7 +856,7 @@ public class CharacterItemManager {
this.itemIDtoType.put(i.getObjectUUID(), i.getObjectType().ordinal()); this.itemIDtoType.put(i.getObjectUUID(), i.getObjectType().ordinal());
if (i.template != null) if (i.template != null)
this.inventoryWeight += i.template.getItemWt(); this.inventoryWeight += i.template.item_wt;
return true; return true;
} }
@@ -1042,7 +1041,7 @@ public class CharacterItemManager {
if (npc.getContractID() >= 1900 && npc.getContractID() <= 1906) if (npc.getContractID() >= 1900 && npc.getContractID() <= 1906)
eatItem = true; eatItem = true;
if (itemToSell.template.getItemType().equals(ItemType.POTION)) if (itemToSell.template.item_type.equals(ItemType.POTION))
eatItem = true; eatItem = true;
if (eatItem) { if (eatItem) {
@@ -1086,14 +1085,14 @@ public class CharacterItemManager {
synchronized (this) { synchronized (this) {
synchronized (itemMan) { synchronized (itemMan) {
CObjectTemplate template = purchasedItem.template; ItemTemplate template = purchasedItem.template;
if (template == null) if (template == null)
return false; return false;
//test inventory is not full //test inventory is not full
if (!hasRoomInventory(template.getItemWt())) if (!hasRoomInventory(template.item_wt))
return false; return false;
if (!itemMan.inventory.contains(purchasedItem)) if (!itemMan.inventory.contains(purchasedItem))
@@ -1106,8 +1105,8 @@ public class CharacterItemManager {
// Reset value // Reset value
purchasedItem.value = (int) (purchasedItem.template.getItemValue() * (purchasedItem.combat_health_current / purchasedItem.template.getCombatHealthFull())); purchasedItem.value = (int) (purchasedItem.template.item_value * (purchasedItem.combat_health_current / purchasedItem.template.combat_health_full));
purchasedItem.magicValue = purchasedItem.template.getItemValue() + purchasedItem.calcMagicValue(); purchasedItem.magicValue = purchasedItem.template.item_value + purchasedItem.calcMagicValue();
// db transfer successfully, remove from this character // db transfer successfully, remove from this character
// skip this check if this is a mobLoot item (which is not in any inventory) // skip this check if this is a mobLoot item (which is not in any inventory)
@@ -1185,9 +1184,9 @@ public class CharacterItemManager {
synchronized (lockFirst) { synchronized (lockFirst) {
synchronized (lockSecond) { synchronized (lockSecond) {
// make sure current player has item in inventory // make sure current player has item in inventory
if (lootItem.template.getItemType().equals(ItemType.GOLD) && lootItem.getObjectUUID() != this.getGoldInventory().getObjectUUID() && !(this.absCharacter.getObjectType().equals(GameObjectType.Mob))) if (lootItem.template.item_type.equals(ItemType.GOLD) && lootItem.getObjectUUID() != this.getGoldInventory().getObjectUUID() && !(this.absCharacter.getObjectType().equals(GameObjectType.Mob)))
return null; return null;
else if (!this.inventory.contains(lootItem) && !this.equipped.containsValue(lootItem) && !lootItem.template.getItemType().equals(ItemType.GOLD)) else if (!this.inventory.contains(lootItem) && !this.equipped.containsValue(lootItem) && !lootItem.template.item_type.equals(ItemType.GOLD))
return null; return null;
// get weight of item // get weight of item
@@ -1195,13 +1194,13 @@ public class CharacterItemManager {
if (lootItem.template == null) if (lootItem.template == null)
return null; return null;
int weight = lootItem.template.getItemWt(); int weight = lootItem.template.item_wt;
// make sure lootingPlayer has room for item // make sure lootingPlayer has room for item
if (!lootItem.template.getItemType().equals(ItemType.GOLD) && !looterItems.hasRoomInventory(weight)) if (!lootItem.template.item_type.equals(ItemType.GOLD) && !looterItems.hasRoomInventory(weight))
return null; return null;
if (lootItem.template.getItemType().equals(ItemType.GOLD)) if (lootItem.template.item_type.equals(ItemType.GOLD))
if (amount != -1) { //from steal if (amount != -1) { //from steal
int total = lootItem.getNumOfItems(); int total = lootItem.getNumOfItems();
amount = (amount > total) ? total : amount; amount = (amount > total) ? total : amount;
@@ -1264,19 +1263,19 @@ public class CharacterItemManager {
* Delegates * Delegates
*/ */
public synchronized boolean bankContains(Item item) { public synchronized boolean bankContains(Item item) {
if (item.template.getItemType().equals(ItemType.GOLD)) if (item.template.item_type.equals(ItemType.GOLD))
return (this.getGoldBank() != null && this.goldBank.getObjectUUID() == item.getObjectUUID()); return (this.getGoldBank() != null && this.goldBank.getObjectUUID() == item.getObjectUUID());
return bank.contains(item); return bank.contains(item);
} }
public synchronized boolean inventoryContains(Item item) { public synchronized boolean inventoryContains(Item item) {
if (item.template.getItemType().equals(ItemType.GOLD)) if (item.template.item_type.equals(ItemType.GOLD))
return (this.getGoldInventory() != null && this.goldInventory.getObjectUUID() == item.getObjectUUID()); return (this.getGoldInventory() != null && this.goldInventory.getObjectUUID() == item.getObjectUUID());
return inventory.contains(item); return inventory.contains(item);
} }
public synchronized boolean vaultContains(Item item) { public synchronized boolean vaultContains(Item item) {
if (item.template.getItemType().equals(ItemType.GOLD)) if (item.template.item_type.equals(ItemType.GOLD))
return (this.getGoldVault() != null && this.goldVault.getObjectUUID() == item.getObjectUUID()); return (this.getGoldVault() != null && this.goldVault.getObjectUUID() == item.getObjectUUID());
return this.account.getVault().contains(item); return this.account.getVault().contains(item);
} }
@@ -1519,13 +1518,13 @@ public class CharacterItemManager {
item.zeroItem(); item.zeroItem();
item.containerType = mbEnums.ItemContainerType.INVENTORY; item.containerType = mbEnums.ItemContainerType.INVENTORY;
if (item.template.getItemType().equals(ItemType.GOLD)) if (item.template.item_type.equals(ItemType.GOLD))
//only add gold item once //only add gold item once
if (!corpse.hasGold()) if (!corpse.hasGold())
corpse.setHasGold(true); corpse.setHasGold(true);
newInventory.add(item); newInventory.add(item);
} else //item } else //item
if (item.template.getItemType().equals(ItemType.GOLD)) { if (item.template.item_type.equals(ItemType.GOLD)) {
int amt = item.getNumOfItems(); int amt = item.getNumOfItems();
item.setNumOfItems(0); item.setNumOfItems(0);
MobLoot ml = new MobLoot(this.absCharacter, amt); MobLoot ml = new MobLoot(this.absCharacter, amt);
@@ -1677,7 +1676,7 @@ public class CharacterItemManager {
if (item == null) if (item == null)
continue; continue;
weight += item.template.getItemWt(); weight += item.template.item_wt;
} }
return weight; return weight;
} }
@@ -1697,7 +1696,7 @@ public class CharacterItemManager {
this.bankWeight = 0; this.bankWeight = 0;
for (Item item : this.bank) { for (Item item : this.bank) {
if (item.template != null) if (item.template != null)
this.bankWeight += item.template.getItemWt(); this.bankWeight += item.template.item_wt;
} }
} }
@@ -1708,7 +1707,7 @@ public class CharacterItemManager {
while (it.hasNext()) { while (it.hasNext()) {
Item item = it.next(); Item item = it.next();
if (item.template != null) if (item.template != null)
this.equipWeight += item.template.getItemWt(); this.equipWeight += item.template.item_wt;
} }
} }
@@ -1716,7 +1715,7 @@ public class CharacterItemManager {
this.inventoryWeight = 0; this.inventoryWeight = 0;
for (Item item : this.inventory) { for (Item item : this.inventory) {
if (item.template != null) if (item.template != null)
this.inventoryWeight += item.template.getItemWt(); this.inventoryWeight += item.template.item_wt;
} }
} }
@@ -1724,7 +1723,7 @@ public class CharacterItemManager {
this.vaultWeight = 0; this.vaultWeight = 0;
for (Item item : this.vault) { for (Item item : this.vault) {
if (item.template != null) if (item.template != null)
this.vaultWeight += item.template.getItemWt(); this.vaultWeight += item.template.item_wt;
} }
} }
@@ -1756,7 +1755,7 @@ public class CharacterItemManager {
return; return;
if (!item.moveItemToInventory(player)) if (!item.moveItemToInventory(player))
Logger.error("templateL " + item.template.getTemplateId()); Logger.error("templateL " + item.template.template_id);
// remove it from other lists: // remove it from other lists:
this.remItemFromLists(item); this.remItemFromLists(item);
@@ -1933,7 +1932,7 @@ public class CharacterItemManager {
return; return;
//don't damage noob gear, hair or beards. //don't damage noob gear, hair or beards.
if (item.template.getCombatHealthFull() == 0) if (item.template.combat_health_full == 0)
return; return;
if (!item.isCanDestroy()) if (!item.isCanDestroy())
+1 -1
View File
@@ -334,7 +334,7 @@ public class CharacterPower extends AbstractGameObject {
// return pc.getBonuses().getByte("gt." + this.power.getToken()); // return pc.getBonuses().getByte("gt." + this.power.getToken());
// } else // } else
// return pc.getBonuses().getByte("gt." + this.power.getToken()); // return pc.getBonuses().getByte("gt." + this.power.getToken());
return PowerGrantedTrains.getGrantedTrains(this.power.getToken(), pc); return PowerGrant.getGrantedTrains(this.power.getToken(), pc);
} else } else
return 0; return 0;
} }
+18 -3
View File
@@ -27,6 +27,7 @@ public class CharacterRune extends AbstractGameObject {
private final int player; private final int player;
private final ArrayList<SkillReq> skillsGranted; private final ArrayList<SkillReq> skillsGranted;
private final ArrayList<PowerReq> powersGranted; private final ArrayList<PowerReq> powersGranted;
private final ArrayList<RuneBaseEffect> effectsGranted;
/** /**
* No Table ID Constructor * No Table ID Constructor
@@ -36,12 +37,16 @@ public class CharacterRune extends AbstractGameObject {
this.runeBase = runeBase; this.runeBase = runeBase;
this.player = characterID; this.player = characterID;
if (this.runeBase != null) { if (this.runeBase != null) {
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID()); this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID()); this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
} else { } else {
this.skillsGranted = new ArrayList<>(); this.skillsGranted = new ArrayList<>();
this.powersGranted = 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<>();
} }
/** /**
@@ -52,12 +57,16 @@ public class CharacterRune extends AbstractGameObject {
this.runeBase = runeBase; this.runeBase = runeBase;
this.player = characterID; this.player = characterID;
if (this.runeBase != null) { if (this.runeBase != null) {
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID()); this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID()); this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
} else { } else {
this.skillsGranted = new ArrayList<>(); this.skillsGranted = new ArrayList<>();
this.powersGranted = 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<>();
} }
/** /**
@@ -69,12 +78,14 @@ public class CharacterRune extends AbstractGameObject {
this.runeBase = RuneBase.getRuneBase(rs.getInt("RuneBaseID")); this.runeBase = RuneBase.getRuneBase(rs.getInt("RuneBaseID"));
this.player = rs.getInt("CharacterID"); this.player = rs.getInt("CharacterID");
if (this.runeBase != null) { if (this.runeBase != null) {
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID()); this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID()); this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
} else { } else {
Logger.error("Failed to find RuneBase for CharacterRune " + this.getObjectUUID()); Logger.error("Failed to find RuneBase for CharacterRune " + this.getObjectUUID());
this.skillsGranted = new ArrayList<>(); this.skillsGranted = new ArrayList<>();
this.powersGranted = new ArrayList<>(); this.powersGranted = new ArrayList<>();
this.effectsGranted = new ArrayList<>();
} }
} }
@@ -189,6 +200,10 @@ public class CharacterRune extends AbstractGameObject {
return this.powersGranted; return this.powersGranted;
} }
public ArrayList<RuneBaseEffect> getEffectsGranted() {
return this.effectsGranted;
}
@Override @Override
public void updateDatabase() { public void updateDatabase() {
DbManager.CharacterRuneQueries.updateDatabase(this); DbManager.CharacterRuneQueries.updateDatabase(this);
+6 -9
View File
@@ -1043,15 +1043,15 @@ public class CharacterSkill extends AbstractGameObject {
if (this.skillsBase.getStrMod() > 0) if (this.skillsBase.getStrMod() > 0)
statMod += (float) this.skillsBase.getStrMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Strength) / 100f; statMod += (float) this.skillsBase.getStrMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseStr() / 100f;
if (this.skillsBase.getDexMod() > 0) if (this.skillsBase.getDexMod() > 0)
statMod += (float) this.skillsBase.getDexMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Dexterity) / 100f; statMod += (float) this.skillsBase.getDexMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseDex() / 100f;
if (this.skillsBase.getConMod() > 0) if (this.skillsBase.getConMod() > 0)
statMod += (float) this.skillsBase.getConMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Constitution) / 100f; statMod += (float) this.skillsBase.getConMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseCon() / 100f;
if (this.skillsBase.getIntMod() > 0) if (this.skillsBase.getIntMod() > 0)
statMod += (float) this.skillsBase.getIntMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Intelligence) / 100f; statMod += (float) this.skillsBase.getIntMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseInt() / 100f;
if (this.skillsBase.getSpiMod() > 0) if (this.skillsBase.getSpiMod() > 0)
statMod += (float) this.skillsBase.getSpiMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Spirit) / 100f; statMod += (float) this.skillsBase.getSpiMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseSpi() / 100f;
if (statMod < 1) if (statMod < 1)
statMod = 1f; statMod = 1f;
else if (statMod > 600) else if (statMod > 600)
@@ -1136,12 +1136,9 @@ public class CharacterSkill extends AbstractGameObject {
Logger.error("SkillsBase not found for skill " + this.getObjectUUID()); Logger.error("SkillsBase not found for skill " + this.getObjectUUID());
this.modifiedAmount = this.baseAmount; this.modifiedAmount = this.baseAmount;
} }
return calculateAmountAfterTrains(this.numTrains.get());
}
public float calculateAmountAfterTrains(int trains) {
int amount; int amount;
int trains = this.numTrains.get();
if (trains < 10) if (trains < 10)
amount = (trains * 2); amount = (trains * 2);
else if (trains < 90) else if (trains < 90)
+3 -3
View File
@@ -296,14 +296,14 @@ public class Corpse extends AbstractWorldObject {
//get weight of item //get weight of item
int weight = item.template.getItemWt(); int weight = item.template.item_wt;
//make sure looter has room for item //make sure looter has room for item
if (item.template.getItemType().equals(ItemType.GOLD) == false && !looterItems.hasRoomInventory(weight)) if (item.template.item_type.equals(ItemType.GOLD) == false && !looterItems.hasRoomInventory(weight))
return null; return null;
//attempt to transfer item in db //attempt to transfer item in db
if (item.template.getItemType().equals(ItemType.GOLD)) { if (item.template.item_type.equals(ItemType.GOLD)) {
if (!looterItems.moveGoldToInventory(item, item.getNumOfItems())) if (!looterItems.moveGoldToInventory(item, item.getNumOfItems()))
return null; return null;
} else if (!item.moveItemToInventory(looter)) } else if (!item.moveItemToInventory(looter))
@@ -0,0 +1,73 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://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;
}
}
+121 -41
View File
@@ -12,17 +12,114 @@ package engine.objects;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums.TargetColor; import engine.mbEnums.TargetColor;
import engine.parsers.objects.RuneTemplate;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.TreeMap;
import static engine.gameManager.LootManager.LOOTMANAGER; import static engine.gameManager.LootManager.LOOTMANAGER;
public class Experience { public class Experience {
// Client ArcCharacter_ExpForLevelUp (0x4715D0) float constant at 0x154195C private static final TreeMap<Integer, Integer> ExpToLevel;
private static final float EXP_LEVEL_SLOPE = 0.0512f; 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 private static final float[] MaxExpPerLevel = {Float.MIN_VALUE, // Pad
// everything // everything
// over // over
@@ -130,56 +227,39 @@ public class Experience {
// (expGranted / group.size()) * (groupBonus * (group.size()-1) +1) // (expGranted / group.size()) * (groupBonus * (group.size()-1) +1)
private static final float GROUP_BONUS = 0.5f; // 0.2 grants (20%) addtional private static final float GROUP_BONUS = 0.5f; // 0.2 grants (20%) addtional
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
// exp per group member // exp per group member
// called to determine current level based on xp // called to determine current level based on xp
public static int getLevel(PlayerCharacter player, int experience) { public static int getLevel(int experience) {
int level = 1; int expKey = ExpToLevel.floorKey(experience);
int level = ExpToLevel.get(expKey);
while (level < MBServerStatics.LEVELCAP && experience >= getBaseExperience(player, level + 1)) if (level > MBServerStatics.LEVELCAP)
level++; level = MBServerStatics.LEVELCAP;
return level; return level;
} }
// The client function returns the XP to reach level + 1, so it is called with level - 1. // Get the base xp for a level
// Arithmetic order and the half-up rounding follow the client so every threshold matches. public static int getBaseExperience(int level) {
public static int getBaseExperience(PlayerCharacter player, int level) {
int clientLevel = level - 1; if (level < LevelToExp.length)
double levelScale; return LevelToExp[level];
levelScale = Math.max(1.0, (clientLevel - 39) * (double) EXP_LEVEL_SLOPE + 1.0); int fLevel = level - 1;
int baseXP = fLevel * fLevel * fLevel;
return (int) (long) ((double) clientLevel * clientLevel * clientLevel * levelScale return (int) ((fLevel < 40) ? (baseXP * 150)
* getClassExpFactor(player) * getRaceExpFactor(player) + 0.5); : (baseXP * (150 + (7.6799998 * (level - 40)))));
}
// rune_exp_req_to_level; the client uses 1.0 when the rune is missing
private static double getRaceExpFactor(PlayerCharacter player) {
RuneTemplate rune = null;
if (player.race != null)
rune = RuneTemplate._runes.get(player.race.getRaceRuneID());
return (rune == null) ? 1.0 : rune.rune_exp_req_to_level;
}
// GUESS: the client's class rune (0x45EAD0) is the promotion once taken; every CLASS rune is 15 either way.
// The CSR promotions 2901+ have no rune, so they fall back to the base class.
private static double getClassExpFactor(PlayerCharacter player) {
RuneTemplate rune = null;
if (player.promotionClass != null)
rune = RuneTemplate._runes.get(player.promotionClass.getObjectUUID());
if (rune == null && player.baseClass != null)
rune = RuneTemplate._runes.get(player.baseClass.getObjectUUID());
return (rune == null) ? 1.0 : rune.rune_exp_req_to_level;
} }
// Max XP granted for killing a blue, yellow or orange mob // Max XP granted for killing a blue, yellow or orange mob
+3 -3
View File
@@ -22,7 +22,7 @@ import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.UpdateClientAlliancesMsg; import engine.net.client.msg.UpdateClientAlliancesMsg;
import engine.net.client.msg.guild.GuildInfoMsg; import engine.net.client.msg.guild.GuildInfoMsg;
import engine.server.world.WorldServer; import engine.server.world.WorldServer;
import org.joda.time.DateTime; import java.time.Instant;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.ResultSet; import java.sql.ResultSet;
@@ -612,8 +612,8 @@ public class Guild extends AbstractWorldObject {
//Add to Guild History //Add to Guild History
if (pc.getGuild() != null) { if (pc.getGuild() != null) {
if (DbManager.GuildQueries.ADD_TO_GUILDHISTORY(pc.getGuildUUID(), pc, DateTime.now(), historyType)) { if (DbManager.GuildQueries.ADD_TO_GUILDHISTORY(pc.getGuildUUID(), pc, Instant.now(), historyType)) {
GuildHistory guildHistory = new GuildHistory(pc.getGuildUUID(), pc.getGuild().name, DateTime.now(), historyType); GuildHistory guildHistory = new GuildHistory(pc.getGuildUUID(), pc.getGuild().name, Instant.now(), historyType);
pc.getGuildHistory().add(guildHistory); pc.getGuildHistory().add(guildHistory);
} }
} }
Loaded 100 of 287 files, more files were not shown because too many files have changed in this diff. Show more