Compare commits
172
Commits
No files matched your search
@@ -118,11 +118,6 @@ public class WorldGrid {
|
||||
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) {
|
||||
HashSet<AbstractWorldObject> outbound = getObjectsInRangePartial(loc, r, mask);
|
||||
return outbound;
|
||||
|
||||
@@ -13,13 +13,7 @@ import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
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 {
|
||||
|
||||
@@ -33,59 +27,6 @@ public class dbBaseClassHandler extends dbHandlerBase {
|
||||
if (id == 0)
|
||||
return null;
|
||||
|
||||
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;
|
||||
return (BaseClass) DbManager.getFromCache(GameObjectType.BaseClass, id);
|
||||
}
|
||||
}
|
||||
@@ -1,303 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,8 +16,6 @@ import engine.mbEnums.ItemType;
|
||||
import engine.objects.AbstractCharacter;
|
||||
import engine.objects.CharacterItemManager;
|
||||
import engine.objects.Item;
|
||||
import engine.objects.ItemTemplate;
|
||||
import org.json.JSONObject;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
@@ -177,47 +175,23 @@ public class dbItemHandler extends dbHandlerBase {
|
||||
return itemList;
|
||||
}
|
||||
|
||||
public void LOAD_ITEM_TEMPLATES() {
|
||||
public HashMap<Integer, Integer> LOAD_TEMPLATE_MODTABLES() {
|
||||
|
||||
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() {
|
||||
HashMap<Integer, Integer> modTables = new HashMap<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_vendor_items`;");
|
||||
ResultSet rs = preparedStatement.executeQuery()) {
|
||||
|
||||
while (rs.next()) {
|
||||
int templateID = rs.getInt("templateID");
|
||||
int modTable = rs.getInt("modTable");
|
||||
ItemTemplate template = ItemTemplate.templates.get(templateID);
|
||||
template.modTable = modTable;
|
||||
}
|
||||
while (rs.next())
|
||||
modTables.put(rs.getInt("templateID"), rs.getInt("modTable"));
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
Logger.info("read: " + modTables.size());
|
||||
return modTables;
|
||||
}
|
||||
|
||||
public Item GET_ITEM(final int itemUUID) {
|
||||
@@ -325,7 +299,7 @@ public class dbItemHandler extends dbHandlerBase {
|
||||
|
||||
for (Item item : inventory) {
|
||||
|
||||
if (item.template.item_type.equals(ItemType.GOLD))
|
||||
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||
continue;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
@@ -474,7 +448,7 @@ public class dbItemHandler extends dbHandlerBase {
|
||||
*/
|
||||
public boolean UPDATE_GOLD(final Item item, int newValue, int oldValue) {
|
||||
|
||||
if (!item.template.item_type.equals(ItemType.GOLD))
|
||||
if (!item.template.getItemType().equals(ItemType.GOLD))
|
||||
return false;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
@@ -554,7 +528,7 @@ public class dbItemHandler extends dbHandlerBase {
|
||||
|
||||
// Write 0 if we will not modify the value from template
|
||||
|
||||
if (value == item.template.item_value)
|
||||
if (value == item.template.getItemValue())
|
||||
value = 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@ package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.loot.*;
|
||||
import engine.objects.Item;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
@@ -221,20 +220,4 @@ public class dbLootHandler extends dbHandlerBase {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,8 +13,6 @@ import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.objects.MobBase;
|
||||
import engine.objects.MobBaseEffects;
|
||||
import engine.objects.MobBaseStats;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
@@ -69,71 +67,10 @@ public class dbMobBaseHandler extends dbHandlerBase {
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
Logger.info("Loaded " + mobbaseList.size() + " mobbases");
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ public class dbNPCHandler extends dbHandlerBase {
|
||||
runeSets.put(runeSetID, runeList);
|
||||
} else {
|
||||
ArrayList<Integer> runeList = runeSets.get(runeSetID);
|
||||
runeList.add(runeSetID);
|
||||
runeList.add(runeBaseID);
|
||||
runeSets.put(runeSetID, runeList);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// 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,30 +27,17 @@ public class dbPromotionClassHandler extends dbHandlerBase {
|
||||
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) {
|
||||
|
||||
PromotionClass promotionClass = null;
|
||||
PromotionClass promotionClass;
|
||||
|
||||
if (objectUUID == 0)
|
||||
return null;
|
||||
|
||||
promotionClass = (PromotionClass) DbManager.getFromCache(mbEnums.GameObjectType.PromotionClass, objectUUID);
|
||||
|
||||
if (promotionClass != null)
|
||||
return promotionClass;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_promotion` WHERE `ID` = ?")) {
|
||||
|
||||
@@ -10,15 +10,14 @@
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.objects.Race;
|
||||
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;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class dbRaceHandler extends dbHandlerBase {
|
||||
|
||||
@@ -46,27 +45,6 @@ public class dbRaceHandler extends dbHandlerBase {
|
||||
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) {
|
||||
|
||||
HashSet<Integer> integerSet = new HashSet<>();
|
||||
@@ -89,28 +67,6 @@ 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) {
|
||||
|
||||
HashSet<Integer> integerSet = new HashSet<>();
|
||||
@@ -132,32 +88,23 @@ public class dbRaceHandler extends dbHandlerBase {
|
||||
return integerSet;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<Integer, Race> LOAD_ALL_RACES() {
|
||||
// Rune id -> {minHeight, strHeightMod}; the rows also decide which race runes are player races
|
||||
public HashMap<Integer, float[]> LOAD_RACE_HEIGHTS() {
|
||||
|
||||
ConcurrentHashMap<Integer, Race> races;
|
||||
Race thisRace;
|
||||
|
||||
races = new ConcurrentHashMap<>();
|
||||
int recordsRead = 0;
|
||||
HashMap<Integer, float[]> raceHeights = new HashMap<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_race")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
|
||||
recordsRead++;
|
||||
thisRace = new Race(rs);
|
||||
|
||||
races.put(thisRace.getRaceRuneID(), thisRace);
|
||||
}
|
||||
while (rs.next())
|
||||
raceHeights.put(rs.getInt("ID"), new float[]{rs.getFloat("minHeight"), rs.getFloat("strHeightMod")});
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
Logger.info("read: " + recordsRead + " cached: " + races.size());
|
||||
return races;
|
||||
return raceHeights;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,17 +11,16 @@ package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
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.powers.RunePowerEntry;
|
||||
import engine.powers.RuneSkillAdjustEntry;
|
||||
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 dbRuneBaseHandler extends dbHandlerBase {
|
||||
|
||||
@@ -30,231 +29,57 @@ public class dbRuneBaseHandler extends dbHandlerBase {
|
||||
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
|
||||
}
|
||||
|
||||
public static HashMap<Integer, ArrayList<RunePowerEntry>> LOAD_RUNE_POWERS() {
|
||||
// static_rune_lookup is generated for the DB views; a failed write must never stop the boot
|
||||
public static void WRITE_RUNE_LOOKUP() {
|
||||
|
||||
HashMap<Integer, ArrayList<RunePowerEntry>> mobPowers = new HashMap<>();
|
||||
RunePowerEntry runePowerEntry;
|
||||
|
||||
int rune_id;
|
||||
int recordsRead = 0;
|
||||
int rowsWritten = 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_powers")) {
|
||||
PreparedStatement deleteStatement = connection.prepareStatement("DELETE FROM `static_rune_lookup`");
|
||||
PreparedStatement insertStatement = connection.prepareStatement("INSERT INTO `static_rune_lookup` (`ID`, `type`, `name`) VALUES (?, ?, ?)")) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
connection.setAutoCommit(false);
|
||||
|
||||
while (rs.next()) {
|
||||
try {
|
||||
deleteStatement.executeUpdate();
|
||||
|
||||
recordsRead++;
|
||||
|
||||
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 (Race race : Race.getAllRaces()) {
|
||||
addRuneLookupRow(insertStatement, race.getRaceRuneID(), "RACE", race.getName());
|
||||
rowsWritten++;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
return mobPowers;
|
||||
}
|
||||
|
||||
Logger.info("read: " + recordsRead + " cached: " + mobPowers.size());
|
||||
return mobPowers;
|
||||
}
|
||||
|
||||
public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> LOAD_RUNE_SKILL_ADJUSTS() {
|
||||
|
||||
HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> runeSkillAdjusts = new HashMap<>();
|
||||
RuneSkillAdjustEntry runeSkillAdjustEntry;
|
||||
|
||||
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);
|
||||
for (AbstractGameObject baseClass : DbManager.getMap(mbEnums.GameObjectType.BaseClass).values()) {
|
||||
addRuneLookupRow(insertStatement, baseClass.getObjectUUID(), "BASECLASS", ((BaseClass) baseClass).getName());
|
||||
rowsWritten++;
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
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) {
|
||||
Logger.error(e);
|
||||
} catch (Exception e) {
|
||||
Logger.warn("static_rune_lookup not written; DB views keep their old names: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.info("static_rune_lookup: wrote " + rowsWritten + " rows");
|
||||
}
|
||||
|
||||
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;
|
||||
private static void addRuneLookupRow(PreparedStatement insertStatement, int runeID, String type, String name) throws SQLException {
|
||||
insertStatement.setInt(1, runeID);
|
||||
insertStatement.setString(2, type);
|
||||
insertStatement.setString(3, name);
|
||||
insertStatement.addBatch();
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ package engine.db.handlers;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.objects.MaxSkills;
|
||||
import engine.objects.SkillsBase;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -20,7 +19,6 @@ 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 dbSkillBaseHandler extends dbHandlerBase {
|
||||
@@ -31,122 +29,33 @@ public class dbSkillBaseHandler extends dbHandlerBase {
|
||||
}
|
||||
|
||||
public SkillsBase GET_BASE(final int objectUUID) {
|
||||
|
||||
SkillsBase skillsBase = (SkillsBase) DbManager.getFromCache(GameObjectType.SkillsBase, objectUUID);
|
||||
|
||||
if (skillsBase != null)
|
||||
return skillsBase;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_skill_skillsbase WHERE ID = ?")) {
|
||||
|
||||
preparedStatement.setInt(1, objectUUID);
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
skillsBase = (SkillsBase) getObjectFromRs(rs);
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
SkillsBase.putInCache(skillsBase);
|
||||
return skillsBase;
|
||||
return (SkillsBase) DbManager.getFromCache(GameObjectType.SkillsBase, objectUUID);
|
||||
}
|
||||
|
||||
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;
|
||||
return SkillsBase.getFromCache(name);
|
||||
}
|
||||
|
||||
public SkillsBase GET_BASE_BY_TOKEN(final int token) {
|
||||
return SkillsBase.getFromCache(token);
|
||||
}
|
||||
|
||||
SkillsBase skillsBase = SkillsBase.getFromCache(token);
|
||||
public HashMap<Integer, String> GET_ALL_SKILL_NAMES() {
|
||||
|
||||
if (skillsBase != null)
|
||||
return skillsBase;
|
||||
HashMap<Integer, String> skillNames = new HashMap<>();
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_skill_skillsbase WHERE token = ?")) {
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT ID, name FROM static_skill_skillsbase")) {
|
||||
|
||||
preparedStatement.setInt(1, token);
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
|
||||
skillsBase = (SkillsBase) getObjectFromRs(rs);
|
||||
while (rs.next())
|
||||
skillNames.put(rs.getInt("ID"), rs.getString("name"));
|
||||
|
||||
} catch (SQLException e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
SkillsBase.putInCache(skillsBase);
|
||||
return skillsBase;
|
||||
return skillNames;
|
||||
}
|
||||
|
||||
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,18 +9,8 @@
|
||||
|
||||
package engine.db.handlers;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
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 {
|
||||
|
||||
@@ -28,72 +18,4 @@ public class dbSkillReqHandler extends dbHandlerBase {
|
||||
this.localClass = SkillReq.class;
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import engine.objects.Warehouse;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.joda.time.DateTime;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -134,7 +135,6 @@ public class dbWarehouseHandler extends dbHandlerBase {
|
||||
|
||||
while (rs.next()) {
|
||||
int cityUID = rs.getInt("cityUUID");
|
||||
JSONObject jsonObject = new JSONObject(rs.getString("warehouse"));
|
||||
City city = City.getCity(cityUID);
|
||||
|
||||
if (city == null) {
|
||||
@@ -142,12 +142,18 @@ public class dbWarehouseHandler extends dbHandlerBase {
|
||||
continue;
|
||||
}
|
||||
|
||||
city.warehouse = new Warehouse(jsonObject);
|
||||
try {
|
||||
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;
|
||||
|
||||
// Locate warehouse building
|
||||
for (Building building : city.parentZone.zoneBuildingSet) {
|
||||
if (building.getBlueprint().getBuildingGroup().equals(mbEnums.BuildingGroup.WAREHOUSE)) {
|
||||
if (building.getBlueprint().getBuildingGroup().equals(mbEnums.BuildingGroup.WAREHOUSE) && building.getRank() != -1) {
|
||||
city.warehouse.building = building;
|
||||
break;
|
||||
}
|
||||
@@ -205,8 +211,16 @@ public class dbWarehouseHandler extends dbHandlerBase {
|
||||
ResultSet rs = preparedStatement.executeQuery()) {
|
||||
|
||||
while (rs.next()) {
|
||||
JSONObject jsonObject = new JSONObject(rs.getString("workorder"));
|
||||
WorkOrder workOrder = new WorkOrder(jsonObject);
|
||||
int workOrderID = rs.getInt("workorderID");
|
||||
WorkOrder workOrder;
|
||||
|
||||
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);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -15,8 +15,8 @@ import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.AbstractGameObject;
|
||||
import engine.objects.Item;
|
||||
import engine.objects.ItemTemplate;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
/**
|
||||
@@ -38,7 +38,7 @@ public class CreateItemCmd extends AbstractDevCmd {
|
||||
}
|
||||
|
||||
int templateID = Integer.parseInt(words[0]);
|
||||
ItemTemplate template = ItemTemplate.templates.get(templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(templateID);
|
||||
|
||||
if (template == null) {
|
||||
ChatManager.chatSystemInfo(playerCharacter, "No such template found.");
|
||||
@@ -51,7 +51,7 @@ public class CreateItemCmd extends AbstractDevCmd {
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
if (!playerCharacter.charItemManager.hasRoomInventory(template.item_wt)) {
|
||||
if (!playerCharacter.charItemManager.hasRoomInventory(template.getItemWt())) {
|
||||
ChatManager.chatSystemInfo(playerCharacter, "You are encumbered!.");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// 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)";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import engine.mbEnums.BuildingGroup;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.mbEnums.TargetColor;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.util.StringUtils;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
@@ -507,17 +508,17 @@ public class InfoCmd extends AbstractDevCmd {
|
||||
case Item: //intentional passthrough
|
||||
case MobLoot:
|
||||
Item item = (Item) target;
|
||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
||||
output += StringUtils.addWS("Template: " + template.template_id, 20);
|
||||
output += "Weight: " + template.item_wt;
|
||||
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||
output += StringUtils.addWS("Template: " + template.getTemplateId(), 20);
|
||||
output += "Weight: " + template.getItemWt();
|
||||
output += newline;
|
||||
DecimalFormat df = new DecimalFormat("###,###,###,###,##0");
|
||||
output += StringUtils.addWS("Qty: "
|
||||
+ df.format(item.getNumOfItems()), 20);
|
||||
output += "Charges: " + (byte) item.chargesRemaining
|
||||
+ '/' + item.template.item_initial_charges;
|
||||
+ '/' + item.template.getItemInitialCharges();
|
||||
output += newline;
|
||||
output += "Name: " + template.item_base_name;
|
||||
output += "Name: " + template.getItemBaseName();
|
||||
output += newline;
|
||||
output += item.getContainerInfo();
|
||||
|
||||
|
||||
@@ -11,9 +11,11 @@ package engine.devcmd.cmds;
|
||||
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums.ItemContainerType;
|
||||
import engine.mbEnums.ItemType;
|
||||
import engine.mbEnums.OwnerType;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.powers.EffectsBase;
|
||||
|
||||
/**
|
||||
@@ -59,18 +61,17 @@ public class MakeItemCmd extends AbstractDevCmd {
|
||||
}
|
||||
|
||||
int templateID;
|
||||
ItemTemplate template;
|
||||
CObjectTemplate template;
|
||||
try {
|
||||
templateID = Integer.parseInt(words[0]);
|
||||
template = ItemTemplate.templates.get(words[0].toLowerCase());
|
||||
template = CObjectTemplate.lookup(templateID);
|
||||
|
||||
if (template == null) {
|
||||
throwbackError(pc, "Supplied type " + words[0]
|
||||
+ " failed to parse to an Integer");
|
||||
throwbackError(pc, "No item template with id " + words[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (template.item_type == ItemType.GOLD) {
|
||||
if (template.getItemType() == ItemType.GOLD) {
|
||||
this.throwbackInfo(pc, "use /addgold to add gold.");
|
||||
return;
|
||||
}
|
||||
@@ -132,7 +133,7 @@ public class MakeItemCmd extends AbstractDevCmd {
|
||||
return;
|
||||
}
|
||||
}
|
||||
template = ItemTemplate.templates.get(templateID);
|
||||
template = CObjectTemplate.lookup(templateID);
|
||||
|
||||
if (template == null) {
|
||||
throwbackError(pc, "Unable to find template " + templateID);
|
||||
@@ -140,8 +141,8 @@ public class MakeItemCmd extends AbstractDevCmd {
|
||||
}
|
||||
|
||||
if ((numItems > 1)
|
||||
&& (template.item_type.equals(ItemType.RESOURCE) == false)
|
||||
&& (template.item_type.equals(ItemType.OFFERING)) == false)
|
||||
&& (template.getItemType().equals(ItemType.RESOURCE) == false)
|
||||
&& (template.getItemType().equals(ItemType.OFFERING)) == false)
|
||||
numItems = 1;
|
||||
|
||||
CharacterItemManager cim = pc.charItemManager;
|
||||
@@ -155,7 +156,7 @@ public class MakeItemCmd extends AbstractDevCmd {
|
||||
|
||||
for (int i = 0; i < quantity; i++) {
|
||||
|
||||
int weight = template.item_wt;
|
||||
int weight = template.getItemWt();
|
||||
|
||||
if (!cim.hasRoomInventory(weight)) {
|
||||
throwbackError(pc, "Not enough room in inventory for any more of this item. " + i + " produced.");
|
||||
@@ -169,6 +170,7 @@ public class MakeItemCmd extends AbstractDevCmd {
|
||||
Item item = new Item(templateID);
|
||||
item.ownerID = pc.getObjectUUID();
|
||||
item.ownerType = OwnerType.PlayerCharacter;
|
||||
item.containerType = ItemContainerType.INVENTORY;
|
||||
|
||||
if (numItems > 1)
|
||||
item.setNumOfItems(numItems);
|
||||
@@ -180,6 +182,11 @@ public class MakeItemCmd extends AbstractDevCmd {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item == null) {
|
||||
throwbackError(pc, "DB error 2: Unable to create item " + templateID + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
//create prefix
|
||||
if (!prefix.isEmpty())
|
||||
item.addPermanentEnchantmentForDev(prefix, 0);
|
||||
|
||||
@@ -11,6 +11,7 @@ package engine.devcmd.cmds;
|
||||
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -52,8 +53,8 @@ public class PrintBankCmd extends AbstractDevCmd {
|
||||
throwbackInfo(pc, "Bank for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
||||
|
||||
for (Item item : list) {
|
||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
||||
throwbackInfo(pc, " " + template.item_base_name + ", count: " + item.getNumOfItems());
|
||||
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||
throwbackInfo(pc, " " + template.getItemBaseName() + ", count: " + item.getNumOfItems());
|
||||
}
|
||||
|
||||
Item gold = cim.getGoldBank();
|
||||
|
||||
@@ -13,6 +13,7 @@ import engine.devcmd.AbstractDevCmd;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
|
||||
public class PrintBonusesCmd extends AbstractDevCmd {
|
||||
@@ -33,8 +34,8 @@ public class PrintBonusesCmd extends AbstractDevCmd {
|
||||
if (target instanceof Item) {
|
||||
type = "Item";
|
||||
tar = (Item) target;
|
||||
ItemTemplate template = ItemTemplate.templates.get(((Item) tar).templateID);
|
||||
name = template.item_base_name;
|
||||
CObjectTemplate template = CObjectTemplate.lookup(((Item) tar).templateID);
|
||||
name = template.getItemBaseName();
|
||||
} else if (target instanceof AbstractCharacter) {
|
||||
tar = (AbstractCharacter) target;
|
||||
name = ((AbstractCharacter) tar).getFirstName();
|
||||
|
||||
@@ -10,9 +10,15 @@
|
||||
package engine.devcmd.cmds;
|
||||
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.objects.AbstractCharacter;
|
||||
import engine.objects.AbstractGameObject;
|
||||
import engine.objects.Effect;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.PowersBase;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -30,28 +36,60 @@ public class PrintEffectsCmd extends AbstractDevCmd {
|
||||
AbstractGameObject target) {
|
||||
|
||||
AbstractCharacter tar;
|
||||
StringBuilder output;
|
||||
String newline = "\r\n ";
|
||||
Effect effect;
|
||||
EffectsBase effectsBase;
|
||||
PowersBase power;
|
||||
|
||||
if (target != null && target instanceof AbstractCharacter) {
|
||||
tar = (AbstractCharacter) target;
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
String newline = "\r\n ";
|
||||
String output = "Effects For Character: " + tar.getName() + newline;
|
||||
if (target.getObjectType() != GameObjectType.PlayerCharacter && target.getObjectType() != GameObjectType.Mob
|
||||
&& target.getObjectType() != GameObjectType.NPC)
|
||||
return;
|
||||
|
||||
for (String effect : tar.effects.keySet()) {
|
||||
output += effect + newline;
|
||||
}
|
||||
throwbackInfo(pc, output);
|
||||
tar = (AbstractCharacter) target;
|
||||
output = new StringBuilder("Effects for " + tar.getName() + " (" + tar.effects.size() + "):" + newline);
|
||||
|
||||
// Keys are the effect UUID for mobbase/rune effects, or the stack type (e.g. PetBuff) for power effects
|
||||
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
|
||||
protected String _getHelpString() {
|
||||
return "Returns the player's current stats";
|
||||
return "Lists the target's effects: key, effect id and name, rank, time left and source power";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String _getUsageString() {
|
||||
return "' /printstats'";
|
||||
return "' /printeffects'";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -66,7 +66,7 @@ public class PrintEquipCmd extends AbstractDevCmd {
|
||||
throwbackInfo(pc, "Equip for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
||||
for (mbEnums.EquipSlotType slot : tarMob.charItemManager.equipped.keySet()) {
|
||||
Item equip = tarMob.charItemManager.equipped.get(slot);
|
||||
throwbackInfo(pc, equip.templateID + " : " + equip.template.item_base_name + ", slot: " + slot);
|
||||
throwbackInfo(pc, equip.templateID + " : " + equip.template.getItemBaseName() + ", slot: " + slot);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class PrintEquipCmd extends AbstractDevCmd {
|
||||
throwbackInfo(pc, "Equip for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
||||
for (mbEnums.EquipSlotType slot : tarMob.charItemManager.equipped.keySet()) {
|
||||
Item equip = tarMob.charItemManager.equipped.get(slot);
|
||||
throwbackInfo(pc, equip.templateID + " : " + equip.template.item_base_name + ", slot: " + slot);
|
||||
throwbackInfo(pc, equip.templateID + " : " + equip.template.getItemBaseName() + ", slot: " + slot);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public class PrintEquipCmd extends AbstractDevCmd {
|
||||
|
||||
for (mbEnums.EquipSlotType slot : list.keySet()) {
|
||||
Item item = list.get(slot);
|
||||
throwbackInfo(pc, " " + item.template.item_base_name + ", slot: " + slot);
|
||||
throwbackInfo(pc, " " + item.template.getItemBaseName() + ", slot: " + slot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ package engine.devcmd.cmds;
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.mbEnums.ItemType;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
@@ -75,18 +76,18 @@ public class PrintInventoryCmd extends AbstractDevCmd {
|
||||
int goldCount = 0;
|
||||
|
||||
for (Item item : inventory) {
|
||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||
|
||||
if (item.template.item_type.equals(ItemType.GOLD) == false) {
|
||||
if (item.template.getItemType().equals(ItemType.GOLD) == false) {
|
||||
|
||||
String chargeInfo = "";
|
||||
int chargeMax = template.item_initial_charges;
|
||||
int chargeMax = template.getItemInitialCharges();
|
||||
|
||||
if (chargeMax > 0) {
|
||||
int charges = item.chargesRemaining;
|
||||
chargeInfo = " charges: " + charges + '/' + chargeMax;
|
||||
}
|
||||
throwbackInfo(pc, " " + template.item_base_name + ", count: " + item.getNumOfItems() + chargeInfo);
|
||||
throwbackInfo(pc, " " + template.getItemBaseName() + ", count: " + item.getNumOfItems() + chargeInfo);
|
||||
} else
|
||||
goldCount += item.getNumOfItems();
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ package engine.devcmd.cmds;
|
||||
|
||||
import engine.devcmd.AbstractDevCmd;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -50,8 +51,8 @@ public class PrintVaultCmd extends AbstractDevCmd {
|
||||
ArrayList<Item> list = cim.getVault();
|
||||
throwbackInfo(pc, "Vault for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
||||
for (Item item : list) {
|
||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
||||
throwbackInfo(pc, " " + template.item_base_name + ", count: " + item.getNumOfItems());
|
||||
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||
throwbackInfo(pc, " " + template.getItemBaseName() + ", count: " + item.getNumOfItems());
|
||||
}
|
||||
Item gold = cim.getGoldVault();
|
||||
if (gold != null)
|
||||
|
||||
@@ -5,6 +5,7 @@ import engine.gameManager.LootManager;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.loot.BootySetEntry;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
@@ -34,10 +35,10 @@ public class SimulateBootyCmd extends AbstractDevCmd {
|
||||
if (mob.bootySet != 0) {
|
||||
for (BootySetEntry entry : LootManager._bootySetMap.get(mob.bootySet)) {
|
||||
|
||||
ItemTemplate template = ItemTemplate.templates.get(entry.templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(entry.templateID);
|
||||
|
||||
if (template != null)
|
||||
output += "[" + entry.bootyType + "] " + template.item_base_name + " [Chance] " + entry.dropChance + newline;
|
||||
output += "[" + entry.bootyType + "] " + template.getItemBaseName() + " [Chance] " + entry.dropChance + newline;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +58,7 @@ public class SimulateBootyCmd extends AbstractDevCmd {
|
||||
try {
|
||||
mob.loadInventory();
|
||||
for (Item lootItem : mob.charItemManager.getInventory()) {
|
||||
switch (lootItem.template.item_type) {
|
||||
switch (lootItem.template.getItemType()) {
|
||||
case EMPLOYMENTCONTRACT: //CONTRACT
|
||||
Contracts.add(lootItem);
|
||||
break;
|
||||
|
||||
@@ -118,18 +118,17 @@ public class aiInfoCmd extends AbstractDevCmd {
|
||||
|
||||
ArrayList<RunePowerEntry> powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
|
||||
|
||||
// Additional powers may come from the contract ID. This is to support
|
||||
// powers for player guards irrespective of the mobbase used.
|
||||
// Player guards also cast their captain contract's powers, irrespective of the mobbase used.
|
||||
|
||||
if (mob.isPlayerGuard()) {
|
||||
|
||||
ArrayList<RunePowerEntry> contractEntries = new ArrayList<>();
|
||||
|
||||
if (mob.contract != null)
|
||||
contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.contractUUID));
|
||||
contractEntries = new ArrayList<>(mbEnums.MinionType.getCaptainPowers(mob.contractUUID));
|
||||
|
||||
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION))
|
||||
contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.guardCaptain.contractUUID));
|
||||
contractEntries = new ArrayList<>(mbEnums.MinionType.getCaptainPowers(mob.guardCaptain.contractUUID));
|
||||
|
||||
powerEntries.addAll(contractEntries);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import engine.mbEnums.BuildingGroup;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -199,31 +200,31 @@ public enum BuildingManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemTemplate template = ItemTemplate.templates.get(1705032); // Elan Stone
|
||||
CObjectTemplate template = CObjectTemplate.lookup(1705032); // Elan Stone
|
||||
|
||||
if (!player.charItemManager.hasRoomInventory(template.item_wt))
|
||||
if (!player.charItemManager.hasRoomInventory(template.getItemWt()))
|
||||
return false;
|
||||
|
||||
if (!ItemManager.MakeItemForPlayer(template.template_id, player, amount))
|
||||
if (!ItemManager.MakeItemForPlayer(template.getTemplateId(), player, amount))
|
||||
return false;
|
||||
|
||||
shrine.setFavors(0);
|
||||
break;
|
||||
case WAREHOUSE:
|
||||
|
||||
City city = building.getCity();
|
||||
|
||||
if (city == null)
|
||||
return true;
|
||||
|
||||
Warehouse warehouse = city.warehouse;
|
||||
Warehouse warehouse = Warehouse.destroyedWarehouses.get(building.getObjectUUID());
|
||||
|
||||
if (warehouse == null)
|
||||
return false;
|
||||
|
||||
for (mbEnums.ResourceType resourceType : EnumSet.allOf(mbEnums.ResourceType.class)) {
|
||||
|
||||
if (!player.charItemManager.hasRoomInventory(resourceType.template.item_wt)) {
|
||||
CObjectTemplate resourceTemplate = CObjectTemplate.lookup(resourceType.templateID);
|
||||
|
||||
if (resourceTemplate == null)
|
||||
continue;
|
||||
|
||||
if (!player.charItemManager.hasRoomInventory(resourceTemplate.getItemWt())) {
|
||||
ChatManager.chatSystemInfo(player, "You can not carry any more of that item.");
|
||||
return false;
|
||||
}
|
||||
@@ -241,6 +242,9 @@ public enum BuildingManager {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Warehouse.isEmpty(warehouse))
|
||||
Warehouse.destroyedWarehouses.remove(building.getObjectUUID());
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import engine.net.client.ClientConnection;
|
||||
import engine.net.client.handlers.ClientAdminCommandMsgHandler;
|
||||
import engine.net.client.msg.chat.*;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.server.world.WorldServer;
|
||||
import org.pmw.tinylog.Logger;
|
||||
@@ -535,12 +536,12 @@ public enum ChatManager {
|
||||
if (item != null) //Steal
|
||||
if (success) {
|
||||
String name = "";
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD))
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD))
|
||||
name = amount + " gold ";
|
||||
else {
|
||||
String vowels = "aeiou";
|
||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
||||
String iName = template.item_base_name;
|
||||
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||
String iName = template.getItemBaseName();
|
||||
if (iName.length() > 0)
|
||||
if (vowels.indexOf(iName.substring(0, 1).toLowerCase()) >= 0)
|
||||
name = "an " + iName + ' ';
|
||||
|
||||
@@ -18,6 +18,8 @@ import engine.net.client.msg.PowerProjectileMsg;
|
||||
import engine.net.client.msg.TargetedActionMsg;
|
||||
import engine.net.client.msg.UpdateStateMsg;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.powers.DamageShield;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
import engine.powers.effectmodifiers.WeaponProcEffectModifier;
|
||||
@@ -26,6 +28,7 @@ import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
@@ -92,25 +95,25 @@ public enum CombatManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mainWeapon == null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) {
|
||||
if (mainWeapon == null && offWeapon != null && !offWeapon.template.getItemSkillUsed().equals("Block")) {
|
||||
//swing left hand only
|
||||
processAttack(attacker, target, mbEnums.EquipSlotType.LHELD);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mainWeapon == null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) {
|
||||
if (mainWeapon == null && offWeapon != null && offWeapon.template.getItemSkillUsed().equals("Block")) {
|
||||
//no weapon equipped with a shield, punch with one hand
|
||||
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mainWeapon != null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) {
|
||||
if (mainWeapon != null && offWeapon != null && offWeapon.template.getItemSkillUsed().equals("Block")) {
|
||||
//one weapon equipped with a shield, swing with one hand
|
||||
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mainWeapon != null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) {
|
||||
if (mainWeapon != null && offWeapon != null && !offWeapon.template.getItemSkillUsed().equals("Block")) {
|
||||
//two weapons equipped, swing both hands
|
||||
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
|
||||
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter))
|
||||
@@ -146,7 +149,7 @@ public enum CombatManager {
|
||||
if (bonus != null)
|
||||
rangeMod += bonus.getFloatPercentAll(mbEnums.ModType.WeaponRange, mbEnums.SourceType.None);
|
||||
|
||||
attackRange += weapon.template.item_weapon_max_range * rangeMod;
|
||||
attackRange += engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).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)
|
||||
@@ -211,7 +214,7 @@ public enum CombatManager {
|
||||
|
||||
if (weapon != null) {
|
||||
|
||||
float wepSpeed = (int) (weapon.template.item_weapon_wepspeed);
|
||||
float wepSpeed = (int) (engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed);
|
||||
|
||||
if (weapon.getBonusPercent(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None) != 0f) //add weapon speed bonus
|
||||
wepSpeed *= (1 + weapon.getBonus(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None));
|
||||
@@ -270,13 +273,13 @@ public enum CombatManager {
|
||||
if (weapon != null && !attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) {
|
||||
//check if Out of Stamina
|
||||
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) {
|
||||
if (attacker.getStamina() < (weapon.template.item_wt / 3f)) {
|
||||
if (attacker.getStamina() < (weapon.template.getItemWt() / 3f)) {
|
||||
//set auto attack job
|
||||
setAutoAttackJob(attacker, slot, delay);
|
||||
return;
|
||||
}
|
||||
}
|
||||
float stam = weapon.template.item_wt / 3f;
|
||||
float stam = weapon.template.getItemWt() / 3f;
|
||||
stam = (stam < 1) ? 1 : stam;
|
||||
attacker.modifyStamina(-(stam), attacker, true);
|
||||
} else
|
||||
@@ -416,7 +419,7 @@ public enum CombatManager {
|
||||
if (((Mob) attacker).isSiege())
|
||||
damageType = mbEnums.DamageType.SIEGE;
|
||||
} else {
|
||||
damageType = (mbEnums.DamageType) attacker.charItemManager.getEquipped().get(slot).template.item_weapon_damage.keySet().toArray()[0];
|
||||
damageType = engine.parsers.objects.ItemTemplate.getWeapon(attacker.charItemManager.getEquipped().get(slot).templateID).weapon_damage.get(0).damage_type;
|
||||
}
|
||||
|
||||
//get resists
|
||||
@@ -577,13 +580,14 @@ public enum CombatManager {
|
||||
target.setCombatTarget(attacker);
|
||||
}
|
||||
|
||||
public static int getSwingAnimation(ItemTemplate wb, DeferredPowerJob dpj, mbEnums.EquipSlotType slot) {
|
||||
public static int getSwingAnimation(CObjectTemplate wb, DeferredPowerJob dpj, mbEnums.EquipSlotType slot) {
|
||||
|
||||
//No weapon, return default animation
|
||||
if (wb == null)
|
||||
return 75;
|
||||
|
||||
int token;
|
||||
engine.parsers.objects.ItemTemplate.Weapon weapon = engine.parsers.objects.ItemTemplate.getWeapon(wb.getTemplateId());
|
||||
|
||||
if (dpj != null) {
|
||||
|
||||
@@ -594,47 +598,30 @@ public enum CombatManager {
|
||||
}
|
||||
|
||||
//Item has no equipment slots and should not try to return an animation, return default instead
|
||||
if (wb.item_eq_slots_or == null || wb.item_eq_slots_or.isEmpty()) {
|
||||
if (wb.getItemEqSlotsOr().isEmpty()) {
|
||||
return 75;
|
||||
}
|
||||
|
||||
//declare variables
|
||||
int anim;
|
||||
int random;
|
||||
mbEnums.EquipSlotType hand;
|
||||
ArrayList<int[]> anims;
|
||||
|
||||
//Item can only be equipped in one slot, return animation for that slot
|
||||
if (wb.item_eq_slots_or.size() == 1) {
|
||||
if (wb.item_eq_slots_or.iterator().next().equals(mbEnums.EquipSlotType.RHELD)) {
|
||||
anim = wb.weapon_attack_anim_right.get(0)[0];
|
||||
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;
|
||||
}
|
||||
//Item can only be equipped in one slot, use the animations for that slot
|
||||
if (wb.getItemEqSlotsOr().size() == 1)
|
||||
hand = wb.getItemEqSlotsOr().iterator().next();
|
||||
else
|
||||
hand = slot;
|
||||
|
||||
//Item can be equipped in either hand, and should have animation sets for each hand
|
||||
if (slot.equals(mbEnums.EquipSlotType.RHELD)) {
|
||||
anim = wb.weapon_attack_anim_right.get(0)[0];
|
||||
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;
|
||||
|
||||
// Many cache weapons have no swing anims; GUESS: the client falls back to the default too
|
||||
if (anims.isEmpty())
|
||||
return 75;
|
||||
|
||||
if (dpj != null)
|
||||
return anims.get(ThreadLocalRandom.current().nextInt(anims.size()))[0];
|
||||
|
||||
return anims.get(0)[0];
|
||||
}
|
||||
|
||||
public static int getPassiveAnimation(mbEnums.PassiveType passiveType) {
|
||||
@@ -713,7 +700,7 @@ public enum CombatManager {
|
||||
// Mobs use their mobbase rune, players use their race rune.
|
||||
|
||||
int runeID;
|
||||
ItemTemplate rune;
|
||||
RuneTemplate rune;
|
||||
int hand = slot.equals(mbEnums.EquipSlotType.LHELD) ? 2 : 1;
|
||||
|
||||
switch (attacker.getObjectType()) {
|
||||
@@ -727,18 +714,18 @@ public enum CombatManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
rune = ItemTemplate.templates.get(runeID);
|
||||
rune = RuneTemplate._runes.get(runeID);
|
||||
|
||||
if (rune == null || rune.rune_natural_attacks.isEmpty())
|
||||
if (rune == null || rune.rune_naturalattacks.isEmpty())
|
||||
return null;
|
||||
|
||||
for (float[] attack : rune.rune_natural_attacks)
|
||||
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_natural_attacks.get(0);
|
||||
return rune.rune_naturalattacks.get(0);
|
||||
}
|
||||
|
||||
public static int calculatePetDamage(AbstractCharacter agent) {
|
||||
|
||||
@@ -75,6 +75,7 @@ public enum ConfigManager {
|
||||
// Mobile AI modifiers
|
||||
MB_AI_CAST_FREQUENCY,
|
||||
MB_AI_AGGRO_RANGE,
|
||||
MB_MINION_SPAWN_TIME,
|
||||
|
||||
//drop rates
|
||||
MB_NORMAL_EXP_RATE,
|
||||
@@ -165,14 +166,6 @@ public enum ConfigManager {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,10 +44,8 @@ public enum DbManager {
|
||||
// Omg refactor this out, somebody!
|
||||
public static final dbCSSessionHandler CSSessionQueries = new dbCSSessionHandler();
|
||||
public static final dbEnchantmentHandler EnchantmentQueries = new dbEnchantmentHandler();
|
||||
public static final dbEffectsResourceCostHandler EffectsResourceCostsQueries = new dbEffectsResourceCostHandler();
|
||||
public static final dbGuildHandler GuildQueries = new dbGuildHandler();
|
||||
public static final dbItemHandler ItemQueries = new dbItemHandler();
|
||||
public static final dbKitHandler KitQueries = new dbKitHandler();
|
||||
public static final dbLootHandler LootQueries = new dbLootHandler();
|
||||
public static final dbMenuHandler MenuQueries = new dbMenuHandler();
|
||||
public static final dbMineHandler MineQueries = new dbMineHandler();
|
||||
@@ -57,9 +55,6 @@ public enum DbManager {
|
||||
public static final dbPlayerCharacterHandler PlayerCharacterQueries = new dbPlayerCharacterHandler();
|
||||
public static final dbPromotionClassHandler PromotionQueries = new dbPromotionClassHandler();
|
||||
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 dbSkillBaseHandler SkillsBaseQueries = new dbSkillBaseHandler();
|
||||
public static final dbSkillReqHandler SkillReqQueries = new dbSkillReqHandler();
|
||||
@@ -70,7 +65,6 @@ public enum DbManager {
|
||||
public static final dbShrineHandler ShrineQueries = new dbShrineHandler();
|
||||
public static final dbRunegateHandler RunegateQueries = new dbRunegateHandler();
|
||||
|
||||
public static final dbPowerHandler PowerQueries = new dbPowerHandler();
|
||||
public static final dbPetitionHandler PetitionQueries = new dbPetitionHandler();
|
||||
private static final EnumMap<GameObjectType, ConcurrentHashMap<Integer, AbstractGameObject>> objectCache = new EnumMap<>(GameObjectType.class);
|
||||
public static Hasher hasher;
|
||||
|
||||
@@ -101,6 +101,7 @@ public enum DevCmdManager {
|
||||
DevCmdManager.registerDevCmd(new SetAdminRuneCmd());
|
||||
DevCmdManager.registerDevCmd(new SetInvulCmd());
|
||||
DevCmdManager.registerDevCmd(new MakeItemCmd());
|
||||
DevCmdManager.registerDevCmd(new FillCmd());
|
||||
DevCmdManager.registerDevCmd(new SetSubRaceCmd());
|
||||
// Admin
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ import engine.mbEnums;
|
||||
import engine.net.client.msg.ItemProductionMsg;
|
||||
import engine.objects.City;
|
||||
import engine.objects.Item;
|
||||
import engine.objects.ItemTemplate;
|
||||
import engine.objects.NPC;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.powers.EffectsBase;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -49,6 +49,9 @@ public enum ForgeManager implements Runnable {
|
||||
public static final ConcurrentHashMap<NPC, ConcurrentHashMap.KeySetView<WorkOrder, Boolean>> vendorWorkOrderLookup = 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() {
|
||||
|
||||
Thread forgeManager;
|
||||
@@ -222,12 +225,12 @@ public enum ForgeManager implements Runnable {
|
||||
// Calculate production cost for a single run of the workOrder
|
||||
|
||||
HashMap<mbEnums.ResourceType, Integer> production_cost = new HashMap<>();
|
||||
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(workOrder.templateID);
|
||||
|
||||
// Add gold and resource costs from template
|
||||
|
||||
production_cost.put(mbEnums.ResourceType.GOLD, template.item_value);
|
||||
production_cost.putAll(template.item_resource_cost);
|
||||
production_cost.put(mbEnums.ResourceType.GOLD, template.getItemValue());
|
||||
production_cost.putAll(template.getItemResourceCosts());
|
||||
|
||||
// Calculate cost of prefix and suffix
|
||||
|
||||
@@ -248,8 +251,8 @@ public enum ForgeManager implements Runnable {
|
||||
|
||||
// Create new virtual item from specified template
|
||||
|
||||
ItemTemplate template = ItemTemplate.templates.get(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
|
||||
|
||||
@@ -264,13 +267,13 @@ public enum ForgeManager implements Runnable {
|
||||
|
||||
// Assign a prefix and suffix to this item if random rolled
|
||||
|
||||
if (workOrder.prefixToken == 0 && workOrder.vendor.getItemModTable().contains((template.modTable)))
|
||||
forgedItem.prefixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.PREFIX, template.modTable);
|
||||
if (workOrder.prefixToken == 0 && workOrder.vendor.getItemModTable().contains(modTable))
|
||||
forgedItem.prefixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.PREFIX, modTable);
|
||||
else
|
||||
forgedItem.prefixToken = workOrder.prefixToken;
|
||||
|
||||
if (workOrder.suffixToken == 0 && workOrder.vendor.getItemModTable().contains((template.modTable)))
|
||||
forgedItem.suffixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.SUFFIX, template.modTable);
|
||||
if (workOrder.suffixToken == 0 && workOrder.vendor.getItemModTable().contains(modTable))
|
||||
forgedItem.suffixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.SUFFIX, modTable);
|
||||
else
|
||||
forgedItem.suffixToken = workOrder.suffixToken;
|
||||
|
||||
@@ -364,6 +367,10 @@ public enum ForgeManager implements Runnable {
|
||||
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) {
|
||||
|
||||
// Random prefix or suffix token based on item.template.modtable
|
||||
|
||||
@@ -307,7 +307,7 @@ public enum GroupManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!item.template.item_type.equals(mbEnums.ItemType.GOLD)) //only split goldItem
|
||||
if (!item.template.getItemType().equals(mbEnums.ItemType.GOLD)) //only split goldItem
|
||||
return false;
|
||||
|
||||
Group group = getGroup(pc);
|
||||
|
||||
@@ -2,6 +2,7 @@ package engine.gameManager;
|
||||
|
||||
import engine.mbEnums;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.powers.EffectsBase;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -21,66 +22,46 @@ public enum ItemManager {
|
||||
|
||||
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) {
|
||||
|
||||
if (item.template.item_race_req.isEmpty() && item.template.item_race_res.isEmpty())
|
||||
EnumSet<mbEnums.MonsterType> races = item.template.getItemRaceReq();
|
||||
boolean restrict = item.template.getItemRaceReqRestrict();
|
||||
|
||||
if (races.isEmpty())
|
||||
return true;
|
||||
|
||||
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;
|
||||
return races.contains(race) != restrict;
|
||||
}
|
||||
|
||||
public static Boolean ValidClass(Item item, mbEnums.ClassType base, mbEnums.ClassType profession) {
|
||||
|
||||
// Early exit if no entry
|
||||
EnumSet<mbEnums.ClassType> classes = item.template.getItemClassReq();
|
||||
boolean restrict = item.template.getItemClassReqRestrict();
|
||||
boolean listed;
|
||||
|
||||
if (item.template.item_class_req.isEmpty() && item.template.item_class_res.isEmpty())
|
||||
if (classes.isEmpty())
|
||||
return true;
|
||||
|
||||
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;
|
||||
listed = classes.contains(base) || classes.contains(profession);
|
||||
|
||||
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;
|
||||
return listed != restrict;
|
||||
}
|
||||
|
||||
public static Boolean ValidDiscipline(Item item, EnumSet<mbEnums.DisciplineType> discs) {
|
||||
|
||||
// Early exit if no entry
|
||||
EnumSet<mbEnums.DisciplineType> disciplines = item.template.getItemDiscReq();
|
||||
boolean restrict = item.template.getItemDiscReqRestrict();
|
||||
EnumSet<mbEnums.DisciplineType> workSet;
|
||||
|
||||
if (item.template.item_disc_req.isEmpty() && item.template.item_disc_res.isEmpty())
|
||||
if (disciplines.isEmpty())
|
||||
return true;
|
||||
|
||||
EnumSet<mbEnums.DisciplineType> workSet = EnumSet.copyOf(discs);
|
||||
workSet = EnumSet.copyOf(discs);
|
||||
workSet.retainAll(disciplines);
|
||||
|
||||
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;
|
||||
return workSet.isEmpty() == restrict;
|
||||
}
|
||||
|
||||
public static Boolean canCharacterEquip(Item item, AbstractCharacter character) {
|
||||
@@ -91,12 +72,12 @@ public enum ItemManager {
|
||||
|
||||
CharacterSkill characterSkill;
|
||||
|
||||
if (item.template.item_skill_required.isEmpty())
|
||||
if (item.template.getItemSkillReq().isEmpty())
|
||||
return true;
|
||||
|
||||
for (String skillRequired : item.template.item_skill_required.keySet()) {
|
||||
for (String skillRequired : item.template.getItemSkillReq().keySet()) {
|
||||
|
||||
int required_value = item.template.item_skill_required.get(skillRequired);
|
||||
int required_value = item.template.getItemSkillReq().get(skillRequired);
|
||||
characterSkill = skills.get(skillRequired);
|
||||
|
||||
if (characterSkill == null)
|
||||
@@ -112,31 +93,31 @@ public enum ItemManager {
|
||||
|
||||
public static boolean isTwoHanded(Item item) {
|
||||
|
||||
if (!item.template.item_type.equals(mbEnums.ItemType.WEAPON))
|
||||
if (!item.template.getItemType().equals(mbEnums.ItemType.WEAPON))
|
||||
return false;
|
||||
|
||||
return item.template.item_eq_slots_and.contains(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD));
|
||||
return item.template.getItemEqSlotsAnd().containsAll(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD));
|
||||
}
|
||||
|
||||
public static boolean isTwoHanded(ItemTemplate template) {
|
||||
public static boolean isTwoHanded(CObjectTemplate template) {
|
||||
|
||||
if (!template.item_type.equals(mbEnums.ItemType.WEAPON))
|
||||
if (!template.getItemType().equals(mbEnums.ItemType.WEAPON))
|
||||
return false;
|
||||
|
||||
return template.item_eq_slots_and.contains(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD));
|
||||
return template.getItemEqSlotsAnd().containsAll(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD));
|
||||
}
|
||||
|
||||
public static boolean isShield(Item item) {
|
||||
|
||||
if (item.template.item_skill_required.containsKey("Block"))
|
||||
if (item.template.getItemSkillReq().containsKey("Block"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isShield(ItemTemplate template) {
|
||||
public static boolean isShield(CObjectTemplate template) {
|
||||
|
||||
if (template.item_skill_required.containsKey("Block"))
|
||||
if (template.getItemSkillReq().containsKey("Block"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -150,7 +131,7 @@ public enum ItemManager {
|
||||
return false;
|
||||
//Item not valid for slot
|
||||
|
||||
if (item.template.item_eq_slots_or.contains(slot) == false)
|
||||
if (item.template.getItemEqSlotsOr().contains(slot) == false)
|
||||
return false;
|
||||
|
||||
// Slot is taken
|
||||
@@ -165,7 +146,7 @@ public enum ItemManager {
|
||||
(slot == mbEnums.EquipSlotType.RHELD && equipped.get(mbEnums.EquipSlotType.LHELD) != null)))
|
||||
return false;
|
||||
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.WEAPON))
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.WEAPON))
|
||||
if (equipped.get(slot) != null && equipped.get(slot).equals(item) == false)
|
||||
return false;
|
||||
|
||||
@@ -197,7 +178,7 @@ public enum ItemManager {
|
||||
|
||||
//players can't wear 0 value items.
|
||||
|
||||
return item.template.item_value != 0 || Kit.IsNoobGear(item.templateID);
|
||||
return item.template.getItemValue() != 0 || Kit.IsNoobGear(item.templateID);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import engine.mbEnums;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.net.client.msg.chat.ChatSystemMsg;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -91,8 +92,8 @@ public enum LootManager {
|
||||
//lastly, check mobs inventory for godly or disc runes to send a server announcement
|
||||
for (Item item : mob.getInventory()) {
|
||||
|
||||
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.item_base_name + ". Are you tough enough to take it?");
|
||||
if ((item.templateID > 2499 && item.templateID <= 3050) || item.template.getItemBaseName().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?");
|
||||
chatMsg.setMessageType(10);
|
||||
chatMsg.setChannel(mbEnums.ChatChannelType.SYSTEM.getChannelID());
|
||||
DispatchManager.dispatchMsgToAll(chatMsg);
|
||||
@@ -179,12 +180,12 @@ public enum LootManager {
|
||||
if (itemUUID == 0)
|
||||
return null;
|
||||
|
||||
if (ItemTemplate.templates.get(itemUUID).item_type.equals(mbEnums.ItemType.RESOURCE)) {
|
||||
if (CObjectTemplate.lookup(itemUUID).getItemType().equals(mbEnums.ItemType.RESOURCE)) {
|
||||
int amount = ThreadLocalRandom.current().nextInt(tableRow.minSpawn, tableRow.maxSpawn + 1);
|
||||
return new MobLoot(mob, ItemTemplate.templates.get(itemUUID), amount, false);
|
||||
return new MobLoot(mob, CObjectTemplate.lookup(itemUUID), amount, false);
|
||||
}
|
||||
|
||||
outItem = new MobLoot(mob, ItemTemplate.templates.get(itemUUID), false);
|
||||
outItem = new MobLoot(mob, CObjectTemplate.lookup(itemUUID), false);
|
||||
|
||||
if (selectedRow.pModTable != 0)
|
||||
try {
|
||||
@@ -374,7 +375,7 @@ public enum LootManager {
|
||||
if (chanceRoll > bse.dropChance)
|
||||
return;
|
||||
|
||||
MobLoot lootItem = new MobLoot(mob, ItemTemplate.templates.get(bse.templateID), true);
|
||||
MobLoot lootItem = new MobLoot(mob, CObjectTemplate.lookup(bse.templateID), true);
|
||||
|
||||
if (lootItem != null)
|
||||
mob.charItemManager.addItemToInventory(lootItem);
|
||||
@@ -422,14 +423,14 @@ public enum LootManager {
|
||||
|
||||
//create the item from the table, quantity is always 1
|
||||
|
||||
MobLoot winnings = new MobLoot(playerCharacter, ItemTemplate.templates.get(selectedItem.templateID), 1, false);
|
||||
MobLoot winnings = new MobLoot(playerCharacter, CObjectTemplate.lookup(selectedItem.templateID), 1, false);
|
||||
|
||||
if (winnings == null)
|
||||
return;
|
||||
|
||||
//early exit if the inventory of the player will not old the item
|
||||
|
||||
if (itemMan.hasRoomInventory(winnings.template.item_wt) == false) {
|
||||
if (itemMan.hasRoomInventory(winnings.template.getItemWt()) == false) {
|
||||
ErrorPopupMsg.sendErrorPopup(playerCharacter, 21);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -19,12 +19,14 @@ import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.net.client.msg.PetMsg;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.RuneSkillAdjustEntry;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
@@ -315,26 +317,26 @@ public enum NPCManager {
|
||||
//has main hand weapon
|
||||
Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD);
|
||||
|
||||
if (weapon.template.item_primary_attr.equals(mbEnums.AttributeType.Strength))
|
||||
if (engine.parsers.objects.ItemTemplate._items.get(weapon.templateID).item_primary_attr == mbEnums.AttributeType.Strength)
|
||||
primaryStat = guard.getStatStrCurrent();
|
||||
else
|
||||
primaryStat = guard.getStatDexCurrent();
|
||||
|
||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + weapon.template.item_weapon_damage.values().iterator().next()[0]) * rankModifier) + primaryStat;
|
||||
guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + weapon.template.item_weapon_damage.values().iterator().next()[1]) * rankModifier) + primaryStat;
|
||||
guard.speedHandOne = weapon.template.item_weapon_wepspeed;
|
||||
guard.rangeHandOne = weapon.template.item_weapon_max_range;
|
||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_min) * rankModifier) + primaryStat;
|
||||
guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_max) * rankModifier) + primaryStat;
|
||||
guard.speedHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed;
|
||||
guard.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range;
|
||||
} else if (guard.charItemManager.equipped.containsKey(mbEnums.EquipSlotType.LHELD) && !ItemManager.isShield(guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template)) {
|
||||
//has off hand weapon
|
||||
Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD);
|
||||
if (weapon.template.item_primary_attr.equals(mbEnums.AttributeType.Strength))
|
||||
if (engine.parsers.objects.ItemTemplate._items.get(weapon.templateID).item_primary_attr == mbEnums.AttributeType.Strength)
|
||||
primaryStat = guard.getStatStrCurrent();
|
||||
else
|
||||
primaryStat = guard.getStatDexCurrent();
|
||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + weapon.template.item_weapon_damage.values().iterator().next()[0]) * rankModifier) + primaryStat;
|
||||
guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + weapon.template.item_weapon_damage.values().iterator().next()[1]) * rankModifier) + primaryStat;
|
||||
guard.speedHandOne = weapon.template.item_weapon_wepspeed;
|
||||
guard.rangeHandOne = weapon.template.item_weapon_max_range;
|
||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_min) * rankModifier) + primaryStat;
|
||||
guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_max) * rankModifier) + primaryStat;
|
||||
guard.speedHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed;
|
||||
guard.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range;
|
||||
} else {
|
||||
primaryStat = guard.getStatStrCurrent();
|
||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin()) * rankModifier) + primaryStat;
|
||||
@@ -352,8 +354,8 @@ public enum NPCManager {
|
||||
int baseDef = guard.mobBase.getDefenseRating();
|
||||
int armorDefense = 0;
|
||||
for (Item equipped : guard.charItemManager.equipped.values())
|
||||
if (equipped.template.item_type.equals(mbEnums.ItemType.ARMOR) || ItemManager.isShield(equipped.template))
|
||||
armorDefense += equipped.template.item_defense_rating;
|
||||
if (equipped.template.getItemType().equals(mbEnums.ItemType.ARMOR) || ItemManager.isShield(equipped.template))
|
||||
armorDefense += engine.parsers.objects.ItemTemplate._items.get(equipped.templateID).item_defense_rating;
|
||||
guard.defenseRating = dexterity + baseDef + armorDefense;
|
||||
}
|
||||
|
||||
@@ -361,9 +363,9 @@ public enum NPCManager {
|
||||
int strength = guard.getStatStrCurrent();
|
||||
int baseAtr = guard.mobBase.getAttackRating();
|
||||
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.item_skill_required.values().toArray()[0] * 4) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD).template.item_skill_required.values().toArray()[0] * 3));
|
||||
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));
|
||||
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.item_skill_required.values().toArray()[0] * 4) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template.item_skill_required.values().toArray()[0] * 3));
|
||||
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));
|
||||
else
|
||||
guard.atrHandOne = baseAtr;
|
||||
}
|
||||
@@ -434,28 +436,63 @@ 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) {
|
||||
|
||||
EnumMap<mbEnums.DamageType, Float> armorResists;
|
||||
|
||||
if (mob.charItemManager.equipped.isEmpty())
|
||||
return;
|
||||
|
||||
for (Item equipped : mob.charItemManager.equipped.values()) {
|
||||
if (equipped.template.item_type.equals(mbEnums.ItemType.ARMOR)) {
|
||||
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.CRUSHING, mob.resists.getResist(mbEnums.DamageType.CRUSHING, 0) + equipped.template.combat_attack_resist.get("CRUSHING"));
|
||||
mob.resists.setResist(mbEnums.DamageType.PIERCING, mob.resists.getResist(mbEnums.DamageType.PIERCING, 0) + equipped.template.combat_attack_resist.get("PIERCING"));
|
||||
if (equipped.template.getItemType().equals(mbEnums.ItemType.ARMOR)) {
|
||||
armorResists = equipped.template.getCombatAttackResist();
|
||||
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) + armorResists.getOrDefault(mbEnums.DamageType.CRUSHING, 0f));
|
||||
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) {
|
||||
//load mob skill adjustments from mobbase rune
|
||||
if (PowersManager._allRuneSkillAdjusts.containsKey(runeID))
|
||||
@@ -466,7 +503,7 @@ public enum NPCManager {
|
||||
if (skillBase == null)
|
||||
continue;
|
||||
if (entry.level <= mob.level)
|
||||
if (mob.skills.containsKey(entry.name) == false)
|
||||
if (mob.skills.containsKey(entry.skill_type) == false)
|
||||
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank));
|
||||
else
|
||||
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank + mob.skills.get(entry.skill_type).getNumTrains()));
|
||||
@@ -480,6 +517,11 @@ public enum NPCManager {
|
||||
npc.runes.add(shopkeeper);
|
||||
if (NPCManager._runeSetMap.containsKey(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);
|
||||
if (rb != null) {
|
||||
CharacterRune toApply = new CharacterRune(rb, npc.getObjectUUID());
|
||||
@@ -536,14 +578,14 @@ public enum NPCManager {
|
||||
|
||||
public static long calcRollingDuration(NPC vendor, int templateID) {
|
||||
|
||||
ItemTemplate template = ItemTemplate.templates.get(templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(templateID);
|
||||
float rollingDuration;
|
||||
|
||||
if (template == null)
|
||||
return 0;
|
||||
|
||||
if (template.item_bane_rank > 0)
|
||||
return (long) (template.item_bane_rank * 60 * 60 * 3 * 1000 * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()));
|
||||
if (template.getItemBaneRank() > 0)
|
||||
return (long) (template.getItemBaneRank() * 60 * 60 * 3 * 1000 * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()));
|
||||
|
||||
if (vendor.building == null)
|
||||
return 600;
|
||||
|
||||
@@ -10,9 +10,6 @@ package engine.gameManager;
|
||||
|
||||
import engine.InterestManagement.Terrain;
|
||||
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.AbstractScheduleJob;
|
||||
import engine.job.JobContainer;
|
||||
@@ -28,8 +25,12 @@ import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.*;
|
||||
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.poweractions.AbstractPowerAction;
|
||||
import engine.powers.poweractions.*;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -37,6 +38,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@@ -53,7 +55,6 @@ public enum PowersManager {
|
||||
public static HashMap<String, AbstractPowerAction> powerActionsByIDString = new HashMap<>();
|
||||
public static HashMap<Integer, AbstractPowerAction> powerActionsByID = 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<RuneSkillAdjustEntry>> _allRuneSkillAdjusts;
|
||||
public static HashMap<String, HashMap<ResourceType, Integer>> _effect_costMaps = new HashMap<>();
|
||||
@@ -90,16 +91,200 @@ public enum PowersManager {
|
||||
return PowersManager.effectsBaseByToken.get(token);
|
||||
}
|
||||
|
||||
// This pre-loads only PowersBase for login
|
||||
public static void InitializeLoginPowers() {
|
||||
public static void loadEffectCostMaps() {
|
||||
|
||||
// get all PowersBase
|
||||
ArrayList<PowersBase> pbList = dbSkillReqHandler.getAllPowersBase();
|
||||
for (PowActionCostTemplate costTemplate : PowActionCostTemplate._costs.values())
|
||||
PowersManager._effect_costMaps.put(costTemplate.id, new HashMap<>(costTemplate.costs));
|
||||
|
||||
for (PowersBase pb : pbList) {
|
||||
if (pb.getToken() != 0)
|
||||
PowersManager.powersBaseByToken.put(pb.getToken(), pb);
|
||||
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() {
|
||||
loadPowers();
|
||||
}
|
||||
|
||||
public static ArrayList<RunePowerEntry> getPowersForRune(int rune_id) {
|
||||
@@ -115,48 +300,13 @@ public enum PowersManager {
|
||||
// This pre-loads all powers and effects
|
||||
public static void InitializePowers() {
|
||||
|
||||
// Add EffectsBase
|
||||
ArrayList<EffectsBase> ebList = dbEffectsBaseHandler.getAllEffectsBase();
|
||||
loadEffects();
|
||||
|
||||
for (EffectsBase eb : ebList) {
|
||||
PowersManager.effectsBaseByToken.put(eb.getToken(), eb);
|
||||
PowersManager.effectsBaseByIDString.put(eb.getIDString(), eb);
|
||||
loadPowerActions();
|
||||
|
||||
}
|
||||
|
||||
// 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);
|
||||
loadPowers();
|
||||
|
||||
loadActionLists();
|
||||
}
|
||||
|
||||
public static EffectsBase setEffectToken(int ID, int token) {
|
||||
@@ -1255,6 +1405,27 @@ public enum PowersManager {
|
||||
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) {
|
||||
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(token);
|
||||
|
||||
@@ -1580,9 +1751,6 @@ public enum PowersManager {
|
||||
//Pet only
|
||||
allTargets = WorldGrid.getObjectsInRangePartial(
|
||||
targetLoc, pb.getRadius(), MBServerStatics.MASK_PET);
|
||||
else if (pb.targetNecroPet())
|
||||
allTargets = WorldGrid.getObjectsInRangePartialNecroPets(
|
||||
targetLoc, pb.getRadius());
|
||||
else
|
||||
allTargets = WorldGrid.getObjectsInRangePartial(
|
||||
targetLoc, pb.getRadius(), 0);
|
||||
@@ -1694,6 +1862,11 @@ public enum PowersManager {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isRestrictedMonsterType(awo, pb)) {
|
||||
awolist.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (awo != null && awo.getObjectType().equals(GameObjectType.PlayerCharacter)) {
|
||||
|
||||
// Remove players who are in safe mode
|
||||
@@ -1779,9 +1952,6 @@ public enum PowersManager {
|
||||
//Pet only
|
||||
allTargets = WorldGrid.getObjectsInRangePartial(
|
||||
targetLoc, pb.getRadius(), MBServerStatics.MASK_PET);
|
||||
else if (pb.targetNecroPet())
|
||||
allTargets = WorldGrid.getObjectsInRangePartialNecroPets(
|
||||
targetLoc, pb.getRadius());
|
||||
else
|
||||
allTargets = WorldGrid.getObjectsInRangePartial(
|
||||
targetLoc, pb.getRadius(), 0);
|
||||
@@ -1846,6 +2016,11 @@ public enum PowersManager {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isRestrictedMonsterType(awo, pb)) {
|
||||
awolist.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (awo != null && awo.getObjectType().equals(GameObjectType.PlayerCharacter)) {
|
||||
// Remove players who are in safe mode
|
||||
PlayerCharacter pcc = (PlayerCharacter) awo;
|
||||
@@ -2238,14 +2413,14 @@ public enum PowersManager {
|
||||
String outmsg = "Invalid Target";
|
||||
ChatManager.chatSystemInfo(pc, outmsg);
|
||||
return false; // can't target player, stop here
|
||||
} // target is mob
|
||||
} // target is pet; pets also carry MASK_MOB, so test them first. A pet is still a Mobile (client 0x49E440)
|
||||
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_PET) != 0)
|
||||
return pb.targetPet() || pb.targetMob();
|
||||
|
||||
// target is mob
|
||||
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_MOB) != 0)
|
||||
return pb.targetMob();
|
||||
|
||||
// target is pet
|
||||
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_PET) != 0)
|
||||
return pb.targetPet();
|
||||
|
||||
// target is Building
|
||||
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_BUILDING) != 0)
|
||||
return pb.targetBuilding();
|
||||
@@ -2255,12 +2430,12 @@ public enum PowersManager {
|
||||
if (pb.targetItem())
|
||||
return true;
|
||||
// TODO add these checks later
|
||||
else if (pb.targetArmor() && item.template.item_type.equals(ItemType.ARMOR))
|
||||
else if (pb.targetArmor() && item.template.getItemType().equals(ItemType.ARMOR))
|
||||
return true;
|
||||
else if (pb.targetJewelry() && item.template.item_type.equals(ItemType.JEWELRY))
|
||||
else if (pb.targetJewelry() && item.template.getItemType().equals(ItemType.JEWELRY))
|
||||
return true;
|
||||
else
|
||||
return pb.targetWeapon() && item.template.item_type.equals(ItemType.WEAPON);
|
||||
return pb.targetWeapon() && item.template.getItemType().equals(ItemType.WEAPON);
|
||||
} // How did we get here? all valid targets have been covered
|
||||
else
|
||||
return false;
|
||||
|
||||
@@ -82,11 +82,7 @@ public class ChantJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
if (AbstractWorldObject.IsAbstractCharacter(source))
|
||||
//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);
|
||||
((AbstractCharacter) this.source).setLastChant((int) (this.power.getChantDuration()) * 1000, this);
|
||||
} else {
|
||||
PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains);
|
||||
if (AbstractWorldObject.IsAbstractCharacter(source)) {
|
||||
|
||||
@@ -25,6 +25,7 @@ public class DamageOverTimeJob extends AbstractEffectJob {
|
||||
private final DamageOverTimePowerAction dot;
|
||||
private int iteration = 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) {
|
||||
super(source, target, stackType, trains, action, power, eb);
|
||||
@@ -33,7 +34,9 @@ public class DamageOverTimeJob extends AbstractEffectJob {
|
||||
if (this.target != null && AbstractWorldObject.IsAbstractCharacter(target))
|
||||
this.liveCounter = ((AbstractCharacter) target).getLiveCounter();
|
||||
|
||||
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
|
||||
@@ -82,7 +85,7 @@ public class DamageOverTimeJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
public int getTickLength() {
|
||||
return this.dot.getNumIterations() * 1000;
|
||||
return this.tickLength;
|
||||
}
|
||||
|
||||
public int inc() {
|
||||
|
||||
@@ -21,11 +21,15 @@ public class TransferStatOTJob extends AbstractEffectJob {
|
||||
|
||||
private final TransferStatOTPowerAction dot;
|
||||
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) {
|
||||
super(source, target, stackType, trains, action, power, eb);
|
||||
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
|
||||
@@ -64,7 +68,7 @@ public class TransferStatOTJob extends AbstractEffectJob {
|
||||
}
|
||||
|
||||
public int getTickLength() {
|
||||
return this.dot.getNumIterations() * 1000;
|
||||
return this.tickLength;
|
||||
}
|
||||
|
||||
public int inc() {
|
||||
|
||||
@@ -12,9 +12,9 @@ import engine.gameManager.DbManager;
|
||||
import engine.gameManager.ForgeManager;
|
||||
import engine.mbEnums;
|
||||
import engine.objects.Item;
|
||||
import engine.objects.ItemTemplate;
|
||||
import engine.objects.NPC;
|
||||
import engine.objects.Warehouse;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@@ -127,16 +127,16 @@ public class WorkOrder implements Delayed {
|
||||
|
||||
int validation_result = 0;
|
||||
|
||||
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(workOrder.templateID);
|
||||
|
||||
if (workOrder.vendor.getBuilding() == null)
|
||||
return 58; //58: The formula is beyond the means of this facility
|
||||
|
||||
if (!workOrder.vendor.charItemManager.hasRoomInventory(template.item_wt))
|
||||
if (!workOrder.vendor.charItemManager.hasRoomInventory(template.getItemWt()))
|
||||
return 30; //30: That person cannot carry that item
|
||||
|
||||
if ((workOrder.prefixToken != 0 || workOrder.suffixToken != 0) &&
|
||||
!workOrder.vendor.getItemModTable().contains((template.modTable)))
|
||||
!workOrder.vendor.getItemModTable().contains(ForgeManager.getVendorModTable(workOrder.templateID)))
|
||||
return 59; //59: This hireling does not have this formula
|
||||
|
||||
if (!Warehouse.calcCostOverrun(workOrder).isEmpty())
|
||||
|
||||
@@ -583,36 +583,6 @@ final public class FastMath {
|
||||
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
|
||||
*/
|
||||
|
||||
+91
-40
@@ -15,10 +15,10 @@ import engine.math.Vector2f;
|
||||
import engine.math.Vector3f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.objects.AbstractCharacter;
|
||||
import engine.objects.ItemTemplate;
|
||||
import engine.objects.Shrine;
|
||||
import engine.objects.Zone;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.RunePowerEntry;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -824,6 +824,7 @@ public class mbEnums {
|
||||
ACID,
|
||||
DISEASE,
|
||||
UNKNOWN,
|
||||
ANTISIEGE,
|
||||
// these added for immunities
|
||||
ATTACK,
|
||||
POWERS,
|
||||
@@ -842,34 +843,26 @@ public class mbEnums {
|
||||
|
||||
public static DamageType getDamageType(String modName) {
|
||||
|
||||
String name;
|
||||
|
||||
if (modName.isEmpty())
|
||||
return DamageType.NONE;
|
||||
|
||||
if(modName.toLowerCase().equals("blind"))
|
||||
modName = "BLINDNESS";
|
||||
// Client and DB strings vary in case and punctuation ("Fire", "Anti-Siege")
|
||||
|
||||
if(modName.toLowerCase().equals("powerblock"))
|
||||
modName = "POWERINHIBITOR";
|
||||
name = modName.replaceAll("[\\s,-]", "").toUpperCase();
|
||||
|
||||
//validity check for not looking up damage type that doesn't exist
|
||||
boolean valid = false;
|
||||
for(DamageType type : DamageType.values()){
|
||||
if(type.name().equals(modName))
|
||||
valid = true;
|
||||
}
|
||||
if (name.equals("BLIND"))
|
||||
name = "BLINDNESS";
|
||||
|
||||
if(!valid)
|
||||
return DamageType.NONE;
|
||||
if (name.equals("POWERBLOCK"))
|
||||
name = "POWERINHIBITOR";
|
||||
|
||||
DamageType damageType;
|
||||
for (DamageType type : DamageType.values())
|
||||
if (type.name().equals(name))
|
||||
return type;
|
||||
|
||||
try {
|
||||
damageType = DamageType.valueOf(modName.replace(",", "").toUpperCase());
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
return DamageType.NONE;
|
||||
}
|
||||
return damageType;
|
||||
return DamageType.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1104,11 +1097,28 @@ public class mbEnums {
|
||||
|
||||
public static EffectSourceType GetEffectSourceType(String modName) {
|
||||
EffectSourceType returnMod;
|
||||
String name;
|
||||
|
||||
if (modName.isEmpty())
|
||||
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 {
|
||||
returnMod = EffectSourceType.valueOf(modName.replace(",", ""));
|
||||
returnMod = EffectSourceType.valueOf(name);
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
return EffectSourceType.None;
|
||||
@@ -1138,6 +1148,7 @@ public class mbEnums {
|
||||
BMHealing,
|
||||
Charm,
|
||||
ClassBoon,
|
||||
ColdDeBuff,
|
||||
Confusion,
|
||||
DamageAbsorber,
|
||||
DamageDebuff,
|
||||
@@ -1152,6 +1163,7 @@ public class mbEnums {
|
||||
ElementalDeBuff,
|
||||
EnchantWeapon,
|
||||
Fear,
|
||||
FireDeBuff,
|
||||
Flight,
|
||||
Frenzy,
|
||||
GroupHeal,
|
||||
@@ -1159,12 +1171,16 @@ public class mbEnums {
|
||||
HealOverTime,
|
||||
HealResBuff,
|
||||
HealthPotion,
|
||||
HolyDeBuff,
|
||||
IgnoreStack,
|
||||
Invisible,
|
||||
LightningDeBuff,
|
||||
MagicDeBuff,
|
||||
ManaPotion,
|
||||
MangonelFire,
|
||||
MeleeDamageDeBuff,
|
||||
MeleeDeBuff,
|
||||
MentalDeBuff,
|
||||
MoveBuff,
|
||||
MoveDebuff,
|
||||
NoFear,
|
||||
@@ -1177,6 +1193,9 @@ public class mbEnums {
|
||||
NoTrack,
|
||||
PassiveDefense,
|
||||
PersAttrSPRBuff,
|
||||
PersonalAttrCONBuff,
|
||||
PersonalAttrDEXBuff,
|
||||
PersonalAttrSTRBuff,
|
||||
PetBuff,
|
||||
PierceResistanceDebuff,
|
||||
PoisonBuchinine,
|
||||
@@ -1199,7 +1218,6 @@ public class mbEnums {
|
||||
RecoveryStaminaDeBuff,
|
||||
ResistanceBuff,
|
||||
ResistanceDeBuff,
|
||||
ResistanceDebuff,
|
||||
Root,
|
||||
SafeMode,
|
||||
SelfOneAttrBuff,
|
||||
@@ -1223,6 +1241,7 @@ public class mbEnums {
|
||||
Stun,
|
||||
Track,
|
||||
Transform,
|
||||
UnholyDeBuff,
|
||||
WeaponMove;
|
||||
|
||||
public static StackType GetStackType(String modName) {
|
||||
@@ -1509,6 +1528,15 @@ public class mbEnums {
|
||||
}
|
||||
}
|
||||
|
||||
// rune_type values from the client cache data (COBJECTS/RUNE)
|
||||
|
||||
public enum RuneType {
|
||||
CLASS,
|
||||
DISCIPLINE,
|
||||
RACE,
|
||||
TALENT
|
||||
}
|
||||
|
||||
public enum ShrineType {
|
||||
|
||||
Aelfborn(1701900, -75506007, true),
|
||||
@@ -2632,55 +2660,61 @@ public class mbEnums {
|
||||
|
||||
public enum MinionType {
|
||||
AELFBORNGUARD(951, 1637, MinionClass.MELEE, "Guard", "Aelfborn"),
|
||||
AELFBORNMAGE(952, 1635, MinionClass.MAGE, "Adept", "Aelfborn"),
|
||||
AELFBORNMAGE(952, 1635, MinionClass.MAGE, "Adept", "Aelfborn", "WIZ-016", "WIZ-061", "WIZ-025", "WIZ-020"),
|
||||
AMAZONGUARD(1500, 1670, MinionClass.MELEE, "Guard", "Amazon"),
|
||||
AMAZONMAGE(1502, 1638, MinionClass.MAGE, "Fury", "Amazon"),
|
||||
AMAZONMAGE(1502, 1638, MinionClass.MAGE, "Fury", "Amazon", "FUR-003", "FUR-011", "FUR-009", "FUR-005"),
|
||||
ARACOIXGUARD(1600, 1672, MinionClass.MELEE, "Guard", "Aracoix"), //used guard captain equipset.
|
||||
ARACOIXMAGE(1602, 885, MinionClass.MAGE, "Adept", "Aracoix"),
|
||||
ARACOIXMAGE(1602, 885, MinionClass.MAGE, "Adept", "Aracoix", "WLR-029", "WLR-019", "WLR-027", "WLR-012"),
|
||||
CENTAURGUARD(1650, 1642, MinionClass.MELEE, "Guard", "Centaur"),
|
||||
CENTAURMAGE(1652, 1640, MinionClass.MAGE, "Druid", "Centaur"),
|
||||
CENTAURMAGE(1652, 1640, MinionClass.MAGE, "Druid", "Centaur", "PRL-017", "PRL-046", "PRL-033", "PRL-009"),
|
||||
DWARVENARCHER(845, 1644, MinionClass.ARCHER, "Marksman", "Dwarven"),
|
||||
DWARVENGUARD(1050, 1666, MinionClass.MELEE, "Guard", "Dwarven"),
|
||||
DWARVENMAGE(1052, 1643, MinionClass.MAGE, "War Priest", "Dwarven"),
|
||||
DWARVENMAGE(1052, 1643, MinionClass.MAGE, "War Priest", "Dwarven", "PRL-017", "PRL-046", "PRL-033", "PRL-009"),
|
||||
ELFGUARD(1180, 1671, MinionClass.MELEE, "Guard", "Elven"), //old 1645
|
||||
ELFMAGE(1182, 1667, MinionClass.MAGE, "Adept", "Elven"),
|
||||
ELFMAGE(1182, 1667, MinionClass.MAGE, "Adept", "Elven", "WIZ-020", "WIZ-025", "WIZ-016", "WIZ-061"),
|
||||
FORESTGUARD(1550, 1668, MinionClass.MELEE, "Guard", "Forest"), //captain changed to guard equipset
|
||||
FORESTMAGE(1552, 436, MinionClass.MAGE, "Adept", "Forest"),
|
||||
FORESTMAGE(1552, 436, MinionClass.MAGE, "Adept", "Forest", "DRU-009", "DRU-023", "DRU-036", "DRU-015"),
|
||||
HOLYGUARD(1525, 1658, MinionClass.MELEE, "Guard", "Holy Church"),
|
||||
HOLYMAGE(1527, 1646, MinionClass.MAGE, "Prelate", "Holy Church"),
|
||||
HOLYMAGE(1527, 1646, MinionClass.MAGE, "Prelate", "Holy Church", "PRL-017", "PRL-046", "PRL-033", "PRL-009"),
|
||||
HUMANARCHER(846, 1654, MinionClass.ARCHER, "Archer", "Human"),
|
||||
HUMANGUARD(840, 1665, MinionClass.MELEE, "Guard", "Human"),
|
||||
HUMANMAGE(848, 1655, MinionClass.MAGE, "Adept", "Human"),
|
||||
HUMANMAGE(848, 1655, MinionClass.MAGE, "Adept", "Human", "WIZ-016", "WIZ-025", "WIZ-020", "WIZ-061"),
|
||||
IREKEIGUARD(1350, 1659, MinionClass.MELEE, "Guard", "Irekei"),
|
||||
IREKEIMAGE(1352, 1660, MinionClass.MAGE, "Adept", "Irekei"),
|
||||
IREKEIMAGE(1352, 1660, MinionClass.MAGE, "Adept", "Irekei", "WIZ-061", "WIZ-016", "WIZ-025", "WIZ-020"),
|
||||
MINOTAURARCHER(1701, 0, MinionClass.ARCHER, "Archer", "Minotaur"),
|
||||
MINOTAURGUARD(1700, 1673, MinionClass.MELEE, "Guard", "Minotaur"),
|
||||
NORTHMANGUARD(1250, 1669, MinionClass.MELEE, "Guard", "Northman"),
|
||||
NORTHMANMAGE(1252, 1650, MinionClass.MAGE, "Runecaster", "Northman"),
|
||||
NORTHMANMAGE(1252, 1650, MinionClass.MAGE, "Runecaster", "Northman", "WIZ-061", "WIZ-016", "WIZ-025", "WIZ-020"),
|
||||
SHADEGUARD(1450, 1662, MinionClass.MELEE, "Guard", "Shade"),
|
||||
SHADEMAGE(1452, 1664, MinionClass.MAGE, "Adept", "Shade"),
|
||||
SHADEMAGE(1452, 1664, MinionClass.MAGE, "Adept", "Shade", "NEC-001", "NEC-003", "MAG-013", "MAG-025"),
|
||||
TEMPLARGUARD(841, 1564, MinionClass.MELEE, "Marksman", "Templar"),
|
||||
TEMPLEGUARD(1575, 1652, MinionClass.MELEE, "Guard", "Temple"),
|
||||
TEMPLEMAGE(1577, 1656, MinionClass.MAGE, "Confessor", "Temple"),
|
||||
TEMPLEMAGE(1577, 1656, MinionClass.MAGE, "Confessor", "Temple", "CON-048", "CON-015", "CON-012", "CON-051"),
|
||||
UNDEADGUARD(980100, 1674, MinionClass.MELEE, "Guard", "Undead"),
|
||||
UNDEADMAGE(980102, 1675, MinionClass.MAGE, "Adept", "Undead"),
|
||||
UNDEADMAGE(980102, 1675, MinionClass.MAGE, "Adept", "Undead", "NEC-001", "NEC-003", "MAG-013", "MAG-025"),
|
||||
WEREWOLFGUARD(980104, 0, MinionClass.MELEE, "Guard", "Werewolf"),
|
||||
WEREBEARGUARD(980103, 0, MinionClass.MELEE, "Guard", "Werebear");
|
||||
public static HashMap<Integer, MinionType> ContractToMinionMap = new HashMap<>();
|
||||
private static final int CAPTAIN_POWER_RANK = 40;
|
||||
private final int captainContractID;
|
||||
private final int equipSetID;
|
||||
private final MinionClass minionClass;
|
||||
private final String name;
|
||||
private final String race;
|
||||
private final ArrayList<RunePowerEntry> captainPowers;
|
||||
|
||||
MinionType(int captainContractID, int equipSetID, MinionClass minionClass, String name, String race) {
|
||||
// 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, String... captainPowerTypes) {
|
||||
|
||||
this.captainContractID = captainContractID;
|
||||
this.equipSetID = equipSetID;
|
||||
this.minionClass = minionClass;
|
||||
this.name = name;
|
||||
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() {
|
||||
@@ -2689,6 +2723,17 @@ public class mbEnums {
|
||||
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() {
|
||||
return name;
|
||||
}
|
||||
@@ -2761,7 +2806,6 @@ public class mbEnums {
|
||||
public static HashMap<Integer, ResourceType> templateHashLookup = new HashMap<>();
|
||||
public static HashMap<Integer, ResourceType> resourceHashLookup = new HashMap<>();
|
||||
public int templateID;
|
||||
public ItemTemplate template;
|
||||
public int resourceHash;
|
||||
public int templateHash;
|
||||
public int deposit_limit;
|
||||
@@ -2769,7 +2813,6 @@ public class mbEnums {
|
||||
|
||||
ResourceType(int templateID, int resourceHash, int templateHash, int deposit_limit, int mine_production) {
|
||||
this.templateID = templateID;
|
||||
this.template = ItemTemplate.templates.get(this.templateID);
|
||||
this.resourceHash = resourceHash;
|
||||
this.templateHash = templateHash;
|
||||
this.deposit_limit = deposit_limit;
|
||||
@@ -2908,6 +2951,14 @@ public class mbEnums {
|
||||
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 {
|
||||
None,
|
||||
Strength,
|
||||
|
||||
@@ -19,6 +19,7 @@ import engine.mobileAI.Threads.ReSpawner;
|
||||
import engine.mobileAI.utilities.MovementUtilities;
|
||||
import engine.net.client.msg.PerformActionMsg;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.powers.ActionsBase;
|
||||
import engine.powers.PowersBase;
|
||||
import engine.powers.RunePowerEntry;
|
||||
@@ -49,6 +50,8 @@ public class MobAI {
|
||||
|
||||
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) {
|
||||
|
||||
try {
|
||||
@@ -276,7 +279,7 @@ public class MobAI {
|
||||
|
||||
// Mobile has no powers defined in mobbase or contract..
|
||||
|
||||
if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() && PowersManager.getPowersForRune(contractID).isEmpty())
|
||||
if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() && mbEnums.MinionType.getCaptainPowers(contractID).isEmpty())
|
||||
return false;
|
||||
|
||||
if (mob.nextCastTime == 0)
|
||||
@@ -309,18 +312,17 @@ public class MobAI {
|
||||
powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
|
||||
purgeEntries = new ArrayList<>();
|
||||
|
||||
// Additional powers may come from the contract ID. This is to support
|
||||
// powers for player guards irrespective of the mobbase used.
|
||||
// Player guards also cast their captain contract's powers, irrespective of the mobbase used.
|
||||
|
||||
if (mob.isPlayerGuard()) {
|
||||
|
||||
ArrayList<RunePowerEntry> contractEntries = new ArrayList<>();
|
||||
|
||||
if (mob.contract != null)
|
||||
contractEntries = PowersManager.getPowersForRune(mob.contractUUID);
|
||||
contractEntries = mbEnums.MinionType.getCaptainPowers(mob.contractUUID);
|
||||
|
||||
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION))
|
||||
contractEntries = PowersManager.getPowersForRune(mob.guardCaptain.contractUUID);
|
||||
contractEntries = mbEnums.MinionType.getCaptainPowers(mob.guardCaptain.contractUUID);
|
||||
|
||||
powerEntries.addAll(contractEntries);
|
||||
|
||||
@@ -357,7 +359,7 @@ public class MobAI {
|
||||
int powerRank = runePowerEntry.rank;
|
||||
|
||||
if (mob.isPlayerGuard())
|
||||
powerRank = getGuardPowerRank(mob);
|
||||
powerRank = getGuardPowerRank(mob, mobPower);
|
||||
|
||||
// Cast the spell
|
||||
|
||||
@@ -387,33 +389,27 @@ public class MobAI {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int getGuardPowerRank(Mob mob) {
|
||||
int powerRank = 1;
|
||||
// Client power rank adds every POWERSADJ step at or below the level (0x4B34B0). The Standing Guard rune's
|
||||
// Wizard steps are the curve for every captain spell, capped at MaxLevel as player casts are.
|
||||
public static int getGuardPowerRank(Mob mob, PowersBase power) {
|
||||
|
||||
switch (mob.getRank()) {
|
||||
case 1:
|
||||
powerRank = 10;
|
||||
break;
|
||||
case 2:
|
||||
powerRank = 15;
|
||||
break;
|
||||
case 3:
|
||||
powerRank = 20;
|
||||
break;
|
||||
case 4:
|
||||
powerRank = 25;
|
||||
break;
|
||||
case 5:
|
||||
powerRank = 30;
|
||||
break;
|
||||
case 6:
|
||||
powerRank = 35;
|
||||
break;
|
||||
case 7:
|
||||
powerRank = 40;
|
||||
break;
|
||||
}
|
||||
return powerRank;
|
||||
RuneTemplate guardRune = RuneTemplate._runes.get(STANDING_GUARD_RUNE_ID);
|
||||
ArrayList<int[]> rankSteps;
|
||||
int powerRank = 0;
|
||||
|
||||
if (guardRune == null || guardRune.item_power_action.isEmpty())
|
||||
return 1;
|
||||
|
||||
rankSteps = guardRune.item_power_action.get(power.getIDString());
|
||||
|
||||
if (rankSteps == null)
|
||||
rankSteps = guardRune.item_power_action.values().iterator().next();
|
||||
|
||||
for (int[] rankStep : rankSteps)
|
||||
if (rankStep[1] <= mob.getLevel())
|
||||
powerRank += rankStep[0];
|
||||
|
||||
return Math.max(1, Math.min(powerRank, power.getMaxTrains()));
|
||||
}
|
||||
|
||||
public static void mobCallForHelp(Mob mob) {
|
||||
@@ -470,7 +466,7 @@ public class MobAI {
|
||||
|
||||
//trebuchet spawn handler
|
||||
|
||||
if (mob.despawned && mob.getMobBase().getLoadID() == 13171) {
|
||||
if (mob.despawned && mob.getMobBase().getObjectUUID() == 13171) {
|
||||
checkForRespawn(mob);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class ActivateNPCMsgHandler extends AbstractClientMsgHandler {
|
||||
// Filter hirelings by slot type
|
||||
|
||||
for (Item hirelings : player.getInventory()) {
|
||||
if (hirelings.template.item_type.equals(ItemType.EMPLOYMENTCONTRACT)) {
|
||||
if (hirelings.template.getItemType().equals(ItemType.EMPLOYMENTCONTRACT)) {
|
||||
|
||||
contract = DbManager.ContractQueries.GET_CONTRACT(hirelings.templateID);
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public class AddItemToTradeWindowMsgHandler extends AbstractClientMsgHandler {
|
||||
if (!item.validForInventory(source.getClientConnection(), source, source.charItemManager))
|
||||
return false;
|
||||
|
||||
if (!tradingWith.hasRoomTrade(item.template.item_wt)) {
|
||||
if (!tradingWith.hasRoomTrade(item.template.getItemWt())) {
|
||||
dispatch = Dispatch.borrow(source, msg);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
||||
return false;
|
||||
|
||||
@@ -97,9 +97,13 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler {
|
||||
if (city == null)
|
||||
return true;
|
||||
|
||||
DbManager.WarehouseQueries.DELETE_WAREHOUSE(city.warehouse);
|
||||
Warehouse.destroyedWarehouses.remove(building.getObjectUUID());
|
||||
|
||||
city.warehouse = null;
|
||||
// Rubble no longer owns city.warehouse, which may be null or a newly placed warehouse
|
||||
if (city.warehouse != null && building.getRank() != -1) {
|
||||
DbManager.WarehouseQueries.DELETE_WAREHOUSE(city.warehouse);
|
||||
city.warehouse = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import engine.net.client.msg.guild.GuildInfoMsg;
|
||||
import engine.objects.Guild;
|
||||
import engine.objects.Item;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.parsers.objects.DeedTemplate;
|
||||
import engine.util.StringUtils;
|
||||
|
||||
public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
|
||||
@@ -42,6 +43,7 @@ public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
|
||||
Guild playerGuild;
|
||||
|
||||
Item charter;
|
||||
DeedTemplate charterDeed;
|
||||
Dispatch dispatch;
|
||||
|
||||
msg = (GuildCreationFinalizeMsg) baseMsg;
|
||||
@@ -65,7 +67,9 @@ public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
|
||||
|
||||
// Item must be a valid charterType (type 10 in db)
|
||||
|
||||
if (charter == null || (charter.template.item_type.equals(ItemType.CHARTER) == false)) {
|
||||
charterDeed = DeedTemplate._deeds.get(charter.templateID);
|
||||
|
||||
if (charterDeed == null || (charterDeed.item_type.equals(ItemType.CHARTER) == false)) {
|
||||
ErrorPopupMsg.sendErrorPopup(player, GuildManager.NO_CHARTER_FOUND);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -238,10 +238,10 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (targetItem == null)
|
||||
return;
|
||||
|
||||
if (targetItem.template.item_type.equals(ItemType.GOLD))
|
||||
if (targetItem.template.getItemType().equals(ItemType.GOLD))
|
||||
return;
|
||||
|
||||
if (!vendor.charItemManager.hasRoomInventory(targetItem.template.item_wt)) {
|
||||
if (!vendor.charItemManager.hasRoomInventory(targetItem.template.getItemWt())) {
|
||||
ErrorPopupMsg.sendErrorPopup(player, 21);
|
||||
return;
|
||||
}
|
||||
@@ -319,7 +319,7 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (targetItem == null)
|
||||
continue;
|
||||
|
||||
if (targetItem.template.item_type.equals(ItemType.GOLD))
|
||||
if (targetItem.template.getItemType().equals(ItemType.GOLD))
|
||||
return;
|
||||
|
||||
if (!vendor.charItemManager.doesCharOwnThisItem(targetItem.getObjectUUID()))
|
||||
@@ -328,14 +328,14 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (!vendor.charItemManager.inventoryContains(targetItem))
|
||||
continue;
|
||||
|
||||
itemValue = targetItem.template.item_value;
|
||||
itemValue = targetItem.template.getItemValue();
|
||||
|
||||
if (vendor.getBuilding().getStrongboxValue() + itemValue > vendor.getBuilding().getMaxGold()) {
|
||||
ErrorPopupMsg.sendErrorPopup(player, 201);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (targetItem.template.item_type) {
|
||||
switch (targetItem.template.getItemType()) {
|
||||
case EMPLOYMENTCONTRACT:
|
||||
case CHARTER:
|
||||
case DEED:
|
||||
@@ -465,13 +465,13 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (targetItem == null)
|
||||
return;
|
||||
|
||||
if (targetItem.template.item_type.equals(ItemType.GOLD))
|
||||
if (targetItem.template.getItemType().equals(ItemType.GOLD))
|
||||
return;
|
||||
|
||||
if (!vendor.charItemManager.inventoryContains(targetItem))
|
||||
return;
|
||||
|
||||
if (!player.charItemManager.hasRoomInventory(targetItem.template.item_wt))
|
||||
if (!player.charItemManager.hasRoomInventory(targetItem.template.getItemWt()))
|
||||
return;
|
||||
|
||||
player.charItemManager.buyFromNPC(targetItem, vendor);
|
||||
|
||||
@@ -161,7 +161,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
|
||||
if (itemRet == null)
|
||||
return true;
|
||||
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) {
|
||||
// this is done to prevent the temporary goldItem item
|
||||
// (from the mob) from appearing in player's inventory.
|
||||
// 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
|
||||
Group group = GroupManager.getGroup(player);
|
||||
|
||||
if (group != null && group.getSplitGold() && (item.template.item_type.equals(mbEnums.ItemType.GOLD) == false)) {
|
||||
if (group != null && group.getSplitGold() && (item.template.getItemType().equals(mbEnums.ItemType.GOLD) == false)) {
|
||||
String name = item.getName();
|
||||
String text = player.getFirstName() + " has looted " + name + '.';
|
||||
ChatManager.chatGroupInfoCanSee(player, text);
|
||||
@@ -202,7 +202,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
|
||||
if (itemRet == null)
|
||||
return true;
|
||||
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) {
|
||||
// this is done to prevent the temporary goldItem item
|
||||
// (from the mob) from appearing in player's inventory.
|
||||
// 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
|
||||
Group group = GroupManager.getGroup(player);
|
||||
|
||||
if (group != null && group.getSplitGold() && (item.template.item_type.equals(mbEnums.ItemType.GOLD) == false)) {
|
||||
if (group != null && group.getSplitGold() && (item.template.getItemType().equals(mbEnums.ItemType.GOLD) == false)) {
|
||||
String name = item.getName();
|
||||
String text = player.getFirstName() + " has looted " + name + '.';
|
||||
ChatManager.chatGroupInfoCanSee(player, text);
|
||||
|
||||
@@ -141,17 +141,9 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
City city = building.getCity();
|
||||
Warehouse warehouse = Warehouse.destroyedWarehouses.get(building.getObjectUUID());
|
||||
|
||||
if (city == null)
|
||||
return true;
|
||||
|
||||
Warehouse warehouse = city.warehouse;
|
||||
|
||||
if (warehouse == null)
|
||||
return true;
|
||||
|
||||
if (Warehouse.isEmpty(warehouse)) {
|
||||
if (warehouse == null || Warehouse.isEmpty(warehouse)) {
|
||||
ErrorPopupMsg.sendErrorPopup(player, 167); // no more resources.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.*;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.DeedTemplate;
|
||||
import engine.powers.PowersBase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -78,7 +79,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
int uuid = item.templateID;
|
||||
|
||||
switch (item.template.item_type) {
|
||||
switch (item.template.getItemType()) {
|
||||
|
||||
case DEED: //buildings
|
||||
//Call add building screen here, ib.getUseID() get's building ID
|
||||
@@ -99,7 +100,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
pam.setX(loc.getX() + 64); //offset grid from tol
|
||||
pam.setY(loc.getY());
|
||||
pam.setZ(loc.getZ() + 64); //offset grid from tol
|
||||
pam.addPlacementInfo(item.template.deed_structure_id);
|
||||
pam.addPlacementInfo(DeedTemplate._deeds.get(item.templateID).deed_structure_id);
|
||||
|
||||
dispatch = Dispatch.borrow(player, pam);
|
||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
|
||||
@@ -187,14 +188,14 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
if (uuid > 680069 && uuid < 680074) //Handle Charter, Deed, Petition, Warrant here
|
||||
break;
|
||||
|
||||
if (item.template.item_bane_rank > 0) {
|
||||
if (item.template.getItemBaneRank() > 0) {
|
||||
|
||||
// Only one banestone at a time
|
||||
|
||||
lock.writeLock().lock();
|
||||
|
||||
try {
|
||||
if (Bane.summonBanestone(player, origin, item.template.item_bane_rank) == true)
|
||||
if (Bane.summonBanestone(player, origin, item.template.getItemBaneRank()) == true)
|
||||
itemMan.consume(item);
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
@@ -225,7 +226,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
// Bypass for waterbuckets
|
||||
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.BUCKET)) {
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.BUCKET)) {
|
||||
|
||||
// test for valid target type
|
||||
if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter)
|
||||
@@ -250,10 +251,9 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
}
|
||||
|
||||
if (waterbucketBypass == false) {
|
||||
String powerString = item.template.item_power_grant.keySet().iterator().next();
|
||||
PowersBase powerAction = PowersManager.powersBaseByIDString.get(powerString);
|
||||
int powerValue = item.template.item_power_grant.get(powerString);
|
||||
PowersManager.applyPower(player, target, Vector3fImmutable.ZERO, powerAction.getToken(), powerValue, true);
|
||||
engine.parsers.objects.PowerGrant powerGrant = item.template.getItemPowerGrant().get(0);
|
||||
PowersBase powerAction = PowersManager.powersBaseByIDString.get(powerGrant.power_type);
|
||||
PowersManager.applyPower(player, target, Vector3fImmutable.ZERO, powerAction.getToken(), powerGrant.power_value, true);
|
||||
}
|
||||
itemMan.consume(item);
|
||||
} else //just remove the item at this point
|
||||
@@ -266,7 +266,8 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
case RUNE:
|
||||
if(ApplyRuneMsg.applyRune(uuid, origin, player)) {
|
||||
itemMan.consume(item);
|
||||
}
|
||||
} else
|
||||
ErrorPopupMsg.sendErrorPopup(player, 161);
|
||||
break;
|
||||
default: //shouldn't be here, consume item
|
||||
dispatch = Dispatch.borrow(player, msg);
|
||||
|
||||
@@ -18,6 +18,7 @@ import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.net.client.msg.PlaceAssetMsg;
|
||||
import engine.net.client.msg.PlaceAssetMsg.PlacementInfo;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.DeedTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.joda.time.DateTime;
|
||||
import org.pmw.tinylog.Logger;
|
||||
@@ -135,6 +136,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
private static boolean validateBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo placementInfo) {
|
||||
|
||||
Bane bane;
|
||||
|
||||
if (serverZone.guild_zone == false) {
|
||||
PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName());
|
||||
return false;
|
||||
@@ -205,6 +208,15 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
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)) {
|
||||
PlaceAssetMsg.sendPlaceAssetError(origin, 3, ""); // Conflict between proposed assets
|
||||
return false;
|
||||
@@ -345,8 +357,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
Item contract = null;
|
||||
|
||||
for (Item inventoryItem : playerCharacter.getInventory()) {
|
||||
if (inventoryItem.template.item_type.equals(ItemType.DEED) &&
|
||||
inventoryItem.template.deed_structure_id == buildingList.getBlueprintUUID()) {
|
||||
if (inventoryItem.template.getItemType().equals(ItemType.DEED) &&
|
||||
DeedTemplate._deeds.get(inventoryItem.templateID).deed_structure_id == buildingList.getBlueprintUUID()) {
|
||||
contract = inventoryItem;
|
||||
break;
|
||||
}
|
||||
@@ -1341,6 +1353,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
}
|
||||
|
||||
Warehouse warehouse = new Warehouse(warehouseBuilding);
|
||||
Warehouse.destroyedWarehouses.values().removeIf(destroyed -> destroyed.city == city);
|
||||
city.warehouse = warehouse;
|
||||
DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse);
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import engine.mbEnums;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.ClientNetMsg;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.net.client.msg.RefineMsg;
|
||||
import engine.net.client.msg.RefinerScreenMsg;
|
||||
import engine.objects.*;
|
||||
@@ -88,6 +89,9 @@ public class RefineMsgHandler extends AbstractClientMsgHandler {
|
||||
public static boolean refineSkill(ClientConnection origin, PlayerCharacter pc, int token, RefineMsg msg) {
|
||||
CharacterSkill skill = null;
|
||||
ConcurrentHashMap<String, CharacterSkill> skills = pc.getSkills();
|
||||
int refinedAmount;
|
||||
int requiredAmount;
|
||||
|
||||
for (CharacterSkill sk : skills.values()) {
|
||||
if (sk == null)
|
||||
continue;
|
||||
@@ -106,17 +110,16 @@ public class RefineMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
//TODO verify if any skills have this as prereq
|
||||
|
||||
//TODO verify if any powers have this as a prereq
|
||||
//get all players powers
|
||||
// Dropping below a trained power's skill requirement would make calculatePowers delete the power and its trains
|
||||
refinedAmount = Math.round(skill.getBaseAmountBeforeMods() + skill.calculateAmountAfterTrains(skill.getNumTrains() - 1));
|
||||
|
||||
for (CharacterPower power : pc.getPowers().values()) {
|
||||
ArrayList<PowerReq> reqs = PowerReq.getPowerReqsForRune(power.getPowerID());
|
||||
for (PowerReq req : reqs) {
|
||||
ConcurrentHashMap<String, CharacterSkill> playerSkills = pc.getSkills();
|
||||
CharacterSkill playerSkill = playerSkills.get(token);
|
||||
int currentSkillLevel = playerSkill.getTotalSkillPercet();
|
||||
if (token == req.getToken() && req.getLevel() == currentSkillLevel) {
|
||||
return false;
|
||||
}
|
||||
if (power.getTrains() < 1)
|
||||
continue;
|
||||
requiredAmount = getRequiredSkillAmount(pc, power.getPower().getToken(), token);
|
||||
if (refinedAmount < requiredAmount) {
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "You must refine " + power.getPower().getName() + " to 0 before refining any more from this skill.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +127,36 @@ public class RefineMsgHandler extends AbstractClientMsgHandler {
|
||||
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) {
|
||||
CharacterPower power = null;
|
||||
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
|
||||
|
||||
@@ -85,7 +85,7 @@ public class RepairMsgHandler extends AbstractClientMsgHandler {
|
||||
//make sure item is damaged and not destroyed
|
||||
|
||||
short dur = (short) toRepair.combat_health_current;
|
||||
short max = (short) toRepair.template.combat_health_full;
|
||||
short max = (short) toRepair.template.getCombatHealthFull();
|
||||
|
||||
//account for durability modifications
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public class TransferItemFromBankMsgHandler extends AbstractClientMsgHandler {
|
||||
return true;
|
||||
;
|
||||
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) {
|
||||
|
||||
if (!itemManager.moveGoldToInventory(item, msg.getNumItems()))
|
||||
return true;
|
||||
@@ -85,7 +85,7 @@ public class TransferItemFromBankMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
// Not gold, process update here
|
||||
|
||||
if (!itemManager.hasRoomInventory(item.template.item_wt))
|
||||
if (!itemManager.hasRoomInventory(item.template.getItemWt()))
|
||||
return true;
|
||||
|
||||
if (itemManager.moveItemToInventory(item) == false)
|
||||
|
||||
@@ -65,7 +65,7 @@ public class TransferItemToBankMsgHandler extends AbstractClientMsgHandler {
|
||||
return true;
|
||||
|
||||
if (item.containerType == mbEnums.ItemContainerType.INVENTORY && itemManager.isBankOpen())
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) {
|
||||
if (!itemManager.moveGoldToBank(item, msg.getNumItems()))
|
||||
return true;
|
||||
UpdateGoldMsg goldMes = new UpdateGoldMsg(player);
|
||||
@@ -76,7 +76,7 @@ public class TransferItemToBankMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
} else {
|
||||
|
||||
if (!itemManager.hasRoomBank(item.template.item_wt))
|
||||
if (!itemManager.hasRoomBank(item.template.getItemWt()))
|
||||
return true;
|
||||
|
||||
if (!itemManager.moveItemToBank(item))
|
||||
|
||||
@@ -86,7 +86,7 @@ public class VendorBuyMsgHandler extends AbstractClientMsgHandler {
|
||||
if (me.objectUUID == vendorBuyMsg.getItemID()) {
|
||||
|
||||
//test room available for item
|
||||
if (!itemMan.hasRoomInventory(me.template.item_wt))
|
||||
if (!itemMan.hasRoomInventory(me.template.getItemWt()))
|
||||
return true;
|
||||
|
||||
int cost = me.getValue();
|
||||
@@ -148,10 +148,10 @@ public class VendorBuyMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
//test room available for item
|
||||
|
||||
if (!itemMan.hasRoomInventory(vendorItem.template.item_wt))
|
||||
if (!itemMan.hasRoomInventory(vendorItem.template.getItemWt()))
|
||||
return true;
|
||||
|
||||
int cost = vendorItem.template.item_value;
|
||||
int cost = vendorItem.template.getItemValue();
|
||||
|
||||
if (vendorItem.flags.contains(mbEnums.ItemFlags.Identified) || vendorItem.isCustomValue())
|
||||
cost = vendorItem.magicValue;
|
||||
|
||||
@@ -94,7 +94,7 @@ public class VendorSellMsgHandler extends AbstractClientMsgHandler {
|
||||
return true;
|
||||
|
||||
if (npc.getParentZone() != null && npc.getParentZone().playerCityUUID != 0)
|
||||
if (!npc.charItemManager.hasRoomInventory(sell.template.item_wt)) {
|
||||
if (!npc.charItemManager.hasRoomInventory(sell.template.getItemWt())) {
|
||||
ErrorPopupMsg.sendErrorPopup(player, 21);
|
||||
return true;
|
||||
}
|
||||
@@ -104,7 +104,7 @@ public class VendorSellMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
//get goldItem cost to sell
|
||||
|
||||
cost = (int) (sell.template.item_value * (sell.combat_health_current / sell.template.combat_health_full));
|
||||
cost = (int) (sell.template.getItemValue() * (sell.combat_health_current / sell.template.getCombatHealthFull()));
|
||||
|
||||
float bargain = player.getBargain();
|
||||
float profit = npc.getBuyPercent(player) + bargain;
|
||||
|
||||
@@ -22,10 +22,17 @@ import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class ApplyRuneMsg extends ClientNetMsg {
|
||||
|
||||
// Client ArcCharacter_AddRune (0x4695D0)
|
||||
private static final int MAX_TALENTS = 8;
|
||||
|
||||
private int targetType;
|
||||
private int targetID;
|
||||
private int removeRuneBase;
|
||||
@@ -78,67 +85,28 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
||||
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();
|
||||
ConcurrentHashMap<Integer, Boolean> disciplines = rb.getDiscipline();
|
||||
if (disciplines.size() > 0) {
|
||||
for (CharacterRune cr : runes) {
|
||||
int runeBaseID = cr.getRuneBaseID();
|
||||
for (Integer prohID : disciplines.keySet()) {
|
||||
if (runeBaseID == prohID) {
|
||||
return false; //Prohibited rune
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HashSet<Integer> classIDs = new HashSet<>();
|
||||
HashSet<Integer> heldDiscIDs = new HashSet<>();
|
||||
|
||||
// Client ArcCharacter_MeetsItemReqs (0x475F40)
|
||||
if (!meetsListReq(rb.getRace().keySet(), rb.isRaceRestrict(), Collections.singleton(playerCharacter.getRaceID())))
|
||||
return false;
|
||||
|
||||
// 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;
|
||||
for (CharacterRune cr : runes) {
|
||||
@@ -158,6 +126,32 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
||||
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 dexTotal = 0;
|
||||
int conTotal = 0;
|
||||
@@ -227,11 +221,6 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
||||
}
|
||||
}
|
||||
|
||||
//Check if max number runes already reached
|
||||
if (runes.size() > 12) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//if discipline, check number applied
|
||||
if (isDiscipline(runeID)) {
|
||||
if (playerCharacter.getLevel() < 70) {
|
||||
@@ -259,13 +248,10 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
||||
return false;
|
||||
}
|
||||
|
||||
//remove any overridden runes from player
|
||||
ArrayList<Integer> overwrite = rb.getOverwrite();
|
||||
//remove the replaced talent from player
|
||||
CharacterRune toRemove = null;
|
||||
if (overwrite.size() > 0) {
|
||||
for (int overwriteID : overwrite) {
|
||||
toRemove = playerCharacter.removeRune(overwriteID);
|
||||
}
|
||||
if (replacedRune != null) {
|
||||
toRemove = playerCharacter.removeRune(replacedRune.getRuneBaseID());
|
||||
}
|
||||
|
||||
//add rune to player
|
||||
@@ -331,6 +317,21 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -19,6 +19,7 @@ import engine.net.ByteBufferReader;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.net.Protocol;
|
||||
import engine.objects.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Period;
|
||||
import org.joda.time.Seconds;
|
||||
@@ -420,17 +421,18 @@ public class ManageNPCMsg extends ClientNetMsg {
|
||||
writer.putInt(rollableSet.size());
|
||||
|
||||
for (int templateID : rollableSet) {
|
||||
ItemTemplate template = ItemTemplate.templates.get(templateID);
|
||||
CObjectTemplate template = CObjectTemplate.lookup(templateID);
|
||||
int modTable = ForgeManager.getVendorModTable(templateID);
|
||||
writer.put((byte) 1);
|
||||
writer.putInt(0);
|
||||
writer.putInt(templateID); //itemID
|
||||
writer.putInt(template.item_value);
|
||||
writer.putInt(template.getItemValue());
|
||||
writer.putInt(600);
|
||||
writer.put((byte) 1);
|
||||
writer.put((byte) template.modTable);
|
||||
writer.put((byte) template.modTable);
|
||||
writer.put((byte) template.modTable);
|
||||
writer.put((byte) template.modTable);//EffectItemType
|
||||
writer.put((byte) modTable);
|
||||
writer.put((byte) modTable);
|
||||
writer.put((byte) modTable);
|
||||
writer.put((byte) modTable);//EffectItemType
|
||||
}
|
||||
|
||||
ArrayList<Item> cooking = NPCManager.getAllCookingForVendor(npc);
|
||||
@@ -444,7 +446,7 @@ public class ManageNPCMsg extends ClientNetMsg {
|
||||
|
||||
writer.putInt(0);
|
||||
writer.putInt(item.templateID);
|
||||
writer.putInt(item.template.item_value);
|
||||
writer.putInt(item.template.getItemValue());
|
||||
|
||||
long timeLife = item.getDateToUpgrade() - System.currentTimeMillis();
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public class UpdateInventoryMsg extends ClientNetMsg {
|
||||
|
||||
|
||||
for (Item item : list) {
|
||||
if (item.template.item_type.equals(ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(ItemType.GOLD)) {
|
||||
if (item.getNumOfItems() == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import engine.net.ByteBufferWriter;
|
||||
import engine.net.Protocol;
|
||||
import engine.objects.Item;
|
||||
import engine.objects.PlayerCharacter;
|
||||
import engine.parsers.objects.DeedTemplate;
|
||||
|
||||
|
||||
public class UseCharterMsg extends ClientNetMsg {
|
||||
@@ -61,9 +62,13 @@ public class UseCharterMsg extends ClientNetMsg {
|
||||
|
||||
public void configure() {
|
||||
|
||||
DeedTemplate charterDeed;
|
||||
|
||||
if (close) {
|
||||
for (Item i : player.getInventory()) {
|
||||
if (i.template.item_type.equals(ItemType.CHARTER)) {
|
||||
charterDeed = DeedTemplate._deeds.get(i.templateID);
|
||||
|
||||
if (charterDeed != null && charterDeed.item_type.equals(ItemType.CHARTER)) {
|
||||
charterUUID = i.getObjectUUID();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ public class VendorBuyWindowMsg extends ClientNetMsg {
|
||||
for (Item item : inventory) {
|
||||
if (item.getOwnerID() != ownerID)
|
||||
continue;
|
||||
if (item.template.item_type.equals(ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(ItemType.GOLD)) {
|
||||
if (item.getNumOfItems() == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.ApplyRuneMsg;
|
||||
import engine.net.client.msg.UpdateStateMsg;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.PowersBase;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
@@ -652,11 +654,11 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
AssignDefenseValue(abstractCharacter);
|
||||
// calculate atr and damage for each hand
|
||||
ConcurrentHashMap<EquipSlotType, Item> equipped = abstractCharacter.charItemManager.getEquipped();
|
||||
AssignDamageAtrForPlayers(abstractCharacter, equipped.get(EquipSlotType.RHELD), true, equipped.get(EquipSlotType.RHELD));
|
||||
AssignDamageAtrForPlayers(abstractCharacter, equipped.get(EquipSlotType.LHELD), false, equipped.get(EquipSlotType.LHELD));
|
||||
AssignDamageAtrForPlayers(abstractCharacter, equipped.get(EquipSlotType.RHELD), true, equipped.get(EquipSlotType.LHELD));
|
||||
AssignDamageAtrForPlayers(abstractCharacter, equipped.get(EquipSlotType.LHELD), false, equipped.get(EquipSlotType.RHELD));
|
||||
if (abstractCharacter.getObjectType().equals(GameObjectType.Mob)) {
|
||||
Mob mob = (Mob) abstractCharacter;
|
||||
ItemTemplate rune = ItemTemplate.templates.get(mob.loadID);
|
||||
RuneTemplate rune = RuneTemplate._runes.get(mob.loadID);
|
||||
float minDamage = mob.mobBase.getDamageMin();
|
||||
float maxDamage = mob.mobBase.getDamageMax();
|
||||
int attackRating = mob.mobBase.getAttackRating();
|
||||
@@ -691,16 +693,17 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
|
||||
// make sure weapon exists
|
||||
boolean noWeapon = false;
|
||||
ItemTemplate weaponTemplate = null;
|
||||
CObjectTemplate weaponTemplate = null;
|
||||
engine.parsers.objects.ItemTemplate.Damage damage;
|
||||
|
||||
if (weapon == null)
|
||||
noWeapon = true;
|
||||
else {
|
||||
ItemTemplate itemTemplate = weapon.template;
|
||||
CObjectTemplate itemTemplate = weapon.template;
|
||||
|
||||
if (itemTemplate == null)
|
||||
noWeapon = true;
|
||||
else if (!weapon.template.item_type.equals(ItemType.WEAPON)) {
|
||||
else if (!weapon.template.getItemType().equals(ItemType.WEAPON)) {
|
||||
defaultAtrAndDamage(abstractCharacter, mainHand);
|
||||
return;
|
||||
} else
|
||||
@@ -717,7 +720,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
if (noWeapon) {
|
||||
if (mainHand) {
|
||||
Item off = abstractCharacter.charItemManager.getEquipped().get(EquipSlotType.LHELD);
|
||||
if (off != null && off.template != null && off.template.item_type.equals(ItemType.WEAPON))
|
||||
if (off != null && off.template != null && off.template.getItemType().equals(ItemType.WEAPON))
|
||||
abstractCharacter.rangeHandOne = 10 * (1 + (abstractCharacter.statStrBase / 600)); // Set
|
||||
// to
|
||||
// no
|
||||
@@ -750,9 +753,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
|
||||
} else {
|
||||
if (mainHand)
|
||||
abstractCharacter.rangeHandOne = weapon.template.item_weapon_max_range * (1 + (abstractCharacter.statStrBase / 600));
|
||||
abstractCharacter.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range * (1 + (abstractCharacter.statStrBase / 600));
|
||||
else
|
||||
abstractCharacter.rangeHandTwo = weapon.template.item_weapon_max_range * (1 + (abstractCharacter.statStrBase / 600));
|
||||
abstractCharacter.rangeHandTwo = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range * (1 + (abstractCharacter.statStrBase / 600));
|
||||
|
||||
if (abstractCharacter.bonuses != null) {
|
||||
float range_bonus = 1 + abstractCharacter.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.None);
|
||||
@@ -764,20 +767,20 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
|
||||
}
|
||||
|
||||
skillPercentage = getModifiedAmount(abstractCharacter.skills.get(weapon.template.item_skill_used));
|
||||
masteryPercentage = getModifiedAmount(abstractCharacter.skills.get(weaponTemplate.item_skill_mastery_used));
|
||||
skillPercentage = getModifiedAmount(abstractCharacter.skills.get(weapon.template.getItemSkillUsed()));
|
||||
masteryPercentage = getModifiedAmount(abstractCharacter.skills.get(weaponTemplate.getItemSkillMasteryUsed()));
|
||||
|
||||
if (masteryPercentage == 0f)
|
||||
mastDam = 0f;
|
||||
// mastDam = CharacterSkill.getQuickMastery(this, wb.getMastery());
|
||||
else
|
||||
mastDam = masteryPercentage;
|
||||
int[] damages = (int[]) weaponTemplate.item_weapon_damage.values().toArray()[0];
|
||||
damage = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0);
|
||||
|
||||
min = damages[0];
|
||||
max = damages[1];
|
||||
min = damage.damage_min;
|
||||
max = damage.damage_max;
|
||||
|
||||
strBased = weaponTemplate.item_primary_attr.equals(AttributeType.Strength);
|
||||
strBased = engine.parsers.objects.ItemTemplate._items.get(weapon.templateID).item_primary_attr == AttributeType.Strength;
|
||||
}
|
||||
|
||||
if (abstractCharacter.effects != null && abstractCharacter.effects.containsKey("DeathShroud"))
|
||||
@@ -826,7 +829,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
|
||||
//calculate speed
|
||||
if (weaponTemplate != null)
|
||||
speed = weaponTemplate.item_weapon_wepspeed;
|
||||
speed = engine.parsers.objects.ItemTemplate.getWeapon(weaponTemplate.getTemplateId()).weapon_wepspeed;
|
||||
else
|
||||
speed = 20f; //unarmed attack speed
|
||||
if (weapon != null)
|
||||
@@ -881,15 +884,12 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
max *= percentMaxDamage;
|
||||
}
|
||||
|
||||
//if duel wielding, cut damage by 30%
|
||||
// Client (0x466EB0 sets char+0xD0C, 0x46D200 applies it): 30% cut only when both hands hold a WEAPON.
|
||||
|
||||
if (otherHand != null) {
|
||||
ItemTemplate ibo = otherHand.template;
|
||||
|
||||
if (ibo != null && otherHand.template.equals(ItemType.WEAPON)) {
|
||||
min *= 0.7f;
|
||||
max *= 0.7f;
|
||||
}
|
||||
if (!noWeapon && otherHand != null && otherHand.template != null
|
||||
&& otherHand.template.getItemType().equals(ItemType.WEAPON)) {
|
||||
min *= 0.7f;
|
||||
max *= 0.7f;
|
||||
}
|
||||
|
||||
// calculate damage
|
||||
@@ -955,7 +955,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
if (ItemManager.isShield(shield) == false)
|
||||
return 0;
|
||||
|
||||
ItemTemplate template = shield.template;
|
||||
CObjectTemplate template = shield.template;
|
||||
|
||||
if (template == null)
|
||||
return 0;
|
||||
@@ -969,7 +969,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
} else
|
||||
skillMod = blockSkill.getModifiedAmount();
|
||||
|
||||
float def = template.item_defense_rating;
|
||||
float def = engine.parsers.objects.ItemTemplate._items.get(shield.templateID).item_defense_rating;
|
||||
|
||||
//apply item defense bonuses
|
||||
|
||||
@@ -991,29 +991,30 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
if (armor == null)
|
||||
return 0;
|
||||
|
||||
ItemTemplate template = armor.template;
|
||||
CObjectTemplate template = armor.template;
|
||||
|
||||
if (template == null)
|
||||
return 0;
|
||||
|
||||
if (!armor.template.item_type.equals(ItemType.ARMOR))
|
||||
if (!armor.template.getItemType().equals(ItemType.ARMOR))
|
||||
return 0;
|
||||
|
||||
if (armor.template.item_skill_used.isEmpty())
|
||||
return template.item_defense_rating;
|
||||
// "Cloth" is a placeholder in Skills.cfg (token 0) that no character learns
|
||||
if (armor.template.getItemSkillUsed().isEmpty() || armor.template.getItemSkillUsed().equals("Cloth"))
|
||||
return engine.parsers.objects.ItemTemplate._items.get(armor.templateID).item_defense_rating;
|
||||
|
||||
CharacterSkill armorSkill = abstractCharacter.skills.get(armor.template.item_skill_used);
|
||||
CharacterSkill armorSkill = abstractCharacter.skills.get(armor.template.getItemSkillUsed());
|
||||
|
||||
if (abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter) && armorSkill == null) {
|
||||
Logger.error("Player " + abstractCharacter.getObjectUUID()
|
||||
+ " has armor equipped without the nescessary skill to equip it");
|
||||
return template.item_defense_rating;
|
||||
return engine.parsers.objects.ItemTemplate._items.get(armor.templateID).item_defense_rating;
|
||||
}
|
||||
|
||||
if (armorSkill == null)
|
||||
return template.item_defense_rating; // Mobiles do not have armor skills @TODO
|
||||
return engine.parsers.objects.ItemTemplate._items.get(armor.templateID).item_defense_rating; // Mobiles do not have armor skills @TODO
|
||||
|
||||
float def = template.item_defense_rating;
|
||||
float def = engine.parsers.objects.ItemTemplate._items.get(armor.templateID).item_defense_rating;
|
||||
|
||||
//apply item defense bonuses
|
||||
|
||||
@@ -1031,7 +1032,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
private static float getWeaponDefense(AbstractCharacter abstractCharacter, ConcurrentHashMap<EquipSlotType, Item> equipped) {
|
||||
|
||||
Item weapon = equipped.get(EquipSlotType.RHELD);
|
||||
ItemTemplate weaponTemplate = null;
|
||||
CObjectTemplate weaponTemplate = null;
|
||||
CharacterSkill skill, mastery;
|
||||
float val = 0;
|
||||
boolean unarmed = false;
|
||||
@@ -1052,8 +1053,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
skill = abstractCharacter.skills.get("Unarmed Combat");
|
||||
mastery = abstractCharacter.skills.get("Unarmed Combat Mastery");
|
||||
} else {
|
||||
skill = abstractCharacter.skills.get(weapon.template.item_skill_used);
|
||||
mastery = abstractCharacter.skills.get(weaponTemplate.item_skill_mastery_used);
|
||||
skill = abstractCharacter.skills.get(weapon.template.getItemSkillUsed());
|
||||
mastery = abstractCharacter.skills.get(weaponTemplate.getItemSkillMasteryUsed());
|
||||
}
|
||||
|
||||
if (skill != null)
|
||||
@@ -1088,7 +1089,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
|
||||
for (Item item : equipped.values()) {
|
||||
|
||||
ItemTemplate ib = item.template;
|
||||
CObjectTemplate ib = item.template;
|
||||
|
||||
if (ib == null)
|
||||
continue;
|
||||
@@ -1256,8 +1257,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
}
|
||||
|
||||
public final Resists getResists() {
|
||||
if (this.resists == null)
|
||||
return Resists.getResists(0);
|
||||
return this.resists;
|
||||
}
|
||||
|
||||
@@ -1507,9 +1506,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
||||
}
|
||||
float range = 8;
|
||||
if ((this).charItemManager.equipped.get(EquipSlotType.RHELD) != null) {
|
||||
range = ((Mob) this).charItemManager.equipped.get(EquipSlotType.RHELD).template.item_weapon_max_range;
|
||||
range = engine.parsers.objects.ItemTemplate.getWeapon(((Mob) this).charItemManager.equipped.get(EquipSlotType.RHELD).templateID).weapon_max_range;
|
||||
} else if (((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD) != null) {
|
||||
range = ((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD).template.item_weapon_max_range;
|
||||
range = engine.parsers.objects.ItemTemplate.getWeapon(((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD).templateID).weapon_max_range;
|
||||
} else {
|
||||
|
||||
// Unarmed: use the rune natural attack range when it has one (e.g. Gasser 150), not clamped.
|
||||
|
||||
@@ -172,7 +172,7 @@ public class Account extends AbstractGameObject {
|
||||
this.vault = DbManager.ItemQueries.GET_ITEMS_FOR_ACCOUNT(this.getObjectUUID());
|
||||
|
||||
for (Item item : this.vault) {
|
||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) {
|
||||
this.vaultGold = item;
|
||||
}
|
||||
}
|
||||
@@ -216,7 +216,7 @@ public class Account extends AbstractGameObject {
|
||||
return;
|
||||
|
||||
if (item.containerType == mbEnums.ItemContainerType.INVENTORY && player.charItemManager.isVaultOpen()) {
|
||||
if (!player.charItemManager.hasRoomVault(item.template.item_wt)) {
|
||||
if (!player.charItemManager.hasRoomVault(item.template.getItemWt())) {
|
||||
ItemToVaultMsgHandler.forceTransferFromVaultToInventory(msg, origin, "There is no room in your vault.");
|
||||
return;
|
||||
}
|
||||
@@ -262,7 +262,7 @@ public class Account extends AbstractGameObject {
|
||||
return;
|
||||
|
||||
if (item.containerType == mbEnums.ItemContainerType.VAULT && itemManager.isVaultOpen()) {
|
||||
if (!itemManager.hasRoomInventory(item.template.item_wt)) {
|
||||
if (!itemManager.hasRoomInventory(item.template.getItemWt())) {
|
||||
ItemFromVaultMsgHandler.forceTransferFromInventoryToVault(msg, origin, "There is no room in your inventory.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
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;
|
||||
|
||||
|
||||
@@ -82,30 +84,41 @@ public class BaseClass extends AbstractGameObject {
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
* Rune Template Constructor
|
||||
*/
|
||||
public BaseClass(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
public BaseClass(RuneTemplate rune) {
|
||||
super(rune.template_id);
|
||||
|
||||
this.name = rs.getString("name");
|
||||
this.description = rs.getString("description");
|
||||
this.strMod = rs.getByte("strMod");
|
||||
this.dexMod = rs.getByte("dexMod");
|
||||
this.conMod = rs.getByte("conMod");
|
||||
this.intMod = rs.getByte("intMod");
|
||||
this.spiMod = rs.getByte("spiMod");
|
||||
this.token = rs.getInt("token");
|
||||
this.healthMod = rs.getInt("healthMod");
|
||||
this.manaMod = rs.getInt("manaMod");
|
||||
this.staminaMod = rs.getInt("staminaMod");
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.getObjectUUID());
|
||||
this.name = rune.obj_name;
|
||||
this.description = rune.rune_dsc;
|
||||
this.strMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Strength, 0).byteValue();
|
||||
this.dexMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Dexterity, 0).byteValue();
|
||||
this.conMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Constitution, 0).byteValue();
|
||||
this.intMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Intelligence, 0).byteValue();
|
||||
this.spiMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Spirit, 0).byteValue();
|
||||
this.token = Hasher.SBStringHash(rune.rune_sub_type);
|
||||
this.healthMod = rune.rune_health;
|
||||
this.manaMod = rune.rune_mana;
|
||||
this.staminaMod = rune.rune_stamina;
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
||||
this.effectsList = (DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID()));
|
||||
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(this.getObjectUUID());
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -187,10 +200,6 @@ public class BaseClass extends AbstractGameObject {
|
||||
return this.powersGranted;
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
||||
return RuneBaseEffect.RuneIDBaseEffectMap.get(this.getObjectUUID());
|
||||
}
|
||||
|
||||
/*
|
||||
* Utils
|
||||
*/
|
||||
@@ -199,10 +208,6 @@ public class BaseClass extends AbstractGameObject {
|
||||
if (this.getRuneList().contains(rb.getObjectUUID()))
|
||||
return true;
|
||||
|
||||
if (RuneBase.AllowedBaseClassRunesMap.containsKey(111111)) {
|
||||
if (RuneBase.AllowedBaseClassRunesMap.get(111111).contains(rb.getObjectUUID()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -433,6 +433,7 @@ public class Building extends AbstractWorldObject {
|
||||
// Special handling of warehouses
|
||||
|
||||
if (blueprint.getBuildingGroup() == BuildingGroup.WAREHOUSE) {
|
||||
Warehouse.destroyedWarehouses.put(this.getObjectUUID(), city.warehouse);
|
||||
DbManager.WarehouseQueries.DELETE_WAREHOUSE(city.warehouse);
|
||||
city.warehouse = null;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import engine.mbEnums.ItemType;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.*;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -130,19 +131,19 @@ public class CharacterItemManager {
|
||||
this.equipped.put(i.equipSlot, i);
|
||||
break;
|
||||
case BANK:
|
||||
if (i.template.item_type.equals(ItemType.GOLD))
|
||||
if (i.template.getItemType().equals(ItemType.GOLD))
|
||||
this.goldBank = i;
|
||||
else if (this.bank.contains(i) == false)
|
||||
this.bank.add(i);
|
||||
break;
|
||||
case INVENTORY:
|
||||
if (i.template.item_type.equals(ItemType.GOLD))
|
||||
if (i.template.getItemType().equals(ItemType.GOLD))
|
||||
this.goldInventory = i;
|
||||
else if (this.inventory.contains(i) == false)
|
||||
this.inventory.add(i);
|
||||
break;
|
||||
case VAULT:
|
||||
if (i.template.item_type.equals(ItemType.GOLD))
|
||||
if (i.template.getItemType().equals(ItemType.GOLD))
|
||||
this.goldVault = i;
|
||||
else if (this.vault.contains(i) == false)
|
||||
this.vault.add(i);
|
||||
@@ -175,13 +176,13 @@ public class CharacterItemManager {
|
||||
this.equipped.put(i.equipSlot, i);
|
||||
break;
|
||||
case BANK:
|
||||
if (i.template.item_type.equals(ItemType.GOLD))
|
||||
if (i.template.getItemType().equals(ItemType.GOLD))
|
||||
this.goldBank = i;
|
||||
else if (this.bank.contains(i) == false)
|
||||
this.bank.add(i);
|
||||
break;
|
||||
case INVENTORY:
|
||||
if (i.template.item_type.equals(ItemType.GOLD))
|
||||
if (i.template.getItemType().equals(ItemType.GOLD))
|
||||
this.goldInventory = i;
|
||||
else if (this.inventory.contains(i) == false)
|
||||
this.inventory.add(i);
|
||||
@@ -511,7 +512,7 @@ public class CharacterItemManager {
|
||||
if (i == null)
|
||||
return false;
|
||||
|
||||
if (i.template.item_type.equals(ItemType.GOLD)) {
|
||||
if (i.template.getItemType().equals(ItemType.GOLD)) {
|
||||
if (this.getGoldInventory() != null) {
|
||||
if (i.getObjectUUID() == this.getGoldInventory().getObjectUUID())
|
||||
this.goldInventory = null;
|
||||
@@ -541,7 +542,7 @@ public class CharacterItemManager {
|
||||
}
|
||||
|
||||
private synchronized boolean junk(Item i, boolean updateInventory) {
|
||||
if (i.template.item_type.equals(ItemType.GOLD)) {
|
||||
if (i.template.getItemType().equals(ItemType.GOLD)) {
|
||||
if (this.getGoldInventory().getObjectUUID() == i.getObjectUUID())
|
||||
if (DbManager.ItemQueries.UPDATE_GOLD(i, 0)) {
|
||||
this.getGoldInventory().setNumOfItems(0);
|
||||
@@ -596,7 +597,7 @@ public class CharacterItemManager {
|
||||
|
||||
if (equippedContains(item)) {
|
||||
fromEquip = true;
|
||||
if (item.template.item_type.equals(ItemType.GOLD))
|
||||
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||
this.absCharacter.cancelOnUnEquip();
|
||||
}
|
||||
|
||||
@@ -814,7 +815,7 @@ public class CharacterItemManager {
|
||||
|
||||
// This removes ingame item from inventory for loot.
|
||||
private synchronized boolean removeItemFromInventory(Item i) {
|
||||
if (i.template.item_type.equals(ItemType.GOLD)) {
|
||||
if (i.template.getItemType().equals(ItemType.GOLD)) {
|
||||
if (i.getObjectUUID() != this.getGoldInventory().getObjectUUID())
|
||||
return false;
|
||||
if (!DbManager.ItemQueries.UPDATE_GOLD(this.goldInventory, 0)) {
|
||||
@@ -837,7 +838,7 @@ public class CharacterItemManager {
|
||||
|
||||
// This adds item to inventory for loot. Validity checks already handled
|
||||
public synchronized boolean addItemToInventory(Item i) {
|
||||
if (i.template.item_type.equals(ItemType.GOLD))
|
||||
if (i.template.getItemType().equals(ItemType.GOLD))
|
||||
if (this.absCharacter.getObjectType() == GameObjectType.Mob) {
|
||||
if (this.goldInventory == null)
|
||||
loadGoldItems();
|
||||
@@ -856,7 +857,7 @@ public class CharacterItemManager {
|
||||
this.itemIDtoType.put(i.getObjectUUID(), i.getObjectType().ordinal());
|
||||
|
||||
if (i.template != null)
|
||||
this.inventoryWeight += i.template.item_wt;
|
||||
this.inventoryWeight += i.template.getItemWt();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1041,7 +1042,7 @@ public class CharacterItemManager {
|
||||
if (npc.getContractID() >= 1900 && npc.getContractID() <= 1906)
|
||||
eatItem = true;
|
||||
|
||||
if (itemToSell.template.item_type.equals(ItemType.POTION))
|
||||
if (itemToSell.template.getItemType().equals(ItemType.POTION))
|
||||
eatItem = true;
|
||||
|
||||
if (eatItem) {
|
||||
@@ -1085,14 +1086,14 @@ public class CharacterItemManager {
|
||||
|
||||
synchronized (this) {
|
||||
synchronized (itemMan) {
|
||||
ItemTemplate template = purchasedItem.template;
|
||||
CObjectTemplate template = purchasedItem.template;
|
||||
|
||||
if (template == null)
|
||||
return false;
|
||||
|
||||
//test inventory is not full
|
||||
|
||||
if (!hasRoomInventory(template.item_wt))
|
||||
if (!hasRoomInventory(template.getItemWt()))
|
||||
return false;
|
||||
|
||||
if (!itemMan.inventory.contains(purchasedItem))
|
||||
@@ -1105,8 +1106,8 @@ public class CharacterItemManager {
|
||||
|
||||
// Reset value
|
||||
|
||||
purchasedItem.value = (int) (purchasedItem.template.item_value * (purchasedItem.combat_health_current / purchasedItem.template.combat_health_full));
|
||||
purchasedItem.magicValue = purchasedItem.template.item_value + purchasedItem.calcMagicValue();
|
||||
purchasedItem.value = (int) (purchasedItem.template.getItemValue() * (purchasedItem.combat_health_current / purchasedItem.template.getCombatHealthFull()));
|
||||
purchasedItem.magicValue = purchasedItem.template.getItemValue() + purchasedItem.calcMagicValue();
|
||||
|
||||
// db transfer successfully, remove from this character
|
||||
// skip this check if this is a mobLoot item (which is not in any inventory)
|
||||
@@ -1184,9 +1185,9 @@ public class CharacterItemManager {
|
||||
synchronized (lockFirst) {
|
||||
synchronized (lockSecond) {
|
||||
// make sure current player has item in inventory
|
||||
if (lootItem.template.item_type.equals(ItemType.GOLD) && lootItem.getObjectUUID() != this.getGoldInventory().getObjectUUID() && !(this.absCharacter.getObjectType().equals(GameObjectType.Mob)))
|
||||
if (lootItem.template.getItemType().equals(ItemType.GOLD) && lootItem.getObjectUUID() != this.getGoldInventory().getObjectUUID() && !(this.absCharacter.getObjectType().equals(GameObjectType.Mob)))
|
||||
return null;
|
||||
else if (!this.inventory.contains(lootItem) && !this.equipped.containsValue(lootItem) && !lootItem.template.item_type.equals(ItemType.GOLD))
|
||||
else if (!this.inventory.contains(lootItem) && !this.equipped.containsValue(lootItem) && !lootItem.template.getItemType().equals(ItemType.GOLD))
|
||||
return null;
|
||||
|
||||
// get weight of item
|
||||
@@ -1194,13 +1195,13 @@ public class CharacterItemManager {
|
||||
if (lootItem.template == null)
|
||||
return null;
|
||||
|
||||
int weight = lootItem.template.item_wt;
|
||||
int weight = lootItem.template.getItemWt();
|
||||
|
||||
// make sure lootingPlayer has room for item
|
||||
if (!lootItem.template.item_type.equals(ItemType.GOLD) && !looterItems.hasRoomInventory(weight))
|
||||
if (!lootItem.template.getItemType().equals(ItemType.GOLD) && !looterItems.hasRoomInventory(weight))
|
||||
return null;
|
||||
|
||||
if (lootItem.template.item_type.equals(ItemType.GOLD))
|
||||
if (lootItem.template.getItemType().equals(ItemType.GOLD))
|
||||
if (amount != -1) { //from steal
|
||||
int total = lootItem.getNumOfItems();
|
||||
amount = (amount > total) ? total : amount;
|
||||
@@ -1263,19 +1264,19 @@ public class CharacterItemManager {
|
||||
* Delegates
|
||||
*/
|
||||
public synchronized boolean bankContains(Item item) {
|
||||
if (item.template.item_type.equals(ItemType.GOLD))
|
||||
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||
return (this.getGoldBank() != null && this.goldBank.getObjectUUID() == item.getObjectUUID());
|
||||
return bank.contains(item);
|
||||
}
|
||||
|
||||
public synchronized boolean inventoryContains(Item item) {
|
||||
if (item.template.item_type.equals(ItemType.GOLD))
|
||||
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||
return (this.getGoldInventory() != null && this.goldInventory.getObjectUUID() == item.getObjectUUID());
|
||||
return inventory.contains(item);
|
||||
}
|
||||
|
||||
public synchronized boolean vaultContains(Item item) {
|
||||
if (item.template.item_type.equals(ItemType.GOLD))
|
||||
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||
return (this.getGoldVault() != null && this.goldVault.getObjectUUID() == item.getObjectUUID());
|
||||
return this.account.getVault().contains(item);
|
||||
}
|
||||
@@ -1518,13 +1519,13 @@ public class CharacterItemManager {
|
||||
item.zeroItem();
|
||||
item.containerType = mbEnums.ItemContainerType.INVENTORY;
|
||||
|
||||
if (item.template.item_type.equals(ItemType.GOLD))
|
||||
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||
//only add gold item once
|
||||
if (!corpse.hasGold())
|
||||
corpse.setHasGold(true);
|
||||
newInventory.add(item);
|
||||
} else //item
|
||||
if (item.template.item_type.equals(ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(ItemType.GOLD)) {
|
||||
int amt = item.getNumOfItems();
|
||||
item.setNumOfItems(0);
|
||||
MobLoot ml = new MobLoot(this.absCharacter, amt);
|
||||
@@ -1676,7 +1677,7 @@ public class CharacterItemManager {
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
weight += item.template.item_wt;
|
||||
weight += item.template.getItemWt();
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
@@ -1696,7 +1697,7 @@ public class CharacterItemManager {
|
||||
this.bankWeight = 0;
|
||||
for (Item item : this.bank) {
|
||||
if (item.template != null)
|
||||
this.bankWeight += item.template.item_wt;
|
||||
this.bankWeight += item.template.getItemWt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1707,7 +1708,7 @@ public class CharacterItemManager {
|
||||
while (it.hasNext()) {
|
||||
Item item = it.next();
|
||||
if (item.template != null)
|
||||
this.equipWeight += item.template.item_wt;
|
||||
this.equipWeight += item.template.getItemWt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1715,7 +1716,7 @@ public class CharacterItemManager {
|
||||
this.inventoryWeight = 0;
|
||||
for (Item item : this.inventory) {
|
||||
if (item.template != null)
|
||||
this.inventoryWeight += item.template.item_wt;
|
||||
this.inventoryWeight += item.template.getItemWt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1723,7 +1724,7 @@ public class CharacterItemManager {
|
||||
this.vaultWeight = 0;
|
||||
for (Item item : this.vault) {
|
||||
if (item.template != null)
|
||||
this.vaultWeight += item.template.item_wt;
|
||||
this.vaultWeight += item.template.getItemWt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1755,7 +1756,7 @@ public class CharacterItemManager {
|
||||
return;
|
||||
|
||||
if (!item.moveItemToInventory(player))
|
||||
Logger.error("templateL " + item.template.template_id);
|
||||
Logger.error("templateL " + item.template.getTemplateId());
|
||||
|
||||
// remove it from other lists:
|
||||
this.remItemFromLists(item);
|
||||
@@ -1932,7 +1933,7 @@ public class CharacterItemManager {
|
||||
return;
|
||||
|
||||
//don't damage noob gear, hair or beards.
|
||||
if (item.template.combat_health_full == 0)
|
||||
if (item.template.getCombatHealthFull() == 0)
|
||||
return;
|
||||
|
||||
if (!item.isCanDestroy())
|
||||
|
||||
@@ -334,7 +334,7 @@ public class CharacterPower extends AbstractGameObject {
|
||||
// return pc.getBonuses().getByte("gt." + this.power.getToken());
|
||||
// } else
|
||||
// return pc.getBonuses().getByte("gt." + this.power.getToken());
|
||||
return PowerGrant.getGrantedTrains(this.power.getToken(), pc);
|
||||
return PowerGrantedTrains.getGrantedTrains(this.power.getToken(), pc);
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ public class CharacterRune extends AbstractGameObject {
|
||||
private final int player;
|
||||
private final ArrayList<SkillReq> skillsGranted;
|
||||
private final ArrayList<PowerReq> powersGranted;
|
||||
private final ArrayList<RuneBaseEffect> effectsGranted;
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
@@ -37,16 +36,12 @@ public class CharacterRune extends AbstractGameObject {
|
||||
this.runeBase = runeBase;
|
||||
this.player = characterID;
|
||||
if (this.runeBase != null) {
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
||||
} else {
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.powersGranted = new ArrayList<>();
|
||||
}
|
||||
if (this.runeBase != null)
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
||||
else
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,16 +52,12 @@ public class CharacterRune extends AbstractGameObject {
|
||||
this.runeBase = runeBase;
|
||||
this.player = characterID;
|
||||
if (this.runeBase != null) {
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
||||
} else {
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.powersGranted = new ArrayList<>();
|
||||
}
|
||||
if (this.runeBase != null)
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
||||
else
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,14 +69,12 @@ public class CharacterRune extends AbstractGameObject {
|
||||
this.runeBase = RuneBase.getRuneBase(rs.getInt("RuneBaseID"));
|
||||
this.player = rs.getInt("CharacterID");
|
||||
if (this.runeBase != null) {
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
||||
} else {
|
||||
Logger.error("Failed to find RuneBase for CharacterRune " + this.getObjectUUID());
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.powersGranted = new ArrayList<>();
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,10 +189,6 @@ public class CharacterRune extends AbstractGameObject {
|
||||
return this.powersGranted;
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
||||
return this.effectsGranted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
DbManager.CharacterRuneQueries.updateDatabase(this);
|
||||
|
||||
@@ -1043,15 +1043,15 @@ public class CharacterSkill extends AbstractGameObject {
|
||||
|
||||
|
||||
if (this.skillsBase.getStrMod() > 0)
|
||||
statMod += (float) this.skillsBase.getStrMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseStr() / 100f;
|
||||
statMod += (float) this.skillsBase.getStrMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Strength) / 100f;
|
||||
if (this.skillsBase.getDexMod() > 0)
|
||||
statMod += (float) this.skillsBase.getDexMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseDex() / 100f;
|
||||
statMod += (float) this.skillsBase.getDexMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Dexterity) / 100f;
|
||||
if (this.skillsBase.getConMod() > 0)
|
||||
statMod += (float) this.skillsBase.getConMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseCon() / 100f;
|
||||
statMod += (float) this.skillsBase.getConMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Constitution) / 100f;
|
||||
if (this.skillsBase.getIntMod() > 0)
|
||||
statMod += (float) this.skillsBase.getIntMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseInt() / 100f;
|
||||
statMod += (float) this.skillsBase.getIntMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Intelligence) / 100f;
|
||||
if (this.skillsBase.getSpiMod() > 0)
|
||||
statMod += (float) this.skillsBase.getSpiMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseSpi() / 100f;
|
||||
statMod += (float) this.skillsBase.getSpiMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Spirit) / 100f;
|
||||
if (statMod < 1)
|
||||
statMod = 1f;
|
||||
else if (statMod > 600)
|
||||
@@ -1136,9 +1136,12 @@ public class CharacterSkill extends AbstractGameObject {
|
||||
Logger.error("SkillsBase not found for skill " + this.getObjectUUID());
|
||||
this.modifiedAmount = this.baseAmount;
|
||||
}
|
||||
return calculateAmountAfterTrains(this.numTrains.get());
|
||||
}
|
||||
|
||||
public float calculateAmountAfterTrains(int trains) {
|
||||
int amount;
|
||||
|
||||
int trains = this.numTrains.get();
|
||||
if (trains < 10)
|
||||
amount = (trains * 2);
|
||||
else if (trains < 90)
|
||||
|
||||
@@ -296,14 +296,14 @@ public class Corpse extends AbstractWorldObject {
|
||||
|
||||
//get weight of item
|
||||
|
||||
int weight = item.template.item_wt;
|
||||
int weight = item.template.getItemWt();
|
||||
|
||||
//make sure looter has room for item
|
||||
if (item.template.item_type.equals(ItemType.GOLD) == false && !looterItems.hasRoomInventory(weight))
|
||||
if (item.template.getItemType().equals(ItemType.GOLD) == false && !looterItems.hasRoomInventory(weight))
|
||||
return null;
|
||||
|
||||
//attempt to transfer item in db
|
||||
if (item.template.item_type.equals(ItemType.GOLD)) {
|
||||
if (item.template.getItemType().equals(ItemType.GOLD)) {
|
||||
if (!looterItems.moveGoldToInventory(item, item.getNumOfItems()))
|
||||
return null;
|
||||
} else if (!item.moveItemToInventory(looter))
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -12,114 +12,17 @@ package engine.objects;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.mbEnums.TargetColor;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import static engine.gameManager.LootManager.LOOTMANAGER;
|
||||
|
||||
public class Experience {
|
||||
|
||||
private static final TreeMap<Integer, Integer> ExpToLevel;
|
||||
private static final int[] LevelToExp = {Integer.MIN_VALUE, // Pad
|
||||
// everything
|
||||
// over 1
|
||||
|
||||
// R0
|
||||
0, // Level 1
|
||||
150, // Level 2
|
||||
1200, // Level 3
|
||||
4050, // Level 4
|
||||
9600, // Level 5
|
||||
18750, // Level 6
|
||||
32400, // Level 7
|
||||
51450, // Level 8
|
||||
76800, // Level 9
|
||||
|
||||
// R1
|
||||
109350, // Level 10
|
||||
150000, // Level 11
|
||||
199650, // Level 12
|
||||
259200, // Level 13
|
||||
329550, // Level 14
|
||||
411600, // Level 15
|
||||
506250, // Level 16
|
||||
614400, // Level 17
|
||||
736950, // Level 18
|
||||
874800, // Level 19
|
||||
|
||||
// R2
|
||||
1028850, // Level 20
|
||||
1200000, // Level 21
|
||||
1389150, // Level 22
|
||||
1597200, // Level 23
|
||||
1825050, // Level 24
|
||||
2073600, // Level 25
|
||||
2343750, // Level 26
|
||||
2636400, // Level 27
|
||||
2952450, // Level 28
|
||||
3292800, // Level 29
|
||||
|
||||
// R3
|
||||
3658350, // Level 30
|
||||
4050000, // Level 31
|
||||
4468650, // Level 32
|
||||
4915200, // Level 33
|
||||
5390550, // Level 34
|
||||
5895600, // Level 35
|
||||
6431250, // Level 36
|
||||
6998400, // Level 37
|
||||
7597950, // Level 38
|
||||
8230800, // Level 39
|
||||
|
||||
// R4
|
||||
8897850, // Level 40
|
||||
10091520, // Level 41
|
||||
11396777, // Level 42
|
||||
12820187, // Level 43
|
||||
14368505, // Level 44
|
||||
16048666, // Level 45
|
||||
17867790, // Level 46
|
||||
19833183, // Level 47
|
||||
21952335, // Level 48
|
||||
24232919, // Level 49
|
||||
|
||||
// R5
|
||||
26682793, // Level 50
|
||||
29310000, // Level 51
|
||||
32122766, // Level 52
|
||||
35129502, // Level 53
|
||||
38338805, // Level 54
|
||||
41759452, // Level 55
|
||||
45400409, // Level 56
|
||||
49270824, // Level 57
|
||||
53380030, // Level 58
|
||||
57737542, // Level 59
|
||||
|
||||
// R6
|
||||
62353064, // Level 60
|
||||
67236479, // Level 61
|
||||
72397859, // Level 62
|
||||
77847457, // Level 63
|
||||
83595712, // Level 64
|
||||
89653247, // Level 65
|
||||
96030869, // Level 66
|
||||
102739569, // Level 67
|
||||
109790524, // Level 68
|
||||
117195093, // Level 69
|
||||
|
||||
// R7
|
||||
124964822, // Level 70
|
||||
133111438, // Level 71
|
||||
141646855, // Level 72
|
||||
150583171, // Level 73
|
||||
159932666, // Level 74
|
||||
169707808, // Level 75
|
||||
179921247, // Level 76
|
||||
|
||||
};
|
||||
|
||||
// Client ArcCharacter_ExpForLevelUp (0x4715D0) float constant at 0x154195C
|
||||
private static final float EXP_LEVEL_SLOPE = 0.0512f;
|
||||
private static final float[] MaxExpPerLevel = {Float.MIN_VALUE, // Pad
|
||||
// everything
|
||||
// over
|
||||
@@ -227,39 +130,56 @@ public class Experience {
|
||||
// (expGranted / group.size()) * (groupBonus * (group.size()-1) +1)
|
||||
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
|
||||
|
||||
// called to determine current level based on xp
|
||||
public static int getLevel(int experience) {
|
||||
public static int getLevel(PlayerCharacter player, int experience) {
|
||||
|
||||
int expKey = ExpToLevel.floorKey(experience);
|
||||
int level = ExpToLevel.get(expKey);
|
||||
int level = 1;
|
||||
|
||||
if (level > MBServerStatics.LEVELCAP)
|
||||
level = MBServerStatics.LEVELCAP;
|
||||
while (level < MBServerStatics.LEVELCAP && experience >= getBaseExperience(player, level + 1))
|
||||
level++;
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
// Get the base xp for a level
|
||||
public static int getBaseExperience(int level) {
|
||||
// The client function returns the XP to reach level + 1, so it is called with level - 1.
|
||||
// Arithmetic order and the half-up rounding follow the client so every threshold matches.
|
||||
public static int getBaseExperience(PlayerCharacter player, int level) {
|
||||
|
||||
if (level < LevelToExp.length)
|
||||
return LevelToExp[level];
|
||||
int clientLevel = level - 1;
|
||||
double levelScale;
|
||||
|
||||
int fLevel = level - 1;
|
||||
int baseXP = fLevel * fLevel * fLevel;
|
||||
levelScale = Math.max(1.0, (clientLevel - 39) * (double) EXP_LEVEL_SLOPE + 1.0);
|
||||
|
||||
return (int) ((fLevel < 40) ? (baseXP * 150)
|
||||
: (baseXP * (150 + (7.6799998 * (level - 40)))));
|
||||
return (int) (long) ((double) clientLevel * clientLevel * clientLevel * levelScale
|
||||
* getClassExpFactor(player) * getRaceExpFactor(player) + 0.5);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
@@ -20,6 +20,8 @@ import engine.net.ByteBufferWriter;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.DeleteItemMsg;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.parsers.objects.UserPowerAction;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||
import engine.powers.poweractions.AbstractPowerAction;
|
||||
@@ -31,6 +33,7 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@@ -55,7 +58,7 @@ public class Item extends AbstractWorldObject {
|
||||
public int templateID;
|
||||
private long dateToUpgrade;
|
||||
public int magicValue;
|
||||
public ItemTemplate template;
|
||||
public CObjectTemplate template;
|
||||
public String name = "";
|
||||
public int prefixToken; // Forge support
|
||||
public int suffixToken; // Forge support
|
||||
@@ -68,14 +71,14 @@ public class Item extends AbstractWorldObject {
|
||||
public Item(int templateID) {
|
||||
super();
|
||||
this.templateID = templateID;
|
||||
this.template = ItemTemplate.templates.get(templateID);
|
||||
this.chargesRemaining = this.template.item_initial_charges;
|
||||
this.combat_health_current = this.template.combat_health_full;
|
||||
this.template = CObjectTemplate.lookup(templateID);
|
||||
this.chargesRemaining = this.template.getItemInitialCharges();
|
||||
this.combat_health_current = this.template.getCombatHealthFull();
|
||||
this.equipSlot = EquipSlotType.NONE;
|
||||
this.containerType = ItemContainerType.NONE;
|
||||
this.numberOfItems = 1;
|
||||
this.flags.addAll(this.template.item_flags);
|
||||
this.value = this.template.item_value;
|
||||
this.flags.addAll(this.template.getItemFlags());
|
||||
this.value = this.template.getItemValue();
|
||||
this.magicValue = this.value + calcMagicValue();
|
||||
loadTemplateEnchantments();
|
||||
}
|
||||
@@ -87,7 +90,7 @@ public class Item extends AbstractWorldObject {
|
||||
super(rs);
|
||||
|
||||
this.templateID = rs.getInt("templateID");
|
||||
this.template = ItemTemplate.templates.get(this.templateID);
|
||||
this.template = CObjectTemplate.lookup(this.templateID);
|
||||
|
||||
if (this.template == null)
|
||||
Logger.error("Null template of " + this.templateID);
|
||||
@@ -166,7 +169,7 @@ public class Item extends AbstractWorldObject {
|
||||
this.value = rs.getInt("value");
|
||||
|
||||
if (this.value == 0) {
|
||||
this.value = this.template.item_value;
|
||||
this.value = this.template.getItemValue();
|
||||
this.magicValue = this.value + calcMagicValue();
|
||||
} else
|
||||
this.magicValue = this.value; // Value was overridden in vendor inventory
|
||||
@@ -238,7 +241,7 @@ public class Item extends AbstractWorldObject {
|
||||
writer.putString(item.name); // Unknown. pad?
|
||||
writer.put((byte) 1); // End Datablock byte
|
||||
|
||||
writer.putFloat(item.template.combat_health_full);
|
||||
writer.putFloat(item.template.getCombatHealthFull());
|
||||
writer.putFloat((float) item.combat_health_current);
|
||||
|
||||
writer.put((byte) 1); // End Datablock byte
|
||||
@@ -255,7 +258,7 @@ public class Item extends AbstractWorldObject {
|
||||
} else
|
||||
writer.putInt(item.numberOfItems); // Amount of gold
|
||||
} else
|
||||
writer.putInt(item.template.item_value);
|
||||
writer.putInt(item.template.getItemValue());
|
||||
|
||||
writer.putInt(item.getValue());
|
||||
|
||||
@@ -288,7 +291,7 @@ public class Item extends AbstractWorldObject {
|
||||
writer.putInt(36); //Magical, blue name
|
||||
else
|
||||
writer.putInt(40); //Magical, unidentified
|
||||
else if (item.template.item_user_power_action.size() > 0)
|
||||
else if (item.template.getItemUserPowerAction().isEmpty() == false)
|
||||
writer.putInt(36); //Magical, blue name
|
||||
else
|
||||
writer.putInt(4); //Non-Magical, grey name
|
||||
@@ -298,7 +301,7 @@ public class Item extends AbstractWorldObject {
|
||||
writer.put((byte) 0);
|
||||
|
||||
|
||||
if (item.template.item_type.equals(ItemType.EMPLOYMENTCONTRACT) == false) {
|
||||
if (item.template.getItemType().equals(ItemType.EMPLOYMENTCONTRACT) == false) {
|
||||
writer.putShort((short) 0);
|
||||
return;
|
||||
}
|
||||
@@ -463,7 +466,7 @@ public class Item extends AbstractWorldObject {
|
||||
int serialized = 0;
|
||||
for (Item item : list) {
|
||||
|
||||
if (item.template.item_type.equals(ItemType.GOLD))
|
||||
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||
if (item.numberOfItems == 0)
|
||||
continue;
|
||||
try {
|
||||
@@ -497,7 +500,7 @@ public class Item extends AbstractWorldObject {
|
||||
int serialized = 0;
|
||||
for (Item item : list) {
|
||||
|
||||
if (item.template.item_type.equals(ItemType.GOLD))
|
||||
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||
if (item.numberOfItems == 0)
|
||||
continue;
|
||||
try {
|
||||
@@ -931,12 +934,16 @@ public class Item extends AbstractWorldObject {
|
||||
private void loadTemplateEnchantments() {
|
||||
|
||||
EffectsBase effect;
|
||||
LinkedHashMap<String, int[]> templateEnchantments = new LinkedHashMap<>();
|
||||
|
||||
if (ConfigManager.serverType.equals(mbEnums.ServerType.LOGINSERVER))
|
||||
return;
|
||||
|
||||
// Duplicate powers collapse to the last entry; applying one twice would double its magic value.
|
||||
for (UserPowerAction userPowerAction : this.template.getItemUserPowerAction())
|
||||
templateEnchantments.put(userPowerAction.power, userPowerAction.arguments);
|
||||
|
||||
for (String effectID : this.template.item_user_power_action.keySet()) {
|
||||
for (String effectID : templateEnchantments.keySet()) {
|
||||
|
||||
effect = PowersManager.getEffectByIDString(effectID);
|
||||
|
||||
@@ -946,7 +953,7 @@ public class Item extends AbstractWorldObject {
|
||||
}
|
||||
|
||||
AbstractPowerAction apa = PowersManager.getPowerActionByIDString(effect.getIDString());
|
||||
apa.applyBakedInStatsForItem(this, this.template.item_user_power_action.get(effectID)[0]);
|
||||
apa.applyBakedInStatsForItem(this, templateEnchantments.get(effectID)[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -955,7 +962,7 @@ public class Item extends AbstractWorldObject {
|
||||
// No enchantments for negative id items in the db. Early exit.
|
||||
|
||||
if (this.objectUUID < 0) {
|
||||
this.magicValue = this.template.item_value + calcMagicValue();
|
||||
this.magicValue = this.template.getItemValue() + calcMagicValue();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -971,8 +978,8 @@ public class Item extends AbstractWorldObject {
|
||||
|
||||
// Value is overridden the db
|
||||
|
||||
if (this.value == this.template.item_value)
|
||||
this.magicValue = this.template.item_value + calcMagicValue();
|
||||
if (this.value == this.template.getItemValue())
|
||||
this.magicValue = this.template.getItemValue() + calcMagicValue();
|
||||
}
|
||||
|
||||
public void addPermanentEnchantment(String enchantID, int rank) {
|
||||
@@ -1116,11 +1123,11 @@ public class Item extends AbstractWorldObject {
|
||||
else
|
||||
modifiedValue = this.value;
|
||||
|
||||
if (this.template.item_initial_charges > 0)
|
||||
modifiedValue = modifiedValue * (this.chargesRemaining / this.template.item_initial_charges);
|
||||
if (this.template.getItemInitialCharges() > 0)
|
||||
modifiedValue = modifiedValue * (this.chargesRemaining / this.template.getItemInitialCharges());
|
||||
|
||||
if (this.template.combat_health_full > 0)
|
||||
modifiedValue = (int) (modifiedValue * (this.combat_health_current / this.template.combat_health_full));
|
||||
if (this.template.getCombatHealthFull() > 0)
|
||||
modifiedValue = (int) (modifiedValue * (this.combat_health_current / this.template.getCombatHealthFull()));
|
||||
|
||||
return modifiedValue;
|
||||
}
|
||||
|
||||
@@ -1,643 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.mbEnums;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ItemTemplate {
|
||||
|
||||
// MB Dev Notes:
|
||||
// This class parses JSON data generated by mbEditor Pro 2.1.
|
||||
// Cache definitions are loaded for ItemType.ITEM, ItemType,DEED
|
||||
// and ItemType.RUNE.
|
||||
//
|
||||
// Exported JSON data is stored in db table static_item_templates
|
||||
// and can be easily mass updated using tooling available on the Wiki.
|
||||
//
|
||||
// Always read never write!
|
||||
// Use copies of fields to avoid side effects.
|
||||
|
||||
// Global template lookup
|
||||
|
||||
public static HashMap<Integer, ItemTemplate> templates = new HashMap<>();
|
||||
public int template_id;
|
||||
|
||||
// Template Properties
|
||||
|
||||
public String obj_name;
|
||||
public boolean obj_pickable;
|
||||
public Vector3fImmutable obj_scale;
|
||||
public Vector3fImmutable obj_forward_vector;
|
||||
public Vector3fImmutable obj_default_alignment;
|
||||
public int obj_render_object;
|
||||
public int obj_icon;
|
||||
public final HashMap<String, String> obj_sparse_data = new HashMap<>();
|
||||
public float combat_health_current;
|
||||
public float combat_health_full;
|
||||
public final HashMap<String, Float> combat_attack_resist = new HashMap<>();
|
||||
public mbEnums.ItemType item_type;
|
||||
public int item_eq_slots_value;
|
||||
public boolean item_eq_slots_type;
|
||||
public final EnumSet<mbEnums.EquipSlotType> item_eq_slots_or = EnumSet.noneOf(mbEnums.EquipSlotType.class);
|
||||
public final EnumSet<mbEnums.EquipSlotType> item_eq_slots_and = EnumSet.noneOf(mbEnums.EquipSlotType.class);
|
||||
public boolean item_takeable;
|
||||
public int item_value;
|
||||
public int item_wt;
|
||||
public float item_passive_defense_mod;
|
||||
public String item_base_name;
|
||||
public String item_dsc;
|
||||
public int item_render_object_female;
|
||||
public float item_health_full;
|
||||
public String item_skill_used = "";
|
||||
public String item_skill_mastery_used = "";
|
||||
public int item_parry_anim_id;
|
||||
public float item_bulk_factor;
|
||||
public final HashMap<mbEnums.ShrineType, Integer> item_offering_info = new HashMap<>();
|
||||
public int item_defense_rating;
|
||||
public float item_weapon_wepspeed;
|
||||
public float item_weapon_max_range;
|
||||
public int item_weapon_projectile_id;
|
||||
public float item_weapon_projectile_speed;
|
||||
public int item_weapon_combat_idle_anim;
|
||||
public final HashMap<mbEnums.DamageType, int[]> item_weapon_damage = new HashMap<>();
|
||||
public final ArrayList<int[]> weapon_attack_anim_right = new ArrayList<>();
|
||||
public final ArrayList<int[]> weapon_attack_anim_left = new ArrayList<>();
|
||||
public mbEnums.AttributeType item_primary_attr = mbEnums.AttributeType.None;
|
||||
public mbEnums.AttributeType item_secondary_attr = mbEnums.AttributeType.None;
|
||||
public final EnumSet<mbEnums.ItemFlags> item_flags = EnumSet.noneOf(mbEnums.ItemFlags.class);
|
||||
public final EnumSet<mbEnums.ItemUseFlags> item_use_flags = EnumSet.noneOf(mbEnums.ItemUseFlags.class);
|
||||
public int item_initial_charges;
|
||||
public final HashMap<String, Integer> item_skill_required = new HashMap<>();
|
||||
public final EnumSet<mbEnums.MonsterType> item_race_req = EnumSet.noneOf(mbEnums.MonsterType.class);
|
||||
public final EnumSet<mbEnums.MonsterType> item_race_res = EnumSet.noneOf(mbEnums.MonsterType.class);
|
||||
public final EnumSet<mbEnums.ClassType> item_class_req = EnumSet.noneOf(mbEnums.ClassType.class);
|
||||
public final EnumSet<mbEnums.ClassType> item_class_res = EnumSet.noneOf(mbEnums.ClassType.class);
|
||||
public final EnumSet<mbEnums.DisciplineType> item_disc_req = EnumSet.noneOf(mbEnums.DisciplineType.class);
|
||||
public final EnumSet<mbEnums.DisciplineType> item_disc_res = EnumSet.noneOf(mbEnums.DisciplineType.class);
|
||||
public int item_level_req;
|
||||
public mbEnums.SexType item_sex_req;
|
||||
public final HashMap<String, int[]> item_user_power_action = new HashMap<>();
|
||||
public final HashMap<String, Integer> item_power_grant = new HashMap<>();
|
||||
public final HashMap<String, int[]> item_power_action = new HashMap<>();
|
||||
public final HashMap<mbEnums.ResourceType, Integer> item_resource_cost = new HashMap<>();
|
||||
public int modTable;
|
||||
public int deed_type;
|
||||
public int deed_furniture_id;
|
||||
public int deed_target_id;
|
||||
public int deed_employment;
|
||||
public int deed_start_rank;
|
||||
public int deed_name_lookup;
|
||||
public boolean deed_indoors;
|
||||
public boolean deed_is_fortress;
|
||||
public float deed_namelookup_val;
|
||||
public boolean deed_custom_city;
|
||||
public int deed_structure_id;
|
||||
public final HashMap<mbEnums.AttributeType, Integer> rune_attr_adj = new HashMap<>();
|
||||
public final HashMap<mbEnums.AttributeType, Integer> rune_max_attr_adj = new HashMap<>();
|
||||
public final HashMap<String, Integer> rune_skill_grant = new HashMap<>();
|
||||
public final HashMap<String, Integer> skill_granted_skills = new HashMap<>();
|
||||
public final HashMap<String, Integer> power_granted_skills = new HashMap<>();
|
||||
public String rune_type;
|
||||
public String rune_sub_type;
|
||||
public boolean rune_is_standard_character_creation = false;
|
||||
public int rune_creation_cost;
|
||||
public int rune_rank;
|
||||
public int rune_pracs_per_level;
|
||||
public float rune_exp_req_to_level;
|
||||
public mbEnums.SexType rune_sex;
|
||||
public int rune_class_icon;
|
||||
public int rune_health;
|
||||
public int rune_mana;
|
||||
public int rune_stamina;
|
||||
public float rune_min_damage;
|
||||
public float rune_max_damage;
|
||||
public int rune_attack;
|
||||
public int rune_defense;
|
||||
public int rune_level;
|
||||
public final HashMap<mbEnums.MovementType, Float> rune_speed = new HashMap<>();
|
||||
public int rune_group_type;
|
||||
public boolean rune_group_is_faction = false;
|
||||
public boolean rune_group_is_guild = false;
|
||||
public String rune_dsc;
|
||||
public String rune_fx_txt;
|
||||
public final EnumSet<mbEnums.MobBehaviourType> rune_group_tactics = EnumSet.noneOf(mbEnums.MobBehaviourType.class);
|
||||
public final EnumSet<mbEnums.MobBehaviourType> rune_group_role_set = EnumSet.noneOf(mbEnums.MobBehaviourType.class);
|
||||
public boolean rune_renderable = false;
|
||||
public int rune_natural_power_attack;
|
||||
// One float[] per rune_naturalattacks entry. Same "attack info" struct as a weapon (verified in IDA, see
|
||||
// MBDATA/docs/client-map.md): [0] attack speed (WEPSPEED), [1] range (MAXRANGE), [2] unknown int,
|
||||
// [3] equip slot (1 = RHELD, 2 = LHELD), [4] projectile template id, [5] projectile speed, [6] swing anim,
|
||||
// [7] damage type, [8] min damage, [9] max damage
|
||||
public final ArrayList<float[]> rune_natural_attacks = new ArrayList<>();
|
||||
public final HashMap<String, String> rune_sparse_data = new HashMap<>();
|
||||
public final HashMap<String, int[]> rune_skill_adj = new HashMap<>();
|
||||
public final EnumSet<mbEnums.MonsterType> rune_enemy_monster_types = EnumSet.noneOf(mbEnums.MonsterType.class);
|
||||
public final EnumSet<mbEnums.MonsterType> rune_not_enemy_monster_types = EnumSet.noneOf(mbEnums.MonsterType.class);
|
||||
public final ArrayList<Integer> rune_groupee_monster_types = new ArrayList<>();
|
||||
public final ArrayList<Integer> rune_helper_monster_types = new ArrayList<>();
|
||||
public int item_bane_rank;
|
||||
|
||||
public ItemTemplate(JSONObject jsonObject) {
|
||||
|
||||
try {
|
||||
// Reading a String
|
||||
|
||||
obj_name = jsonObject.getString("obj_name");
|
||||
|
||||
// Reading a boolean
|
||||
|
||||
obj_pickable = jsonObject.getBoolean("obj_pickable");
|
||||
|
||||
// Reading floats from an array (note always check for empty arrays)
|
||||
|
||||
JSONArray scaleData = jsonObject.getJSONArray("obj_scale");
|
||||
|
||||
if (scaleData.isEmpty() == false)
|
||||
obj_scale = new Vector3fImmutable(scaleData.getFloat(0), scaleData.getFloat(1),
|
||||
scaleData.getFloat(2));
|
||||
|
||||
JSONArray forwardVector = jsonObject.getJSONArray("obj_forward_vector");
|
||||
|
||||
if (forwardVector.isEmpty() == false)
|
||||
obj_forward_vector = new Vector3fImmutable(forwardVector.getFloat(0), forwardVector.getFloat(1),
|
||||
forwardVector.getFloat(2));
|
||||
|
||||
JSONArray defaultAlignment = jsonObject.getJSONArray("obj_default_alignment");
|
||||
|
||||
if (defaultAlignment.isEmpty() == false)
|
||||
obj_default_alignment = new Vector3fImmutable(defaultAlignment.getFloat(0), defaultAlignment.getFloat(1),
|
||||
defaultAlignment.getFloat(2));
|
||||
|
||||
// Reading an integer value
|
||||
|
||||
obj_render_object = jsonObject.getInt("obj_render_object");
|
||||
obj_icon = jsonObject.getInt("obj_icon");
|
||||
|
||||
JSONObject obj_sparse_json = jsonObject.getJSONObject("obj_sparse_data");
|
||||
|
||||
for (String sparseType : obj_sparse_json.keySet()) {
|
||||
Object sparseValue = obj_sparse_json.get(sparseType);
|
||||
obj_sparse_data.put(sparseType, sparseValue.toString());
|
||||
}
|
||||
|
||||
// Banes are defined by their sparse data field
|
||||
|
||||
if (obj_sparse_data.get("ACTIONRESPONSE") != null)
|
||||
if (obj_sparse_data.get("ACTIONRESPONSE").equals("4250517122"))
|
||||
item_bane_rank = jsonObject.getInt("item_bane_rank");
|
||||
|
||||
// Reading float values
|
||||
|
||||
combat_health_current = jsonObject.getFloat("combat_health_current");
|
||||
combat_health_full = jsonObject.getFloat("combat_health_full");
|
||||
|
||||
// Reading a hashmap of floats
|
||||
|
||||
JSONObject resist_json = jsonObject.getJSONObject("combat_attack_resist");
|
||||
|
||||
for (String resistType : resist_json.keySet()) {
|
||||
float resistValue = resist_json.getFloat(resistType);
|
||||
combat_attack_resist.put(resistType, resistValue);
|
||||
}
|
||||
|
||||
// Parsing an enum
|
||||
|
||||
item_type = mbEnums.ItemType.valueOf(jsonObject.getString("item_type"));
|
||||
item_eq_slots_value = jsonObject.getInt("item_eq_slots_value");
|
||||
item_eq_slots_type = jsonObject.getBoolean("item_eq_slots_type");
|
||||
|
||||
// Parsing an enumset
|
||||
|
||||
JSONArray eq_slots_or = jsonObject.getJSONArray("item_eq_slots_or");
|
||||
|
||||
if (eq_slots_or.isEmpty() == false)
|
||||
for (Object o : eq_slots_or)
|
||||
item_eq_slots_or.add(mbEnums.EquipSlotType.valueOf((String) o));
|
||||
|
||||
JSONArray eq_slots_and = jsonObject.getJSONArray("item_eq_slots_and");
|
||||
|
||||
if (eq_slots_and.isEmpty() == false)
|
||||
for (Object o : eq_slots_and)
|
||||
item_eq_slots_and.add(mbEnums.EquipSlotType.valueOf((String) o));
|
||||
|
||||
item_takeable = jsonObject.getBoolean("item_takeable");
|
||||
item_value = (jsonObject.getInt("item_value"));
|
||||
item_wt = jsonObject.getInt("item_wt");
|
||||
item_passive_defense_mod = jsonObject.getFloat("item_passive_defense_mod");
|
||||
item_base_name = jsonObject.getString("item_base_name");
|
||||
item_dsc = jsonObject.getString("item_dsc");
|
||||
item_render_object_female = jsonObject.getInt("item_render_object_female");
|
||||
item_health_full = jsonObject.getFloat("item_health_full");
|
||||
|
||||
Object skill_used = jsonObject.get("item_skill_used");
|
||||
|
||||
if (skill_used instanceof String) {
|
||||
if (skill_used.equals("Cloth") == false)
|
||||
item_skill_used = (String) skill_used;
|
||||
}
|
||||
|
||||
Object mastery_used = jsonObject.get("item_skill_mastery_used");
|
||||
|
||||
if (mastery_used instanceof String)
|
||||
item_skill_mastery_used = (String) mastery_used;
|
||||
|
||||
item_parry_anim_id = jsonObject.getInt("item_parry_anim_id");
|
||||
|
||||
// Reading offering data
|
||||
|
||||
JSONArray offering_data = jsonObject.getJSONArray("item_offering_info");
|
||||
|
||||
for (Object entry : offering_data) {
|
||||
JSONObject offering_entry = (JSONObject) entry;
|
||||
String offering_type = offering_entry.getString("offering_type").replaceAll("-", "");
|
||||
int offering_value = offering_entry.getInt("offering_value");
|
||||
item_offering_info.put(mbEnums.ShrineType.valueOf(offering_type), offering_value);
|
||||
}
|
||||
|
||||
// Fields only present for ARMOR
|
||||
|
||||
if (item_type.equals(mbEnums.ItemType.ARMOR)) {
|
||||
item_bulk_factor = jsonObject.getFloat("item_bulk_factor");
|
||||
item_defense_rating = jsonObject.getInt("item_defense_rating");
|
||||
}
|
||||
|
||||
// Fields only present for WEAPON
|
||||
|
||||
if (item_type.equals(mbEnums.ItemType.WEAPON)) {
|
||||
|
||||
JSONObject item_weapon = jsonObject.getJSONObject("item_weapon");
|
||||
item_weapon_wepspeed = item_weapon.getFloat("weapon_wepspeed");
|
||||
item_weapon_max_range = item_weapon.getFloat("weapon_max_range");
|
||||
item_weapon_projectile_id = item_weapon.getInt("weapon_projectile_id");
|
||||
item_weapon_projectile_speed = item_weapon.getFloat("weapon_projectile_speed");
|
||||
item_weapon_combat_idle_anim = item_weapon.getInt("weapon_combat_idle_anim");
|
||||
|
||||
JSONArray weapon_damage = item_weapon.getJSONArray("weapon_damage");
|
||||
|
||||
if (weapon_damage.isEmpty() == false)
|
||||
for (Object o : weapon_damage) {
|
||||
JSONObject damage_entry = (JSONObject) o;
|
||||
mbEnums.DamageType damageType = mbEnums.DamageType.getDamageType(damage_entry.getString("damage_type"));
|
||||
int min = damage_entry.getInt("damage_min");
|
||||
int max = damage_entry.getInt("damage_max");
|
||||
int[] minMax = {min, max};
|
||||
item_weapon_damage.put(damageType, minMax);
|
||||
}
|
||||
|
||||
JSONArray attack_anim_right = item_weapon.getJSONArray("weapon_attack_anim_right");
|
||||
|
||||
if (attack_anim_right.isEmpty() == false)
|
||||
for (Object o : attack_anim_right) {
|
||||
JSONArray animationEntry = (JSONArray) o;
|
||||
int animation = animationEntry.getInt(0);
|
||||
int duration = animationEntry.getInt(1);
|
||||
weapon_attack_anim_right.add(new int[]{animation, duration});
|
||||
}
|
||||
|
||||
JSONArray attack_anim_left = item_weapon.getJSONArray("weapon_attack_anim_left");
|
||||
|
||||
if (attack_anim_left.isEmpty() == false)
|
||||
for (Object o : attack_anim_left) {
|
||||
JSONArray animationEntry = (JSONArray) o;
|
||||
int animation = animationEntry.getInt(0);
|
||||
int duration = animationEntry.getInt(1);
|
||||
weapon_attack_anim_left.add(new int[]{animation, duration});
|
||||
}
|
||||
|
||||
item_primary_attr = mbEnums.AttributeType.valueOf(jsonObject.getString("item_primary_attr"));
|
||||
item_secondary_attr = mbEnums.AttributeType.valueOf(jsonObject.getString("item_secondary_attr"));
|
||||
}
|
||||
|
||||
JSONArray itemflags = jsonObject.getJSONArray("item_flags");
|
||||
|
||||
if (itemflags.isEmpty() == false)
|
||||
for (Object o : itemflags) {
|
||||
String flag = (String) o;
|
||||
if (flag.equals("None") == false)
|
||||
item_flags.add(mbEnums.ItemFlags.valueOf((String) o));
|
||||
}
|
||||
|
||||
JSONArray itemUseflags = jsonObject.getJSONArray("item_use_flags");
|
||||
|
||||
if (itemUseflags.isEmpty() == false)
|
||||
for (Object o : itemUseflags)
|
||||
item_use_flags.add(mbEnums.ItemUseFlags.valueOf((String) o));
|
||||
|
||||
item_initial_charges = jsonObject.getInt("item_initial_charges");
|
||||
|
||||
JSONArray skill_required = jsonObject.getJSONArray("item_skill_req");
|
||||
|
||||
if (skill_required.isEmpty() == false)
|
||||
for (Object o : skill_required) {
|
||||
JSONObject skill_req = (JSONObject) o;
|
||||
String skill_type = skill_req.getString("skill_type");
|
||||
int skill_level = skill_req.getInt("skill_level");
|
||||
|
||||
if (skill_type.equals("Cloth") == false)
|
||||
item_skill_required.put(skill_type, skill_level);
|
||||
}
|
||||
|
||||
JSONObject race_required = jsonObject.getJSONObject("item_race_req");
|
||||
boolean restrict = race_required.getBoolean("restrict");
|
||||
JSONArray races = race_required.getJSONArray("races");
|
||||
|
||||
if (races.isEmpty() == false)
|
||||
for (Object o : races) {
|
||||
String race = (String) o;
|
||||
race = race.replaceAll("\\s", "");
|
||||
race = race.replaceAll(",", "");
|
||||
race = race.replaceAll("-", "");
|
||||
|
||||
if (restrict)
|
||||
item_race_res.add(mbEnums.MonsterType.valueOf(race));
|
||||
else
|
||||
item_race_req.add(mbEnums.MonsterType.valueOf(race));
|
||||
}
|
||||
|
||||
JSONObject class_required = jsonObject.getJSONObject("item_class_req");
|
||||
restrict = class_required.getBoolean("restrict");
|
||||
JSONArray classes = class_required.getJSONArray("classes");
|
||||
|
||||
if (classes.isEmpty() == false)
|
||||
for (Object o : classes) {
|
||||
String classEntry = (String) o;
|
||||
classEntry = classEntry.replaceAll("\\s", "");
|
||||
classEntry = classEntry.replaceAll(",", "");
|
||||
|
||||
if (restrict)
|
||||
item_class_res.add(mbEnums.ClassType.valueOf(classEntry));
|
||||
else
|
||||
item_class_req.add(mbEnums.ClassType.valueOf(classEntry));
|
||||
}
|
||||
|
||||
JSONObject disc_required = jsonObject.getJSONObject("item_disc_req");
|
||||
restrict = disc_required.getBoolean("restrict");
|
||||
JSONArray discs = disc_required.getJSONArray("discs");
|
||||
|
||||
if (discs.isEmpty() == false)
|
||||
for (Object o : discs) {
|
||||
String disc = (String) o;
|
||||
disc = disc.replaceAll("\\s", "");
|
||||
disc = disc.replaceAll(",", "");
|
||||
|
||||
if (restrict)
|
||||
item_disc_res.add(mbEnums.DisciplineType.valueOf(disc));
|
||||
else
|
||||
item_disc_req.add(mbEnums.DisciplineType.valueOf(disc));
|
||||
}
|
||||
|
||||
item_level_req = jsonObject.getInt("item_level_req");
|
||||
item_sex_req = mbEnums.SexType.valueOf(jsonObject.getString("item_sex_req"));
|
||||
|
||||
JSONArray userPowerActions = jsonObject.getJSONArray("item_user_power_action");
|
||||
|
||||
if (userPowerActions.isEmpty() == false)
|
||||
for (Object o : userPowerActions) {
|
||||
JSONObject powerActionEntry = (JSONObject) o;
|
||||
String power = powerActionEntry.getString("power");
|
||||
JSONArray args = powerActionEntry.getJSONArray("arguments");
|
||||
int[] arguments = {args.getInt(0), args.getInt(1)};
|
||||
item_user_power_action.put(power, arguments);
|
||||
}
|
||||
|
||||
JSONArray powerGrantsArray = jsonObject.getJSONArray("item_power_grant");
|
||||
|
||||
if (powerGrantsArray.isEmpty() == false) {
|
||||
|
||||
for (Object grantArrayEntry : powerGrantsArray) {
|
||||
JSONObject powerGrantEntry = (JSONObject) grantArrayEntry;
|
||||
String power_type = powerGrantEntry.getString("power_type");
|
||||
int power_value = powerGrantEntry.getInt("power_value");
|
||||
item_power_grant.put(power_type, power_value);
|
||||
|
||||
JSONArray skill_granted_array = powerGrantEntry.getJSONArray("power_granted_skills");
|
||||
|
||||
for (Object skillGrantEntry : skill_granted_array) {
|
||||
JSONArray skill_entry = (JSONArray) skillGrantEntry;
|
||||
String skill_type = skill_entry.getString(0);
|
||||
int skill_level = skill_entry.getInt(1);
|
||||
power_granted_skills.put(skill_type, skill_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray item_power_actions = jsonObject.getJSONArray("item_power_action");
|
||||
|
||||
if (item_power_actions.isEmpty() == false)
|
||||
for (Object o : item_power_actions) {
|
||||
JSONObject powerActionEntry = (JSONObject) o;
|
||||
String power = powerActionEntry.getString("power_type");
|
||||
JSONArray power_actions = powerActionEntry.getJSONArray("power_actions");
|
||||
JSONObject argument_entry = power_actions.getJSONObject(0);
|
||||
JSONArray power_args = argument_entry.getJSONArray("power_arguments");
|
||||
int[] power_arguments = {power_args.getInt(0), power_args.getInt(1)};
|
||||
item_power_action.put(power, power_arguments);
|
||||
}
|
||||
|
||||
JSONArray resource_costs = jsonObject.getJSONArray("item_resource_costs");
|
||||
|
||||
if (resource_costs.isEmpty() == false)
|
||||
for (Object o : resource_costs) {
|
||||
JSONObject resource_entry = (JSONObject) o;
|
||||
mbEnums.ResourceType resource_type = mbEnums.ResourceType.valueOf(resource_entry.getString("resource_type").toUpperCase());
|
||||
int resource_value = resource_entry.getInt("resource_value");
|
||||
item_resource_cost.put(resource_type, resource_value);
|
||||
}
|
||||
|
||||
// Deed related fields
|
||||
|
||||
if (item_type.equals(mbEnums.ItemType.DEED)) {
|
||||
|
||||
deed_type = jsonObject.getInt("deed_type");
|
||||
deed_furniture_id = jsonObject.getInt("deed_furniture_id");
|
||||
deed_target_id = jsonObject.getInt("deed_target_id");
|
||||
deed_employment = jsonObject.getInt("deed_employment");
|
||||
deed_start_rank = jsonObject.getInt("deed_start_rank");
|
||||
deed_name_lookup = jsonObject.getInt("deed_name_lookup");
|
||||
deed_indoors = jsonObject.getBoolean("deed_indoors");
|
||||
deed_is_fortress = jsonObject.getBoolean("deed_is_fortress");
|
||||
deed_namelookup_val = jsonObject.getFloat("deed_namelookup_val");
|
||||
deed_custom_city = jsonObject.getBoolean("deed_custom_city");
|
||||
deed_structure_id = jsonObject.getInt("deed_structure_id");
|
||||
}
|
||||
|
||||
if (item_type.equals(mbEnums.ItemType.RUNE)) {
|
||||
|
||||
rune_type = jsonObject.getString("rune_type");
|
||||
|
||||
Object subType = jsonObject.get("rune_sub_type");
|
||||
|
||||
if (subType instanceof String)
|
||||
rune_sub_type = (String) subType;
|
||||
|
||||
rune_is_standard_character_creation = jsonObject.getBoolean("rune_is_standard_character_creation");
|
||||
rune_creation_cost = jsonObject.getInt("rune_creation_cost");
|
||||
rune_rank = jsonObject.getInt("rune_rank");
|
||||
rune_pracs_per_level = jsonObject.getInt("rune_pracs_per_level");
|
||||
rune_exp_req_to_level = jsonObject.getFloat("rune_exp_req_to_level");
|
||||
rune_sex = mbEnums.SexType.valueOf(jsonObject.getString("rune_sex"));
|
||||
rune_class_icon = jsonObject.getInt("rune_class_icon");
|
||||
rune_health = jsonObject.getInt("rune_health");
|
||||
rune_mana = jsonObject.getInt("rune_mana");
|
||||
rune_stamina = jsonObject.getInt("rune_stamina");
|
||||
rune_min_damage = jsonObject.getFloat("rune_min_damage");
|
||||
rune_max_damage = jsonObject.getFloat("rune_max_damage");
|
||||
rune_attack = jsonObject.getInt("rune_attack");
|
||||
rune_defense = jsonObject.getInt("rune_defense");
|
||||
rune_level = jsonObject.getInt("rune_level");
|
||||
|
||||
JSONObject rune_speed_json = jsonObject.getJSONObject("rune_speed");
|
||||
|
||||
for (String key : rune_speed_json.keySet()) {
|
||||
mbEnums.MovementType movementType = mbEnums.MovementType.valueOf(key);
|
||||
float speed = rune_speed_json.getFloat(key);
|
||||
rune_speed.put(movementType, speed);
|
||||
}
|
||||
|
||||
JSONObject rune_group = jsonObject.getJSONObject("rune_group");
|
||||
|
||||
rune_group_type = rune_group.getInt("group_type");
|
||||
rune_group_is_faction = rune_group.getBoolean("group_is_faction");
|
||||
rune_group_is_guild = rune_group.getBoolean("group_is_guild");
|
||||
rune_dsc = jsonObject.getString("rune_dsc");
|
||||
rune_fx_txt = jsonObject.getString("rune_fx_txt");
|
||||
|
||||
long group_tactics_bitvector = jsonObject.getLong("rune_group_tactics");
|
||||
|
||||
rune_group_tactics.addAll(mbEnums.fromLong(group_tactics_bitvector, mbEnums.MobBehaviourType.class));
|
||||
|
||||
long group_role_bitvector = jsonObject.getLong("rune_group_role_set");
|
||||
|
||||
rune_group_role_set.addAll(mbEnums.fromLong(group_role_bitvector, mbEnums.MobBehaviourType.class));
|
||||
|
||||
JSONArray enemy_types_json = jsonObject.getJSONArray("rune_enemy_monster_types");
|
||||
|
||||
for (Object o : enemy_types_json) {
|
||||
String enemy = (String) o;
|
||||
enemy = enemy.replaceAll("-", "");
|
||||
mbEnums.MonsterType monsterType = mbEnums.MonsterType.valueOf(enemy);
|
||||
rune_enemy_monster_types.add(monsterType);
|
||||
}
|
||||
|
||||
JSONArray not_enemy_types_json = jsonObject.getJSONArray("rune_not_enemy_monster_types");
|
||||
|
||||
for (Object o : not_enemy_types_json) {
|
||||
String notenemy = (String) o;
|
||||
notenemy = notenemy.replaceAll("-", "");
|
||||
mbEnums.MonsterType monsterType = mbEnums.MonsterType.valueOf(notenemy);
|
||||
rune_not_enemy_monster_types.add(monsterType);
|
||||
}
|
||||
|
||||
JSONArray groupee_types_json = jsonObject.getJSONArray("rune_groupee_monster_types");
|
||||
|
||||
for (Object o : groupee_types_json) {
|
||||
int groupeeId = (int) o;
|
||||
rune_groupee_monster_types.add(groupeeId);
|
||||
}
|
||||
|
||||
JSONArray helper_types_json = jsonObject.getJSONArray("rune_helper_monster_types");
|
||||
|
||||
for (Object o : helper_types_json) {
|
||||
int helperId = (int) o;
|
||||
rune_helper_monster_types.add(helperId);
|
||||
}
|
||||
|
||||
rune_renderable = jsonObject.getBoolean("rune_renderable");
|
||||
rune_natural_power_attack = jsonObject.getInt("rune_natural_power_attack");
|
||||
|
||||
if (jsonObject.has("rune_naturalattacks")) {
|
||||
|
||||
JSONArray natural_attacks_json = jsonObject.getJSONArray("rune_naturalattacks");
|
||||
|
||||
for (Object attackEntry : natural_attacks_json) {
|
||||
JSONArray attackArray = (JSONArray) attackEntry;
|
||||
float[] attack = new float[attackArray.length()];
|
||||
|
||||
for (int i = 0; i < attackArray.length(); i++)
|
||||
attack[i] = attackArray.getFloat(i);
|
||||
|
||||
rune_natural_attacks.add(attack);
|
||||
}
|
||||
}
|
||||
|
||||
JSONObject rune_sparse_json = jsonObject.getJSONObject("rune_sparse_data");
|
||||
|
||||
for (String sparseType : rune_sparse_json.keySet()) {
|
||||
Object sparseValue = rune_sparse_json.get(sparseType);
|
||||
rune_sparse_data.put(sparseType, sparseValue.toString());
|
||||
}
|
||||
|
||||
JSONArray skill_adj_json = (JSONArray) jsonObject.get("rune_skill_adj");
|
||||
|
||||
for (Object skillEntry : skill_adj_json) {
|
||||
JSONObject skill = (JSONObject) skillEntry;
|
||||
String typeString = skill.getString("skill_type");
|
||||
JSONArray adjArray = skill.getJSONArray("skill_adjusts");
|
||||
|
||||
for (Object adjustList : adjArray) {
|
||||
JSONArray adjustEntry = (JSONArray) adjustList;
|
||||
int[] adjust = {adjustEntry.getInt(0), adjustEntry.getInt(1)};
|
||||
rune_skill_adj.put(typeString, adjust);
|
||||
}
|
||||
|
||||
}
|
||||
JSONArray attr_adj_json = jsonObject.getJSONArray("rune_attr_adj");
|
||||
|
||||
for (Object attributeEntry : attr_adj_json) {
|
||||
JSONObject attribute = (JSONObject) attributeEntry;
|
||||
String typeString = attribute.getString("attr_type");
|
||||
mbEnums.AttributeType attributeType = mbEnums.AttributeType.valueOf(typeString);
|
||||
int attributeValue = attribute.getInt("attr_value");
|
||||
rune_attr_adj.put(attributeType, attributeValue);
|
||||
}
|
||||
|
||||
JSONArray max_attr_adj_json = jsonObject.getJSONArray("rune_max_attr_adj");
|
||||
|
||||
for (Object attributeEntry : max_attr_adj_json) {
|
||||
JSONObject attribute = (JSONObject) attributeEntry;
|
||||
String typeString = attribute.getString("attr_type");
|
||||
mbEnums.AttributeType attributeType = mbEnums.AttributeType.valueOf(typeString);
|
||||
int attributeValue = attribute.getInt("attr_value");
|
||||
rune_max_attr_adj.put(attributeType, attributeValue);
|
||||
}
|
||||
|
||||
JSONArray skill_grant_json = jsonObject.getJSONArray("rune_skill_grant");
|
||||
|
||||
if (skill_grant_json.isEmpty() == false)
|
||||
for (Object runeSkillEntry : skill_grant_json) {
|
||||
JSONObject skill_granted = (JSONObject) runeSkillEntry;
|
||||
String typeString = skill_granted.getString("skill_type");
|
||||
int skill_level = skill_granted.getInt("skill_value");
|
||||
rune_skill_grant.put(typeString, skill_level);
|
||||
|
||||
JSONArray skill_granted_array = skill_granted.getJSONArray("skill_granted_skills");
|
||||
|
||||
for (Object skillGrantEntry : skill_granted_array) {
|
||||
JSONArray skill_entry = (JSONArray) skillGrantEntry;
|
||||
typeString = skill_entry.getString(0);
|
||||
skill_level = skill_entry.getInt(1);
|
||||
skill_granted_skills.put(typeString, skill_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error(obj_name + ":" + e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+77
-348
@@ -1,3 +1,4 @@
|
||||
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
@@ -11,94 +12,93 @@ package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.mbEnums.EquipSlotType;
|
||||
import engine.mbEnums.ItemContainerType;
|
||||
import engine.mbEnums.OwnerType;
|
||||
import engine.parsers.objects.ItemTemplate;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.parsers.objects.wpak.StartingKitTemplate;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class Kit extends AbstractGameObject {
|
||||
|
||||
public static HashMap<Integer, Boolean> NoobGearIDS = new HashMap<>();
|
||||
public static HashMap<Integer, ArrayList<Kit>> RaceClassIDMap = new HashMap<>();
|
||||
private final int raceBaseClassID;
|
||||
|
||||
// Keyed like the client's kit map (0x620250): race name, sex and class name, not rune ids
|
||||
private static final HashMap<String, ArrayList<Kit>> _kitsByRaceClass = new HashMap<>();
|
||||
|
||||
private final byte kitNumber;
|
||||
private final int legs;
|
||||
private final int chest;
|
||||
private final int feet;
|
||||
private final int offhand;
|
||||
private final int weapon;
|
||||
private final EnumMap<EquipSlotType, Integer> items = new EnumMap<>(EquipSlotType.class);
|
||||
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
*/
|
||||
public Kit(int raceBaseClassID, byte kitNumber, int legs, int chest,
|
||||
int feet, int offhand, int weapon) {
|
||||
public Kit(StartingKitTemplate template) {
|
||||
super();
|
||||
this.raceBaseClassID = raceBaseClassID;
|
||||
this.kitNumber = kitNumber;
|
||||
this.legs = legs;
|
||||
this.chest = chest;
|
||||
this.feet = feet;
|
||||
this.offhand = offhand;
|
||||
this.weapon = weapon;
|
||||
|
||||
int itemID;
|
||||
ItemTemplate itemTemplate;
|
||||
EquipSlotType slot;
|
||||
|
||||
this.kitNumber = (byte) template.kit_number;
|
||||
|
||||
// The cfg lists the off-hand column before the weapon; fill from the end so the weapon takes RHELD
|
||||
for (int i = template.item_ids.size() - 1; i >= 0; i--) {
|
||||
itemID = template.item_ids.get(i);
|
||||
Kit.NoobGearIDS.put(itemID, true);
|
||||
itemTemplate = ItemTemplate._items.get(itemID);
|
||||
|
||||
if (itemTemplate == null) {
|
||||
Logger.warn("Kit " + kitKey(template.race, template.sex.name(), template.base_class) + " #" + this.kitNumber
|
||||
+ ": no item template " + itemID);
|
||||
continue;
|
||||
}
|
||||
|
||||
slot = freeSlot(itemTemplate);
|
||||
|
||||
if (slot == null) {
|
||||
Logger.warn("Kit " + kitKey(template.race, template.sex.name(), template.base_class) + " #" + this.kitNumber
|
||||
+ ": no free slot for item " + itemID);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.items.put(slot, itemID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public Kit(int raceBaseClassID, byte kitNumber, int legs, int chest,
|
||||
int feet, int offhand, int weapon, int newUUID) {
|
||||
super(newUUID);
|
||||
this.raceBaseClassID = raceBaseClassID;
|
||||
this.kitNumber = kitNumber;
|
||||
this.legs = legs;
|
||||
this.chest = chest;
|
||||
this.feet = feet;
|
||||
this.offhand = offhand;
|
||||
this.weapon = weapon;
|
||||
}
|
||||
public static void LoadAllKits() {
|
||||
|
||||
/**
|
||||
* RecordSet Constructor
|
||||
*/
|
||||
public Kit(ResultSet rs) throws SQLException, UnknownHostException {
|
||||
super(rs);
|
||||
|
||||
this.raceBaseClassID = rs.getInt("RaceBaseClassesID");
|
||||
this.kitNumber = rs.getByte("kitNumber");
|
||||
|
||||
this.legs = rs.getInt("legs");
|
||||
this.chest = rs.getInt("chest");
|
||||
this.feet = rs.getInt("feet");
|
||||
this.offhand = rs.getInt("offhand");
|
||||
this.weapon = rs.getInt("weapon");
|
||||
if (Kit.RaceClassIDMap.containsKey(this.raceBaseClassID)) {
|
||||
Kit.RaceClassIDMap.get(this.raceBaseClassID).add(this);
|
||||
} else {
|
||||
ArrayList<Kit> tempList = new ArrayList<>();
|
||||
tempList.add(this);
|
||||
Kit.RaceClassIDMap.put(this.raceBaseClassID, tempList);
|
||||
Kit kit;
|
||||
String key;
|
||||
|
||||
for (StartingKitTemplate template : StartingKitTemplate._kits) {
|
||||
kit = new Kit(template);
|
||||
key = kitKey(template.race, template.sex.name(), template.base_class);
|
||||
_kitsByRaceClass.computeIfAbsent(key, k -> new ArrayList<>()).add(kit);
|
||||
}
|
||||
|
||||
if (this.legs != 0)
|
||||
Kit.NoobGearIDS.put(this.legs, true);
|
||||
if (this.chest != 0)
|
||||
Kit.NoobGearIDS.put(this.chest, true);
|
||||
if (this.feet != 0)
|
||||
Kit.NoobGearIDS.put(this.feet, true);
|
||||
if (this.offhand != 0)
|
||||
Kit.NoobGearIDS.put(this.offhand, true);
|
||||
if (this.weapon != 0)
|
||||
Kit.NoobGearIDS.put(this.weapon, true);
|
||||
Logger.info("Loaded " + StartingKitTemplate._kits.size() + " kits for " + _kitsByRaceClass.size() + " race/sex/class");
|
||||
}
|
||||
|
||||
public static Kit getKit(int raceRuneID, int baseClassRuneID, int kitNumber) {
|
||||
|
||||
RuneTemplate raceRune = RuneTemplate._runes.get(raceRuneID);
|
||||
RuneTemplate classRune = RuneTemplate._runes.get(baseClassRuneID);
|
||||
mbEnums.RaceType raceType = mbEnums.RaceType.getRaceTypebyRuneID(raceRuneID);
|
||||
ArrayList<Kit> kits;
|
||||
|
||||
if (raceRune == null || classRune == null || raceType == null)
|
||||
return null;
|
||||
|
||||
kits = _kitsByRaceClass.get(kitKey(raceRune.obj_name, raceType.getCharacterSex().name(), classRune.obj_name));
|
||||
|
||||
if (kits == null || kitNumber < 0 || kitNumber >= kits.size())
|
||||
return null;
|
||||
|
||||
return kits.get(kitNumber);
|
||||
}
|
||||
|
||||
public static boolean IsNoobGear(int itemID) {
|
||||
@@ -107,9 +107,9 @@ public class Kit extends AbstractGameObject {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
private static String kitKey(String race, String sex, String baseClass) {
|
||||
return race + " " + sex + " " + baseClass;
|
||||
}
|
||||
|
||||
private static boolean kitItemCreator(PlayerCharacter pc, int templateID, mbEnums.EquipSlotType slot) {
|
||||
|
||||
@@ -131,293 +131,22 @@ public class Kit extends AbstractGameObject {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int GetKitIDByRaceClass(final int raceID, final int classID) {
|
||||
switch (raceID) {
|
||||
case 2000:
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 2;
|
||||
case 2501:
|
||||
return 3;
|
||||
case 2502:
|
||||
return 4;
|
||||
case 2503:
|
||||
return 5;
|
||||
}
|
||||
case 2001:
|
||||
private EquipSlotType freeSlot(ItemTemplate itemTemplate) {
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 6;
|
||||
case 2501:
|
||||
return 7;
|
||||
case 2502:
|
||||
return 8;
|
||||
case 2503:
|
||||
return 9;
|
||||
}
|
||||
case 2002:
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 10;
|
||||
case 2501:
|
||||
return 11;
|
||||
case 2502:
|
||||
return 12;
|
||||
for (EquipSlotType slot : itemTemplate.item_eq_slots_or)
|
||||
if (!this.items.containsKey(slot))
|
||||
return slot;
|
||||
|
||||
}
|
||||
case 2003:
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 13;
|
||||
case 2501:
|
||||
return 14;
|
||||
case 2502:
|
||||
return 15;
|
||||
}
|
||||
case 2004:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 16;
|
||||
case 2501:
|
||||
return 17;
|
||||
}
|
||||
case 2005:
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 18;
|
||||
case 2501:
|
||||
return 19;
|
||||
}
|
||||
case 2006:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 20;
|
||||
case 2501:
|
||||
return 21;
|
||||
|
||||
}
|
||||
case 2008:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 22;
|
||||
case 2501:
|
||||
return 23;
|
||||
case 2502:
|
||||
return 24;
|
||||
case 2503:
|
||||
return 25;
|
||||
}
|
||||
|
||||
case 2009:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 26;
|
||||
case 2501:
|
||||
return 27;
|
||||
case 2502:
|
||||
return 28;
|
||||
case 2503:
|
||||
return 29;
|
||||
}
|
||||
case 2010:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 30;
|
||||
}
|
||||
|
||||
case 2011:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 31;
|
||||
case 2501:
|
||||
return 32;
|
||||
case 2502:
|
||||
return 33;
|
||||
case 2503:
|
||||
return 34;
|
||||
}
|
||||
|
||||
case 2012:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 35;
|
||||
case 2501:
|
||||
return 36;
|
||||
case 2502:
|
||||
return 37;
|
||||
case 2503:
|
||||
return 38;
|
||||
}
|
||||
|
||||
case 2013:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 39;
|
||||
case 2501:
|
||||
return 40;
|
||||
case 2502:
|
||||
return 41;
|
||||
case 2503:
|
||||
return 42;
|
||||
}
|
||||
|
||||
case 2014:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 43;
|
||||
case 2501:
|
||||
return 44;
|
||||
case 2502:
|
||||
return 45;
|
||||
case 2503:
|
||||
return 46;
|
||||
}
|
||||
|
||||
case 2015:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 47;
|
||||
case 2502:
|
||||
return 48;
|
||||
case 2503:
|
||||
return 49;
|
||||
|
||||
}
|
||||
|
||||
case 2016:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 50;
|
||||
case 2502:
|
||||
return 51;
|
||||
case 2503:
|
||||
return 52;
|
||||
|
||||
}
|
||||
|
||||
case 2017:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 53;
|
||||
case 2501:
|
||||
return 54;
|
||||
|
||||
}
|
||||
|
||||
case 2025:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 55;
|
||||
case 2501:
|
||||
return 56;
|
||||
case 2502:
|
||||
return 57;
|
||||
case 2503:
|
||||
return 58;
|
||||
}
|
||||
|
||||
case 2026:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 59;
|
||||
case 2501:
|
||||
return 60;
|
||||
case 2502:
|
||||
return 61;
|
||||
case 2503:
|
||||
return 62;
|
||||
}
|
||||
|
||||
case 2027:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 63;
|
||||
}
|
||||
|
||||
case 2028:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 64;
|
||||
|
||||
case 2502:
|
||||
return 65;
|
||||
case 2503:
|
||||
return 66;
|
||||
}
|
||||
|
||||
case 2029:
|
||||
|
||||
switch (classID) {
|
||||
case 2500:
|
||||
return 67;
|
||||
|
||||
case 2502:
|
||||
return 68;
|
||||
case 2503:
|
||||
return 69;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getRaceBaseClassID() {
|
||||
return raceBaseClassID;
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte getKitNumber() {
|
||||
return kitNumber;
|
||||
}
|
||||
|
||||
public int getLegs() {
|
||||
return legs;
|
||||
}
|
||||
|
||||
public int getChest() {
|
||||
return chest;
|
||||
}
|
||||
|
||||
public int getFeet() {
|
||||
return feet;
|
||||
}
|
||||
|
||||
public int getOffhand() {
|
||||
return offhand;
|
||||
}
|
||||
|
||||
public int getWeapon() {
|
||||
return weapon;
|
||||
}
|
||||
|
||||
public void equipPCwithKit(PlayerCharacter pc) {
|
||||
if (weapon != 0)
|
||||
kitItemCreator(pc, weapon, mbEnums.EquipSlotType.RHELD);
|
||||
if (offhand != 0)
|
||||
kitItemCreator(pc, offhand, mbEnums.EquipSlotType.LHELD);
|
||||
if (chest != 0)
|
||||
kitItemCreator(pc, chest, mbEnums.EquipSlotType.CHEST);
|
||||
if (legs != 0)
|
||||
kitItemCreator(pc, legs, mbEnums.EquipSlotType.LEGS);
|
||||
if (feet != 0)
|
||||
kitItemCreator(pc, feet, mbEnums.EquipSlotType.FEET);
|
||||
for (Map.Entry<EquipSlotType, Integer> entry : this.items.entrySet())
|
||||
kitItemCreator(pc, entry.getValue(), entry.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,10 +9,14 @@
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import engine.mbEnums;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.util.Hasher;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MaxSkills {
|
||||
|
||||
@@ -23,17 +27,6 @@ public class MaxSkills {
|
||||
private int maxSkillPercent;
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
|
||||
public MaxSkills(ResultSet rs) throws SQLException {
|
||||
this.runeID = rs.getInt("runeID");
|
||||
this.skillToken = rs.getInt("skillToken");
|
||||
this.skillLevel = rs.getInt("skillLevel");
|
||||
this.maxSkillPercent = rs.getInt("maxSkillPercent");
|
||||
}
|
||||
|
||||
public MaxSkills(int runeID, int skillToken, int skillLevel, int maxSkillPercent) {
|
||||
super();
|
||||
this.runeID = runeID;
|
||||
@@ -42,6 +35,29 @@ public class MaxSkills {
|
||||
this.maxSkillPercent = maxSkillPercent;
|
||||
}
|
||||
|
||||
public static void LoadAllMaxSkills() {
|
||||
|
||||
ArrayList<MaxSkills> maxSkillsList;
|
||||
int entryCount = 0;
|
||||
|
||||
// Talents only: class/discipline/race adjusts are skill grants, and contracts that key on those runes would read them as caps
|
||||
for (RuneTemplate rune : RuneTemplate._runes.values()) {
|
||||
if (rune.rune_type != mbEnums.RuneType.TALENT || rune.rune_skill_adj.isEmpty())
|
||||
continue;
|
||||
|
||||
maxSkillsList = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, ArrayList<int[]>> skillAdjust : rune.rune_skill_adj.entrySet())
|
||||
for (int[] adjust : skillAdjust.getValue())
|
||||
maxSkillsList.add(new MaxSkills(rune.template_id, Hasher.SBStringHash(skillAdjust.getKey()), adjust[1], adjust[0]));
|
||||
|
||||
MaxSkillsSet.put(rune.template_id, maxSkillsList);
|
||||
entryCount += maxSkillsList.size();
|
||||
}
|
||||
|
||||
Logger.info("Loaded " + entryCount + " max skills for " + MaxSkillsSet.size() + " runes");
|
||||
}
|
||||
|
||||
public int getRuneID() {
|
||||
return runeID;
|
||||
}
|
||||
|
||||
+100
-31
@@ -22,6 +22,7 @@ import engine.net.ByteBufferWriter;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.client.msg.PetMsg;
|
||||
import engine.net.client.msg.PlaceAssetMsg;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -29,6 +30,7 @@ import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Delayed;
|
||||
@@ -164,7 +166,7 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
||||
writer.putInt(0);
|
||||
writer.putInt(0);
|
||||
|
||||
int tid = (mob.mobBase != null) ? mob.mobBase.getLoadID() : 0;
|
||||
int tid = (mob.mobBase != null) ? mob.mobBase.getObjectUUID() : 0;
|
||||
if (mob.isPet()) {
|
||||
writer.putInt(2);
|
||||
writer.putInt(3);
|
||||
@@ -181,8 +183,8 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
||||
serializeRune(mob, writer, 5, GameObjectType.NPCClassRuneTwo.ordinal(), 252621); //guard rune
|
||||
} else if (mob.contract != null || mob.isPlayerGuard()) {
|
||||
writer.putInt(3);
|
||||
serializeRune(mob, writer, 3, GameObjectType.NPCClassRuneTwo.ordinal(), MobBase.GetClassType(mob.getMobBaseID())); //warrior class
|
||||
serializeRune(mob, writer, 5, GameObjectType.NPCClassRuneThree.ordinal(), 252621); //guard rune
|
||||
serializeRune(mob, writer, 3, GameObjectType.NPCClassRuneTwo.ordinal(), 2518); //warrior class
|
||||
serializeRune(mob, writer, 5, GameObjectType.NPCClassRuneThree.ordinal(), mob.getGuardRuneID());
|
||||
} else
|
||||
writer.putInt(1);
|
||||
|
||||
@@ -191,26 +193,26 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
||||
writer.putInt(0);
|
||||
|
||||
if (mob.mobBase != null)
|
||||
writer.putInt(mob.mobBase.getLoadID());
|
||||
writer.putInt(mob.mobBase.getObjectUUID());
|
||||
else
|
||||
writer.putInt(mob.loadID);
|
||||
|
||||
writer.putInt(mob.getObjectType().ordinal());
|
||||
writer.putInt(mob.currentID);
|
||||
|
||||
//Send Stats
|
||||
// Stats are the base (spent points, 0 for mobs); the client adds every sent rune's attr adj (0x470610)
|
||||
|
||||
writer.putInt(5);
|
||||
writer.putInt(0x8AC3C0E6); //Str
|
||||
writer.putInt(mob.statStrCurrent);
|
||||
writer.putInt(0xACB82E33); //Dex
|
||||
writer.putInt(mob.statDexCurrent);
|
||||
writer.putInt(0xB15DC77E); //Con
|
||||
writer.putInt(mob.statConCurrent);
|
||||
writer.putInt(0xE07B3336); //Int
|
||||
writer.putInt(mob.statIntCurrent);
|
||||
writer.putInt(0xFF665EC3); //Spi
|
||||
writer.putInt(mob.statSpiCurrent);
|
||||
writer.putInt(MBServerStatics.STAT_STR_ID);
|
||||
writer.putInt(0);
|
||||
writer.putInt(MBServerStatics.STAT_DEX_ID);
|
||||
writer.putInt(0);
|
||||
writer.putInt(MBServerStatics.STAT_CON_ID);
|
||||
writer.putInt(0);
|
||||
writer.putInt(MBServerStatics.STAT_INT_ID);
|
||||
writer.putInt(0);
|
||||
writer.putInt(MBServerStatics.STAT_SPI_ID);
|
||||
writer.putInt(0);
|
||||
|
||||
|
||||
writer.putString(mob.firstName);
|
||||
@@ -227,9 +229,9 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
||||
writer.putInt(mob.currentID);
|
||||
|
||||
if (mob.mobBase != null) {
|
||||
writer.putFloat(mob.mobBase.getScale());
|
||||
writer.putFloat(mob.mobBase.getScale());
|
||||
writer.putFloat(mob.mobBase.getScale());
|
||||
writer.putFloat(mob.mobBase.getScale().x);
|
||||
writer.putFloat(mob.mobBase.getScale().y);
|
||||
writer.putFloat(mob.mobBase.getScale().z);
|
||||
} else {
|
||||
writer.putFloat(1.0f);
|
||||
writer.putFloat(1.0f);
|
||||
@@ -436,6 +438,30 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
||||
return mobile;
|
||||
}
|
||||
|
||||
// MB_MINION_SPAWN_TIME (seconds) shortens guard/siege minion spawns for testing; 0 or blank keeps the normal timers.
|
||||
private static int minionSpawnDelay(int defaultDelay) {
|
||||
|
||||
String overrideValue;
|
||||
int overrideDelay;
|
||||
|
||||
overrideValue = ConfigManager.MB_MINION_SPAWN_TIME.getValue();
|
||||
|
||||
if (overrideValue == null || overrideValue.trim().isEmpty())
|
||||
return defaultDelay;
|
||||
|
||||
try {
|
||||
overrideDelay = Integer.parseInt(overrideValue.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
Logger.warn("MB_MINION_SPAWN_TIME is not a number: " + overrideValue);
|
||||
return defaultDelay;
|
||||
}
|
||||
|
||||
if (overrideDelay <= 0)
|
||||
return defaultDelay;
|
||||
|
||||
return overrideDelay;
|
||||
}
|
||||
|
||||
public static synchronized Mob createGuardMinion(Mob guardCaptain, short level, String minionName) {
|
||||
|
||||
Mob minionMobile;
|
||||
@@ -455,7 +481,7 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
||||
|
||||
minionMobile.deathTime = System.currentTimeMillis();
|
||||
minionMobile.guardCaptain = guardCaptain;
|
||||
minionMobile.spawnDelay = (int) (-2.500 * guardCaptain.building.getRank() + 22.5) * 60;
|
||||
minionMobile.spawnDelay = minionSpawnDelay((int) (-2.500 * guardCaptain.building.getRank() + 22.5) * 60);
|
||||
minionMobile.behaviourType = mbEnums.MobBehaviourType.GuardMinion;
|
||||
minionMobile.agentType = AIAgentType.GUARDMINION;
|
||||
minionMobile.guardedCity = guardCaptain.guardedCity;
|
||||
@@ -514,7 +540,7 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
||||
siegeMinion.behaviourType = MobBehaviourType.SiegeEngine;
|
||||
siegeMinion.agentType = AIAgentType.SIEGEENGINE;
|
||||
siegeMinion.bindLoc = Vector3fImmutable.ZERO;
|
||||
siegeMinion.spawnDelay = (60 * 15);
|
||||
siegeMinion.spawnDelay = minionSpawnDelay(60 * 15);
|
||||
|
||||
siegeMinion.runAfterLoad();
|
||||
|
||||
@@ -553,10 +579,8 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
||||
petMinion.despawned = false;
|
||||
petMinion.runAfterLoad();
|
||||
|
||||
// Summoned pets carry MASK_PET. Necro pets keep their own NecroPet handling.
|
||||
|
||||
if (!petMinion.isNecroPet())
|
||||
petMinion.setObjectTypeMask(petMinion.getObjectTypeMask() | MBServerStatics.MASK_PET);
|
||||
// Necro pets count as pets too: DRU-066 targets Pet and requires NECROPETSTATS
|
||||
petMinion.setObjectTypeMask(petMinion.getObjectTypeMask() | MBServerStatics.MASK_PET);
|
||||
|
||||
DbManager.addToCache(petMinion);
|
||||
petMinion.setLoc(petMinion.bindLoc);
|
||||
@@ -703,13 +727,59 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
||||
return this.bindLoc;
|
||||
}
|
||||
|
||||
// The runes serializeForClientMsgOtherPlayer sends; the client derives the mob's attributes from all of them
|
||||
public ArrayList<Integer> getClientRuneIDs() {
|
||||
|
||||
ArrayList<Integer> runeIDs = new ArrayList<>();
|
||||
|
||||
if (this.isPet())
|
||||
runeIDs.add(2522);
|
||||
else if (this.contract != null || this.isPlayerGuard()) {
|
||||
runeIDs.add(2518);
|
||||
runeIDs.add(this.getGuardRuneID());
|
||||
}
|
||||
|
||||
runeIDs.add((this.mobBase != null) ? this.mobBase.getObjectUUID() : this.loadID);
|
||||
return runeIDs;
|
||||
}
|
||||
|
||||
// Wall archers get 252622 Wall Guard; the rest get 252623 Standing Guard, the only rune that fires the client's CloseToGuard hint (0x67AB1B)
|
||||
public int getGuardRuneID() {
|
||||
|
||||
if (this.agentType == AIAgentType.GUARDWALLARCHER)
|
||||
return 252622;
|
||||
|
||||
return 252623;
|
||||
}
|
||||
|
||||
// Client ArcCharacter_RecalcMaxAttributes 0x470440 + RecalcAttributes 0x470610 with no spent points
|
||||
public int getRuneAttribute(AttributeType attributeType) {
|
||||
|
||||
RuneTemplate rune;
|
||||
int value = 0;
|
||||
int max = 0;
|
||||
|
||||
for (int runeID : this.getClientRuneIDs()) {
|
||||
rune = RuneTemplate._runes.get(runeID);
|
||||
|
||||
if (rune == null)
|
||||
continue;
|
||||
|
||||
value += rune.rune_attr_adj.getOrDefault(attributeType, 0);
|
||||
max += rune.rune_max_attr_adj.getOrDefault(attributeType, 0);
|
||||
}
|
||||
|
||||
max = Math.max(max, 1);
|
||||
return Math.min(Math.max(value, 1), max);
|
||||
}
|
||||
|
||||
public void calculateModifiedStats() {
|
||||
|
||||
float strVal = this.mobBase.getMobBaseStats().getBaseStr();
|
||||
float dexVal = this.mobBase.getMobBaseStats().getBaseDex();
|
||||
float conVal = this.mobBase.getMobBaseStats().getBaseCon();
|
||||
float intVal = this.mobBase.getMobBaseStats().getBaseInt();
|
||||
float spiVal = this.mobBase.getMobBaseStats().getBaseSpi();
|
||||
float strVal = this.getRuneAttribute(AttributeType.Strength);
|
||||
float dexVal = this.getRuneAttribute(AttributeType.Dexterity);
|
||||
float conVal = this.getRuneAttribute(AttributeType.Constitution);
|
||||
float intVal = this.getRuneAttribute(AttributeType.Intelligence);
|
||||
float spiVal = this.getRuneAttribute(AttributeType.Spirit);
|
||||
|
||||
// TODO modify for equipment
|
||||
if (this.bonuses != null) {
|
||||
@@ -746,7 +816,7 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
||||
bonus *= (1 + this.bonuses.getFloatPercentAll(ModType.Speed, SourceType.None));
|
||||
|
||||
if (this.isPlayerGuard())
|
||||
switch (this.mobBase.getLoadID()) {
|
||||
switch (this.mobBase.getObjectUUID()) {
|
||||
case 2111:
|
||||
if (this.isWalk())
|
||||
if (this.isCombat())
|
||||
@@ -1266,7 +1336,6 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
|
||||
|
||||
NPCManager.applyMobbaseEffects(this);
|
||||
NPCManager.applyEquipmentResists(this);
|
||||
NPCManager.applyMobbaseSkill(this);
|
||||
NPCManager.applyRuneSkills(this, this.getMobBaseID());
|
||||
this.recalculateStats();
|
||||
this.setHealth(this.healthMax);
|
||||
|
||||
@@ -13,8 +13,12 @@ import engine.gameManager.DbManager;
|
||||
import engine.gameManager.ItemManager;
|
||||
import engine.gameManager.LootManager;
|
||||
import engine.loot.BootySetEntry;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.mbEnums;
|
||||
import engine.parsers.cache.CacheParserUtil;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@@ -24,15 +28,15 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class MobBase extends AbstractGameObject {
|
||||
|
||||
private final int loadID;
|
||||
private final String firstName;
|
||||
private final byte level;
|
||||
private final float scale;
|
||||
private final Vector3fImmutable scale;
|
||||
public final ArrayList<MobBaseEffects> effectsList;
|
||||
public int bootySet;
|
||||
public mbEnums.MobBehaviourType fsm;
|
||||
public EnumSet<mbEnums.MonsterType> notEnemy;
|
||||
public EnumSet<mbEnums.MonsterType> enemy;
|
||||
public mbEnums.MonsterType monsterType;
|
||||
private float healthMax;
|
||||
private int attackRating;
|
||||
private int defenseRating;
|
||||
@@ -46,7 +50,6 @@ public class MobBase extends AbstractGameObject {
|
||||
private int spawnTime = 0;
|
||||
private float attackRange;
|
||||
private boolean isNecroPet = false;
|
||||
private MobBaseStats mobBaseStats;
|
||||
private float walk = 0;
|
||||
private float run = 0;
|
||||
private float walkCombat = 0;
|
||||
@@ -58,31 +61,48 @@ public class MobBase extends AbstractGameObject {
|
||||
public MobBase(ResultSet rs) throws SQLException {
|
||||
super(rs, rs.getInt("ID"));
|
||||
|
||||
this.loadID = rs.getInt("loadID");
|
||||
RuneTemplate rune = null;
|
||||
String fsmName;
|
||||
|
||||
this.firstName = rs.getString("name");
|
||||
this.level = rs.getByte("level");
|
||||
rune = RuneTemplate._runes.get(this.getObjectUUID());
|
||||
|
||||
if (rune != null) {
|
||||
this.firstName = rune.obj_name;
|
||||
this.level = (byte) rune.rune_level;
|
||||
this.healthMax = rune.rune_health;
|
||||
this.damageMin = rune.rune_min_damage;
|
||||
this.damageMax = rune.rune_max_damage;
|
||||
this.attackRating = rune.rune_attack;
|
||||
this.defenseRating = rune.rune_defense;
|
||||
fsmName = rune.obj_sparse_data.getOrDefault("ROOTFSMID", mbEnums.MobBehaviourType.None.name());
|
||||
this.fsm = mbEnums.MobBehaviourType.valueOf(fsmName);
|
||||
this.notEnemy = EnumSet.copyOf(rune.rune_not_enemy_monster_types);
|
||||
this.enemy = EnumSet.copyOf(rune.rune_enemy_monster_types);
|
||||
// The race rune's sub type is its monster type (client g_MonsterTypeEnum, rune +0xC)
|
||||
this.monsterType = CacheParserUtil.readEnum(mbEnums.MonsterType.class, rune.rune_sub_type, rune.template_id, "rune_sub_type");
|
||||
this.walk = rune.rune_speed.getOrDefault(mbEnums.MovementType.WALK, 0f);
|
||||
this.walkCombat = rune.rune_speed.getOrDefault(mbEnums.MovementType.COMBATWALK, 0f);
|
||||
this.run = rune.rune_speed.getOrDefault(mbEnums.MovementType.RUN, 0f);
|
||||
this.runCombat = rune.rune_speed.getOrDefault(mbEnums.MovementType.COMBATRUN, 0f);
|
||||
this.scale = (rune.rune_scale_factor != null) ? rune.rune_scale_factor : new Vector3fImmutable(1, 1, 1);
|
||||
} else {
|
||||
Logger.error("Mobbase " + this.getObjectUUID() + " has no race rune");
|
||||
this.firstName = "";
|
||||
this.level = 0;
|
||||
this.fsm = mbEnums.MobBehaviourType.None;
|
||||
this.notEnemy = EnumSet.noneOf(mbEnums.MonsterType.class);
|
||||
this.enemy = EnumSet.noneOf(mbEnums.MonsterType.class);
|
||||
this.scale = new Vector3fImmutable(1, 1, 1);
|
||||
}
|
||||
|
||||
this.goldMod = rs.getInt("goldMod");
|
||||
this.spawnTime = rs.getInt("spawnTime");
|
||||
|
||||
this.healthMax = rs.getInt("health");
|
||||
this.damageMin = rs.getFloat("minDmg");
|
||||
this.damageMax = rs.getFloat("maxDmg");
|
||||
|
||||
this.attackRating = rs.getInt("atr");
|
||||
this.defenseRating = rs.getInt("defense");
|
||||
this.attackRange = rs.getFloat("attackRange");
|
||||
this.bootySet = rs.getInt("bootySet");
|
||||
|
||||
this.fsm = mbEnums.MobBehaviourType.valueOf(rs.getString("fsm"));
|
||||
|
||||
this.flags = mbEnums.fromLong(rs.getLong("flags"), mbEnums.MobFlagType.class);
|
||||
this.notEnemy = mbEnums.fromLong(rs.getLong("notEnemy"), mbEnums.MonsterType.class);
|
||||
this.enemy = mbEnums.fromLong(rs.getLong("enemy"), mbEnums.MonsterType.class);
|
||||
|
||||
this.seeInvis = rs.getInt("seeInvis");
|
||||
this.scale = rs.getFloat("scale");
|
||||
this.hitBoxRadius = 5f;
|
||||
this.mask = 0;
|
||||
|
||||
@@ -104,10 +124,7 @@ public class MobBase extends AbstractGameObject {
|
||||
if (this.flags.contains(mbEnums.MobFlagType.RAT))
|
||||
this.mask += MBServerStatics.MASK_RAT;
|
||||
|
||||
this.mobBaseStats = DbManager.MobBaseQueries.LOAD_STATS(this.loadID);
|
||||
DbManager.MobBaseQueries.LOAD_ALL_MOBBASE_SPEEDS(this);
|
||||
//load effects for mobbase
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.loadID);
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(this.getObjectUUID());
|
||||
|
||||
}
|
||||
|
||||
@@ -127,9 +144,13 @@ public class MobBase extends AbstractGameObject {
|
||||
for (BootySetEntry equipmentSetEntry : equipList) {
|
||||
|
||||
Item item = new Item(equipmentSetEntry.templateID);
|
||||
|
||||
if (item.template.getItemEqSlotsOr().isEmpty())
|
||||
continue;
|
||||
|
||||
item.objectUUID = ItemManager.lastNegativeID.decrementAndGet();
|
||||
item.drop_chance = equipmentSetEntry.dropChance;
|
||||
item.equipSlot = item.template.item_eq_slots_or.iterator().next();
|
||||
item.equipSlot = item.template.getItemEqSlotsOr().iterator().next();
|
||||
equip.put(item.equipSlot, item);
|
||||
|
||||
}
|
||||
@@ -141,34 +162,6 @@ public class MobBase extends AbstractGameObject {
|
||||
return DbManager.MobBaseQueries.GET_MOBBASE(id);
|
||||
}
|
||||
|
||||
public static int GetClassType(int mobbaseID) {
|
||||
|
||||
switch (mobbaseID) {
|
||||
case 17235:
|
||||
case 17233:
|
||||
case 17256:
|
||||
case 17259:
|
||||
case 17260:
|
||||
case 17261:
|
||||
return 2518;
|
||||
case 17258:
|
||||
case 17257:
|
||||
case 17237:
|
||||
case 17234:
|
||||
return 2521;
|
||||
default:
|
||||
return 2518;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateSpeeds(float walk, float walkCombat, float run, float runCombat) {
|
||||
this.walk = walk;
|
||||
this.walkCombat = walkCombat;
|
||||
this.run = run;
|
||||
this.runCombat = runCombat;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
@@ -176,10 +169,6 @@ public class MobBase extends AbstractGameObject {
|
||||
return this.firstName;
|
||||
}
|
||||
|
||||
public int getLoadID() {
|
||||
return this.loadID;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return this.level;
|
||||
}
|
||||
@@ -208,7 +197,8 @@ public class MobBase extends AbstractGameObject {
|
||||
return this.flags;
|
||||
}
|
||||
|
||||
public float getScale() {
|
||||
// Cosmetic only: the client rebuilds a mob's scale from its race rune (ArcCharacter_BuildCharFromRune 0x458160)
|
||||
public Vector3fImmutable getScale() {
|
||||
return this.scale;
|
||||
}
|
||||
|
||||
@@ -237,10 +227,6 @@ public class MobBase extends AbstractGameObject {
|
||||
}
|
||||
}
|
||||
|
||||
public MobBaseStats getMobBaseStats() {
|
||||
return mobBaseStats;
|
||||
}
|
||||
|
||||
public float getAttackRange() {
|
||||
return attackRange;
|
||||
}
|
||||
|
||||
@@ -9,38 +9,69 @@
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.parsers.objects.UserPowerAction;
|
||||
import engine.parsers.objects.wpak.PowerActionTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.util.Hasher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class MobBaseEffects {
|
||||
|
||||
private int mobBaseID;
|
||||
private static final ConcurrentHashMap<Integer, ArrayList<MobBaseEffects>> effectsByRune = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
private int token;
|
||||
private int rank;
|
||||
private int reqLvl;
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public MobBaseEffects(ResultSet rs) throws SQLException {
|
||||
this.token = rs.getInt("token");
|
||||
this.rank = rs.getInt("rank");
|
||||
this.reqLvl = rs.getInt("reqLvl");
|
||||
public MobBaseEffects(int token, int rank, int reqLvl) {
|
||||
this.token = token;
|
||||
this.rank = rank;
|
||||
this.reqLvl = reqLvl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the mobBaseID
|
||||
*/
|
||||
public int getMobBaseID() {
|
||||
return mobBaseID;
|
||||
public static ArrayList<MobBaseEffects> getEffectsForRune(int runeID) {
|
||||
return effectsByRune.computeIfAbsent(runeID, MobBaseEffects::loadEffectsForRune);
|
||||
}
|
||||
|
||||
// item_user_power_action entries are {action id, [rank, reqLvl]}; the action names the effect to apply
|
||||
private static ArrayList<MobBaseEffects> loadEffectsForRune(int runeID) {
|
||||
|
||||
public void setMobBaseID(int mobBaseID) {
|
||||
this.mobBaseID = mobBaseID;
|
||||
ArrayList<MobBaseEffects> runeEffects = new ArrayList<>();
|
||||
HashSet<String> seenEntries = new HashSet<>();
|
||||
RuneTemplate rune = RuneTemplate._runes.get(runeID);
|
||||
PowerActionTemplate powerAction;
|
||||
String effectID;
|
||||
int rank;
|
||||
int reqLvl;
|
||||
|
||||
if (rune == null)
|
||||
return runeEffects;
|
||||
|
||||
for (UserPowerAction userPowerAction : rune.item_user_power_action) {
|
||||
|
||||
rank = userPowerAction.arguments.length > 0 ? userPowerAction.arguments[0] : 0;
|
||||
reqLvl = userPowerAction.arguments.length > 1 ? userPowerAction.arguments[1] : 0;
|
||||
|
||||
// 54 rune files repeat their whole list; the DB kept each entry once
|
||||
if (!seenEntries.add(userPowerAction.power + ":" + rank + ":" + reqLvl))
|
||||
continue;
|
||||
|
||||
powerAction = PowerActionTemplate._powerActions.get(userPowerAction.power);
|
||||
|
||||
if (powerAction != null && !powerAction.effect_ids.isEmpty())
|
||||
effectID = powerAction.effect_ids.get(0);
|
||||
else
|
||||
effectID = userPowerAction.power;
|
||||
|
||||
runeEffects.add(new MobBaseEffects(Hasher.SBStringHash(effectID), rank, reqLvl));
|
||||
}
|
||||
|
||||
return runeEffects;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2026
|
||||
// https://www.magicbane.com
|
||||
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class MobBaseStats {
|
||||
|
||||
public static MobBaseStats mbs = null;
|
||||
private final int baseStr;
|
||||
private final int baseInt;
|
||||
private final int baseCon;
|
||||
private final int baseSpi;
|
||||
private final int baseDex;
|
||||
|
||||
private final int mobbaseSkill;
|
||||
private final int mobbaseSkillAmount;
|
||||
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public MobBaseStats(ResultSet rs) throws SQLException {
|
||||
this.baseStr = rs.getInt("Strength");
|
||||
this.baseInt = rs.getInt("Intelligence");
|
||||
this.baseCon = rs.getInt("Constitution");
|
||||
this.baseSpi = rs.getInt("Spirit");
|
||||
this.baseDex = rs.getInt("Dexterity");
|
||||
this.mobbaseSkill = rs.getInt("baseSkills");
|
||||
this.mobbaseSkillAmount = rs.getInt("skillAmount");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic Constructor
|
||||
*/
|
||||
|
||||
public MobBaseStats() {
|
||||
this.baseStr = 0;
|
||||
this.baseInt = 0;
|
||||
this.baseCon = 0;
|
||||
this.baseSpi = 0;
|
||||
this.baseDex = 0;
|
||||
this.mobbaseSkill = 0;
|
||||
this.mobbaseSkillAmount = 0;
|
||||
}
|
||||
|
||||
public static MobBaseStats GetGenericStats() {
|
||||
if (mbs != null)
|
||||
return mbs;
|
||||
mbs = new MobBaseStats();
|
||||
return mbs;
|
||||
}
|
||||
|
||||
public int getBaseStr() {
|
||||
return baseStr;
|
||||
}
|
||||
|
||||
public int getBaseInt() {
|
||||
return baseInt;
|
||||
}
|
||||
|
||||
public int getBaseCon() {
|
||||
return baseCon;
|
||||
}
|
||||
|
||||
public int getBaseSpi() {
|
||||
return baseSpi;
|
||||
}
|
||||
|
||||
public int getBaseDex() {
|
||||
return baseDex;
|
||||
}
|
||||
|
||||
public int getBaseSkill() {
|
||||
return mobbaseSkill;
|
||||
}
|
||||
|
||||
public int getBaseSkillAmount() {
|
||||
return mobbaseSkillAmount;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import engine.gameManager.PowersManager;
|
||||
import engine.mbEnums;
|
||||
import engine.mbEnums.ItemType;
|
||||
import engine.mbEnums.OwnerType;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.powers.poweractions.AbstractPowerAction;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
@@ -30,22 +31,22 @@ public final class MobLoot extends Item {
|
||||
private String prefix = "";
|
||||
private String suffix = "";
|
||||
|
||||
public MobLoot(AbstractCharacter mob, ItemTemplate template, boolean noSteal) {
|
||||
public MobLoot(AbstractCharacter mob, CObjectTemplate template, boolean noSteal) {
|
||||
this(mob, template, 0, noSteal);
|
||||
}
|
||||
|
||||
public MobLoot(AbstractCharacter mob, int qtyOfGold) {
|
||||
this(mob, ItemTemplate.templates.get(mbEnums.ResourceType.GOLD.templateID), qtyOfGold, false);
|
||||
this(mob, CObjectTemplate.lookup(mbEnums.ResourceType.GOLD.templateID), qtyOfGold, false);
|
||||
}
|
||||
|
||||
public MobLoot(AbstractCharacter mob, ItemTemplate template, int quantity, boolean noSteal) {
|
||||
public MobLoot(AbstractCharacter mob, CObjectTemplate template, int quantity, boolean noSteal) {
|
||||
|
||||
super(template.template_id);
|
||||
super(template.getTemplateId());
|
||||
this.ownerType = OwnerType.Mob;
|
||||
this.ownerID = mob.getObjectUUID();
|
||||
this.objectUUID = generateId();
|
||||
|
||||
if (quantity == 0 && template.item_type == ItemType.RESOURCE)
|
||||
if (quantity == 0 && template.getItemType() == ItemType.RESOURCE)
|
||||
quantity = 1;
|
||||
|
||||
if (quantity > 0)
|
||||
@@ -105,7 +106,7 @@ public final class MobLoot extends Item {
|
||||
if (isDeleted)
|
||||
return null;
|
||||
|
||||
if (this.template.item_type.equals(ItemType.GOLD))
|
||||
if (this.template.getItemType().equals(ItemType.GOLD))
|
||||
return null;
|
||||
|
||||
Item item = this;
|
||||
|
||||
+12
-11
@@ -23,6 +23,7 @@ import engine.net.ByteBufferWriter;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.client.msg.PetMsg;
|
||||
import engine.net.client.msg.PlaceAssetMsg;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.joda.time.DateTime;
|
||||
import org.pmw.tinylog.Logger;
|
||||
@@ -235,7 +236,7 @@ public class NPC extends AbstractCharacter {
|
||||
writer.putInt(0);
|
||||
|
||||
if (npc.mobBase != null)
|
||||
writer.putInt(npc.mobBase.getLoadID());
|
||||
writer.putInt(npc.mobBase.getObjectUUID());
|
||||
else
|
||||
writer.putInt(2011);
|
||||
|
||||
@@ -287,15 +288,15 @@ public class NPC extends AbstractCharacter {
|
||||
|
||||
//Send Stats
|
||||
writer.putInt(5);
|
||||
writer.putInt(0x8AC3C0E6); //Str
|
||||
writer.putInt(MBServerStatics.STAT_STR_ID);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0xACB82E33); //Dex
|
||||
writer.putInt(MBServerStatics.STAT_DEX_ID);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0xB15DC77E); //Con
|
||||
writer.putInt(MBServerStatics.STAT_CON_ID);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0xE07B3336); //Int
|
||||
writer.putInt(MBServerStatics.STAT_INT_ID);
|
||||
writer.putInt(0);
|
||||
writer.putInt(0xFF665EC3); //Spi
|
||||
writer.putInt(MBServerStatics.STAT_SPI_ID);
|
||||
writer.putInt(0);
|
||||
|
||||
writer.putString(npc.name);
|
||||
@@ -961,15 +962,15 @@ public class NPC extends AbstractCharacter {
|
||||
maxSkill = 110;
|
||||
break;
|
||||
}
|
||||
ItemTemplate itemTemplate;
|
||||
CObjectTemplate itemTemplate;
|
||||
int skillRequired = 0;
|
||||
for (Integer itemID : fullItemList) {
|
||||
itemTemplate = ItemTemplate.templates.get(itemID);
|
||||
itemTemplate = CObjectTemplate.lookup(itemID);
|
||||
|
||||
if (itemTemplate.item_skill_required.values().iterator().hasNext())
|
||||
skillRequired = itemTemplate.item_skill_required.values().iterator().next();
|
||||
if (itemTemplate.getItemSkillReq().values().iterator().hasNext())
|
||||
skillRequired = itemTemplate.getItemSkillReq().values().iterator().next();
|
||||
|
||||
boolean exclude = skillRequired == 0 && ItemTemplate.templates.get(itemID).item_type.equals(ItemType.WEAPON);
|
||||
boolean exclude = skillRequired == 0 && CObjectTemplate.lookup(itemID).getItemType().equals(ItemType.WEAPON);
|
||||
if (skillRequired <= maxSkill && !exclude)
|
||||
filteredItemList.add(itemID);
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
@@ -23,7 +21,6 @@ public class NPCRune extends AbstractGameObject {
|
||||
private final RuneBase runeBase;
|
||||
private final int player;
|
||||
private final ArrayList<SkillReq> skillsGranted;
|
||||
private final ArrayList<RuneBaseEffect> effectsGranted;
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
@@ -33,10 +30,9 @@ public class NPCRune extends AbstractGameObject {
|
||||
this.runeBase = runeBase;
|
||||
this.player = characterID;
|
||||
if (this.runeBase != null)
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||
else
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,10 +43,9 @@ public class NPCRune extends AbstractGameObject {
|
||||
this.runeBase = runeBase;
|
||||
this.player = characterID;
|
||||
if (this.runeBase == null)
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||
else
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,25 +57,10 @@ public class NPCRune extends AbstractGameObject {
|
||||
this.runeBase = RuneBase.getRuneBase(rs.getInt("RuneBaseID"));
|
||||
this.player = rs.getInt("NpcID");
|
||||
if (this.runeBase != null) {
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||
} else {
|
||||
Logger.error("Failed to find RuneBase for NPCRune " + this.getObjectUUID());
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public static void serializeForClientMsg(NPCRune npcRune, ByteBufferWriter writer) {
|
||||
if (npcRune.runeBase != null) {
|
||||
writer.putInt(npcRune.runeBase.getType());
|
||||
writer.putInt(0);
|
||||
writer.putInt(npcRune.runeBase.getObjectUUID());
|
||||
writer.putInt(npcRune.getObjectType().ordinal());
|
||||
writer.putInt(npcRune.getObjectUUID());
|
||||
} else {
|
||||
for (int i = 0; i < 5; i++)
|
||||
writer.putInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,10 +89,6 @@ public class NPCRune extends AbstractGameObject {
|
||||
* Serializing
|
||||
*/
|
||||
|
||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
||||
return this.effectsGranted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
|
||||
|
||||
@@ -236,10 +236,6 @@ public class PlayerBonuses {
|
||||
}
|
||||
|
||||
|
||||
public void grantEffect(RuneBaseEffect rbe) {
|
||||
}
|
||||
|
||||
|
||||
public void setFloat(AbstractEffectModifier mod, float val) {
|
||||
if (val != 0)
|
||||
this.bonusFloats.put(mod, val);
|
||||
|
||||
@@ -32,6 +32,7 @@ import engine.net.Dispatch;
|
||||
import engine.net.client.ClientConnection;
|
||||
import engine.net.client.msg.*;
|
||||
import engine.net.client.msg.login.CommitNewCharacterMsg;
|
||||
import engine.parsers.objects.CObjectTemplate;
|
||||
import engine.powers.EffectsBase;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.server.login.LoginServer;
|
||||
@@ -729,6 +730,14 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
}
|
||||
|
||||
// The client enforces these rules, so a refusal usually means a modified client.
|
||||
|
||||
private static PlayerCharacter refuseCreation(Account account, ClientConnection clientConnection, String reason) {
|
||||
Logger.warn("Character creation refused: " + reason + " ACCOUNT: " + account.getUname() + "(" + account.getObjectUUID()
|
||||
+ ") IP ADDRESS: " + clientConnection.getClientIpAddress());
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PlayerCharacter generatePCFromCommitNewCharacterMsg(Account a, CommitNewCharacterMsg msg, ClientConnection clientConnection) {
|
||||
|
||||
String firstName = msg.getFirstName().trim();
|
||||
@@ -767,8 +776,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
Race race = Race.getRace(raceID);
|
||||
|
||||
if (race == null) {
|
||||
Logger.info("Invalid RaceID: " + raceID);
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Invalid RaceID: " + raceID);
|
||||
}
|
||||
|
||||
// Verify BaseClass Object.
|
||||
@@ -776,8 +784,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
BaseClass baseClass = DbManager.BaseClassQueries.GET_BASE_CLASS(baseClassID);
|
||||
|
||||
if (baseClass == null) {
|
||||
Logger.info("Invalid BaseClasID: " + baseClassID);
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Invalid BaseClasID: " + baseClassID);
|
||||
}
|
||||
|
||||
// Verify Race/baseClass combo.
|
||||
@@ -792,8 +799,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
Logger.info("Invalid BaseClass/Race Combo");
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Invalid BaseClass/Race Combo");
|
||||
}
|
||||
|
||||
// Verify HairStyle/BeardStyle/SkinColor/HairColor/BeardColor
|
||||
@@ -804,23 +810,19 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
int beardColorID = msg.getBeardColor();
|
||||
|
||||
if (!race.isValidHairStyle(hairStyleID)) {
|
||||
Logger.info("Invalid HairStyleID: " + hairStyleID + " for race: " + race.getName());
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Invalid HairStyleID: " + hairStyleID + " for race: " + race.getName());
|
||||
}
|
||||
|
||||
if (!race.isValidSkinColor(skinColorID)) {
|
||||
Logger.info("Invalid skinColorID: " + skinColorID + " for race: " + race.getName());
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Invalid skinColorID: " + skinColorID + " for race: " + race.getName());
|
||||
}
|
||||
|
||||
if (!race.isValidHairColor(hairColorID)) {
|
||||
Logger.info("Invalid hairColorID: " + hairColorID + " for race: " + race.getName());
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Invalid hairColorID: " + hairColorID + " for race: " + race.getName());
|
||||
}
|
||||
|
||||
if (!race.isValidBeardColor(beardColorID)) {
|
||||
Logger.info("Invalid beardColorID: " + beardColorID + " for race: " + race.getName());
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Invalid beardColorID: " + beardColorID + " for race: " + race.getName());
|
||||
}
|
||||
|
||||
// Get stat modifiers
|
||||
@@ -832,8 +834,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
|
||||
if (intMod < -5 || dexMod < -5 || conMod < -5 || strMod < -5 || spiMod < -5) {
|
||||
Logger.error("NEGATIVE STAT CHEAT ATTEMPTED! ACCOUNT: " + a.getUname() + "(" + a.getObjectUUID() + ") IP ADDRESS: " + clientConnection.getClientIpAddress());
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Negative stat mod");
|
||||
}
|
||||
|
||||
// calculate current stats:
|
||||
@@ -850,12 +851,11 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
short intMax = race.getIntMax();
|
||||
short spiMax = race.getSpiMax();
|
||||
|
||||
// Verify not too many runes applied
|
||||
// 10 rune slots including race and class (client 0xBA8C80)
|
||||
int numRunes = msg.getNumRunes();
|
||||
|
||||
if (numRunes > 16) {
|
||||
Logger.info("Too many Runes applied");
|
||||
return null;
|
||||
if (numRunes > 10) {
|
||||
return refuseCreation(a, clientConnection, "Too many Runes applied");
|
||||
}
|
||||
|
||||
// Get Runes
|
||||
@@ -865,7 +865,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
int[] characterRunes = msg.getRunes();
|
||||
|
||||
HashSet<Byte> usedRunesSubType = new HashSet<>();
|
||||
HashSet<Integer> usedRuneIDs = new HashSet<>();
|
||||
HashSet<Integer> usedSubTypeTokens = new HashSet<>();
|
||||
HashSet<RuneBase> usedRunes = new HashSet<>();
|
||||
|
||||
// So that all the penalties can be added at the end.
|
||||
@@ -905,38 +906,33 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
// Null check
|
||||
if (runeBase == null) {
|
||||
Logger.info("GOM returned NULL RuneBase");
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "GOM returned NULL RuneBase");
|
||||
}
|
||||
|
||||
// Validate Rune against Race
|
||||
if (!race.isAllowedRune(runeBase)) {
|
||||
Logger.info("Trait Not valid for Race");
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Trait Not valid for Race");
|
||||
}
|
||||
|
||||
// Validate BaseClass against Race
|
||||
if (!baseClass.isAllowedRune(runeBase)) {
|
||||
Logger.info("Trait Not valid for BaseClass");
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Trait Not valid for BaseClass");
|
||||
}
|
||||
|
||||
int previous_size = usedRunes.size();
|
||||
int previous_subtype = usedRunesSubType.size();
|
||||
if (!usedRuneIDs.add(runeBase.getObjectUUID())) {
|
||||
return refuseCreation(a, clientConnection, "Duplicate RuneBase");
|
||||
}
|
||||
|
||||
// Creation talents are rank 0, so two of the same sub type block each other (client 0x4695D0)
|
||||
if (runeBase.getSubTypeToken() != 0 && !usedSubTypeTokens.add(runeBase.getSubTypeToken())) {
|
||||
return refuseCreation(a, clientConnection, "Duplicate RuneBase Subtype");
|
||||
}
|
||||
|
||||
usedRunes.add(runeBase);
|
||||
usedRunesSubType.add(runeBase.getSubtype());
|
||||
|
||||
// Duplicate Rune check
|
||||
if (usedRunes.size() <= previous_size) {
|
||||
Logger.info("Duplicate RuneBase");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Duplicate Subtype check
|
||||
if (runeBase.getSubtype() != 0 && usedRunesSubType.size() <= previous_subtype) {
|
||||
Logger.info("Duplicate RuneBase Subtype");
|
||||
return null;
|
||||
// Talent cap of 8 (client 0x4695D0)
|
||||
if (usedRunes.size() > 8) {
|
||||
return refuseCreation(a, clientConnection, "Too many talents applied");
|
||||
}
|
||||
|
||||
int maxValue = 0;
|
||||
@@ -981,43 +977,37 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
remainingPoints -= value;
|
||||
continue;
|
||||
}
|
||||
Logger.info("Not enough points left");
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Not enough points left");
|
||||
case MBServerStatics.RUNE_STR_MIN_NEEDED_ATTRIBUTE_ID:
|
||||
|
||||
if (strCur >= value)
|
||||
continue;
|
||||
|
||||
Logger.info("STR fails to meet Rune Minimum --> " + rb.getName());
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "STR fails to meet Rune Minimum --> " + rb.getName());
|
||||
case MBServerStatics.RUNE_DEX_MIN_NEEDED_ATTRIBUTE_ID:
|
||||
|
||||
if (dexCur >= value)
|
||||
continue;
|
||||
|
||||
Logger.info("DEX fails to meet Rune Minimum --> " + rb.getName());
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "DEX fails to meet Rune Minimum --> " + rb.getName());
|
||||
case MBServerStatics.RUNE_CON_MIN_NEEDED_ATTRIBUTE_ID:
|
||||
|
||||
if (conCur >= value)
|
||||
continue;
|
||||
|
||||
Logger.info("CON fails to meet Rune Minimum --> " + rb.getName());
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "CON fails to meet Rune Minimum --> " + rb.getName());
|
||||
case MBServerStatics.RUNE_INT_MIN_NEEDED_ATTRIBUTE_ID:
|
||||
|
||||
if (intCur >= value)
|
||||
continue;
|
||||
|
||||
Logger.info("INT fails to meet Rune Minimum --> " + rb.getName());
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "INT fails to meet Rune Minimum --> " + rb.getName());
|
||||
case MBServerStatics.RUNE_SPI_MIN_NEEDED_ATTRIBUTE_ID:
|
||||
|
||||
if (spiCur >= value)
|
||||
continue;
|
||||
|
||||
Logger.info("SPI fails to meet Rune Minimum --> " + rb.getName());
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "SPI fails to meet Rune Minimum --> " + rb.getName());
|
||||
case MBServerStatics.RUNE_STR_ATTRIBUTE_ID:
|
||||
|
||||
if (value < 0)
|
||||
@@ -1082,12 +1072,20 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
continue;
|
||||
|
||||
default:
|
||||
Logger.info("Unknown ATTRIBUTE_ID while checking RuneBaseAttributes: " + attrID);
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Unknown ATTRIBUTE_ID while checking RuneBaseAttributes: " + attrID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checked before the penalties, as the client's +/- does (0xBAC140): Giant's Blood cuts a max below its stat
|
||||
if (strCur < 1 || dexCur < 1 || conCur < 1 || intCur < 1 || spiCur < 1) {
|
||||
return refuseCreation(a, clientConnection, "Attribute below 1");
|
||||
}
|
||||
|
||||
if (strCur > strMax || dexCur > dexMax || conCur > conMax || intCur > intMax || spiCur > spiMax) {
|
||||
return refuseCreation(a, clientConnection, "Attribute above racial maximum");
|
||||
}
|
||||
|
||||
// Add in all of the penalties.
|
||||
strCur += penalties.get("StrCur");
|
||||
strMax += penalties.get("StrMax");
|
||||
@@ -1102,22 +1100,10 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
int kitID = msg.getKit();
|
||||
|
||||
// get the correctKit
|
||||
int raceClassID = Kit.GetKitIDByRaceClass(raceID, baseClassID);
|
||||
ArrayList<Kit> allKits = Kit.RaceClassIDMap.get(raceClassID);
|
||||
|
||||
Kit kit = null;
|
||||
|
||||
for (Kit k : allKits) {
|
||||
if (k.getKitNumber() == kitID) {
|
||||
kit = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Kit kit = Kit.getKit(raceID, baseClassID, kitID);
|
||||
|
||||
if (kit == null) {
|
||||
Logger.info("Unable to find matching kitID: " + kitID);
|
||||
return null;
|
||||
return refuseCreation(a, clientConnection, "Unable to find matching kitID: " + kitID);
|
||||
}
|
||||
|
||||
byte runningTrains = 0;
|
||||
@@ -1270,7 +1256,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
player.endLoc = Vector3fImmutable.ZERO;
|
||||
|
||||
//get level based on experience
|
||||
player.level = (short) Experience.getLevel(player.exp);
|
||||
player.level = (short) Experience.getLevel(player, player.exp);
|
||||
|
||||
player.setHealth(999999f);
|
||||
player.mana.set(999999f);
|
||||
@@ -1353,10 +1339,10 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
public static float getDexPenalty(Item armor) {
|
||||
if (armor == null)
|
||||
return 0f;
|
||||
ItemTemplate ab = armor.template;
|
||||
CObjectTemplate ab = armor.template;
|
||||
if (ab == null)
|
||||
return 0f;
|
||||
return ab.item_bulk_factor;
|
||||
return engine.parsers.objects.ItemTemplate._items.get(armor.templateID).item_bulk_factor;
|
||||
}
|
||||
|
||||
public static void InitializeSkillsOnLoad(PlayerCharacter pc) {
|
||||
@@ -2816,22 +2802,22 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
if (item == null)
|
||||
return false;
|
||||
|
||||
ItemTemplate ib = item.template;
|
||||
CObjectTemplate ib = item.template;
|
||||
if (ib != null) {
|
||||
|
||||
if ((item.template.item_type.equals(ItemType.WEAPON))
|
||||
&& (item.template.item_skill_used.equals(type) || ib.item_skill_mastery_used.equals(type)))
|
||||
if ((item.template.getItemType().equals(ItemType.WEAPON))
|
||||
&& (item.template.getItemSkillUsed().equals(type) || ib.getItemSkillMasteryUsed().equals(type)))
|
||||
return true;
|
||||
|
||||
return (item.template.item_type.equals(ItemType.ARMOR))
|
||||
&& (item.template.item_skill_used.equals(type));
|
||||
return (item.template.getItemType().equals(ItemType.ARMOR))
|
||||
&& (item.template.getItemSkillUsed().equals(type));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public short getPCLevel() {
|
||||
short level = (short) Experience.getLevel(this.exp);
|
||||
short level = (short) Experience.getLevel(this, this.exp);
|
||||
if (this.promotionClass == null && level >= 10)
|
||||
return (short) 10;
|
||||
|
||||
@@ -2876,8 +2862,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
public synchronized void grantXP(int xp) {
|
||||
// Stop players from getting experience past the cap
|
||||
if (this.exp + xp >= Experience.getBaseExperience(MBServerStatics.LEVELCAP))
|
||||
xp = Experience.getBaseExperience(MBServerStatics.LEVELCAP) - this.exp + 1;
|
||||
if (this.exp + xp >= Experience.getBaseExperience(this, MBServerStatics.LEVELCAP))
|
||||
xp = Experience.getBaseExperience(this, MBServerStatics.LEVELCAP) - this.exp + 1;
|
||||
|
||||
if (xp == 0)
|
||||
xp = 1;
|
||||
@@ -2893,7 +2879,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
//not promoted at level 10, start checking for negative EXP
|
||||
if (this.promotionClass == null && this.getLevel() == 10) {
|
||||
|
||||
if (this.getExp() == Experience.getBaseExperience(11)) {
|
||||
if (this.getExp() == Experience.getBaseExperience(this, 11)) {
|
||||
if (this.overFlowEXP == 110000)
|
||||
return;
|
||||
|
||||
@@ -2916,10 +2902,10 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
} else {
|
||||
|
||||
//Player exp begins negative exp, add remaing exp after level 11 to overflow
|
||||
if (this.getExp() + remainingXP >= Experience.getBaseExperience(11)) {
|
||||
if (this.getExp() + remainingXP >= Experience.getBaseExperience(this, 11)) {
|
||||
|
||||
this.overFlowEXP = remainingXP - (Experience.getBaseExperience(11) - this.getExp());
|
||||
this.exp = Experience.getBaseExperience(11);
|
||||
this.overFlowEXP = remainingXP - (Experience.getBaseExperience(this, 11) - this.getExp());
|
||||
this.exp = Experience.getBaseExperience(this, 11);
|
||||
|
||||
GrantExperienceMsg grantExperienceMsg = new GrantExperienceMsg(this, remainingXP);
|
||||
Dispatch dispatch = Dispatch.borrow(this, grantExperienceMsg);
|
||||
@@ -2951,7 +2937,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
else
|
||||
nextLevel = level + 2;
|
||||
|
||||
int nextLevelEXP = Experience.getBaseExperience(nextLevel);
|
||||
int nextLevelEXP = Experience.getBaseExperience(this, nextLevel);
|
||||
|
||||
// if overflow > 0, u have level 11 experience + overflow, but level is still 10 due to just promoting.
|
||||
//Use level + 2 experience for next level.
|
||||
@@ -2974,8 +2960,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
checkGuildStatus();
|
||||
this.addDatabaseJob("EXP", MBServerStatics.FIVE_MINUTES);
|
||||
// double overflow exp used up, remaining overflow will just add to level + 1.
|
||||
} else if (this.getExp() + this.overFlowEXP >= Experience.getBaseExperience(level + 1)) {
|
||||
int nextExperience = Experience.getBaseExperience(level + 1) + this.overFlowEXP;
|
||||
} else if (this.getExp() + this.overFlowEXP >= Experience.getBaseExperience(this, level + 1)) {
|
||||
int nextExperience = Experience.getBaseExperience(this, level + 1) + this.overFlowEXP;
|
||||
this.exp = nextExperience;
|
||||
this.level++;
|
||||
charReloadRequired = true;
|
||||
@@ -2991,10 +2977,10 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
|
||||
} else {
|
||||
// Hand out each Level one at a time.
|
||||
isNewLevel = Experience.getLevel(exp + remainingXP) > this.getLevel();
|
||||
isNewLevel = Experience.getLevel(this, exp + remainingXP) > this.getLevel();
|
||||
|
||||
if (isNewLevel) {
|
||||
neededXP = Experience.getBaseExperience(this.getLevel() + 1) - this.exp;
|
||||
neededXP = Experience.getBaseExperience(this, this.getLevel() + 1) - this.exp;
|
||||
|
||||
charReloadRequired = true;
|
||||
this.exp += neededXP;
|
||||
@@ -3768,8 +3754,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
ConcurrentHashMap<EquipSlotType, Item> equipped = this.charItemManager.getEquipped();
|
||||
Item off = equipped.get(EquipSlotType.LHELD);
|
||||
Item main = equipped.get(EquipSlotType.RHELD);
|
||||
ItemTemplate wbMain = null;
|
||||
ItemTemplate wbOff = null;
|
||||
CObjectTemplate wbMain = null;
|
||||
CObjectTemplate wbOff = null;
|
||||
if (main != null)
|
||||
wbMain = main.template;
|
||||
if (off != null)
|
||||
@@ -3791,8 +3777,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
this.bonuses.setBool(ModType.Parry, SourceType.None, false);
|
||||
if ((this.baseClass != null && this.baseClass.getObjectUUID() == 2500)
|
||||
|| (this.promotionClass != null && this.promotionClass.getObjectUUID() == 2520))
|
||||
if (wbMain == null || wbMain.item_weapon_max_range < MBServerStatics.RANGED_WEAPON_RANGE)
|
||||
if (wbOff == null || wbOff.item_weapon_max_range < MBServerStatics.RANGED_WEAPON_RANGE)
|
||||
if (wbMain == null || engine.parsers.objects.ItemTemplate.getWeapon(wbMain.getTemplateId()).weapon_max_range < MBServerStatics.RANGED_WEAPON_RANGE)
|
||||
if (wbOff == null || engine.parsers.objects.ItemTemplate.getWeapon(wbOff.getTemplateId()).weapon_max_range < MBServerStatics.RANGED_WEAPON_RANGE)
|
||||
this.bonuses.setBool(ModType.Parry, SourceType.None, true);
|
||||
|
||||
}
|
||||
@@ -4091,7 +4077,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
||||
tmpLevel = (short) Math.min(tmpLevel, 75);
|
||||
|
||||
while (this.level < tmpLevel) {
|
||||
grantXP(Experience.getBaseExperience(tmpLevel) - this.exp);
|
||||
grantXP(Experience.getBaseExperience(this, tmpLevel) - this.exp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,31 +9,25 @@
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.util.Hasher;
|
||||
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.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class PowerGrant extends AbstractGameObject {
|
||||
public class PowerGrantedTrains {
|
||||
|
||||
private static ConcurrentHashMap<Integer, PowerGrant> grantedPowers = null;
|
||||
private static ConcurrentHashMap<Integer, PowerGrantedTrains> grantedPowers = null;
|
||||
private int token;
|
||||
private ConcurrentHashMap<Integer, Short> runeGrants = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public PowerGrant(ResultSet rs) throws SQLException {
|
||||
super();
|
||||
this.token = rs.getInt("powerToken");
|
||||
runeGrants.put(rs.getInt("runeID"), rs.getShort("grantAmount"));
|
||||
public PowerGrantedTrains(int token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -44,11 +38,11 @@ public class PowerGrant extends AbstractGameObject {
|
||||
if (pc == null)
|
||||
return (short) 0;
|
||||
|
||||
if (PowerGrant.grantedPowers == null)
|
||||
fillGrantedPowers();
|
||||
if (PowerGrantedTrains.grantedPowers == null)
|
||||
loadGrantedPowers();
|
||||
|
||||
if (PowerGrant.grantedPowers.containsKey(token)) {
|
||||
PowerGrant pg = PowerGrant.grantedPowers.get(token);
|
||||
if (PowerGrantedTrains.grantedPowers.containsKey(token)) {
|
||||
PowerGrantedTrains pg = PowerGrantedTrains.grantedPowers.get(token);
|
||||
ConcurrentHashMap<Integer, Short> runeGrants = pg.runeGrants;
|
||||
ArrayList<Integer> toks = new ArrayList<>();
|
||||
|
||||
@@ -88,39 +82,33 @@ public class PowerGrant extends AbstractGameObject {
|
||||
return (short) 0;
|
||||
}
|
||||
|
||||
public static void fillGrantedPowers() {
|
||||
// Trains are power_arguments[0] of the first action. Mob race runes are skipped:
|
||||
// their power actions are mob power ranks by level, not trains.
|
||||
public static void loadGrantedPowers() {
|
||||
|
||||
PowerGrant.grantedPowers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
ConcurrentHashMap<Integer, PowerGrantedTrains> powerGrants = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
int token;
|
||||
int grantCount = 0;
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_power_powergrant")) {
|
||||
for (RuneTemplate rune : RuneTemplate._runes.values()) {
|
||||
|
||||
if (rune.rune_type == mbEnums.RuneType.RACE && Race.getRace(rune.template_id) == null)
|
||||
continue;
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
for (Map.Entry<String, ArrayList<int[]>> powerAction : rune.item_power_action.entrySet()) {
|
||||
|
||||
if (PowerGrant.grantedPowers.size() > 0) {
|
||||
rs.close();
|
||||
return;
|
||||
if (powerAction.getValue().isEmpty())
|
||||
continue;
|
||||
|
||||
token = Hasher.SBStringHash(powerAction.getKey());
|
||||
powerGrants.computeIfAbsent(token, PowerGrantedTrains::new)
|
||||
.addRuneGrant(rune.template_id, (short) powerAction.getValue().get(0)[0]);
|
||||
grantCount++;
|
||||
}
|
||||
|
||||
while (rs.next()) {
|
||||
|
||||
int token = rs.getInt("powerToken");
|
||||
|
||||
PowerGrant pg;
|
||||
|
||||
if (PowerGrant.grantedPowers.containsKey(token)) {
|
||||
pg = PowerGrant.grantedPowers.get(token);
|
||||
pg.addRuneGrant(rs.getInt("runeID"), rs.getShort("grantAmount"));
|
||||
} else {
|
||||
pg = new PowerGrant(rs);
|
||||
PowerGrant.grantedPowers.put(token, pg);
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
} catch (SQLException e) {
|
||||
Logger.error("SQL Error number: " + e.getErrorCode(), e);
|
||||
}
|
||||
|
||||
PowerGrantedTrains.grantedPowers = powerGrants;
|
||||
Logger.info("Loaded " + grantCount + " power train grants for " + powerGrants.size() + " powers");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -134,8 +122,4 @@ public class PowerGrant extends AbstractGameObject {
|
||||
private void addRuneGrant(int runeID, short amount) {
|
||||
this.runeGrants.put(runeID, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
}
|
||||
}
|
||||
@@ -9,18 +9,17 @@
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.PowersManager;
|
||||
import engine.parsers.objects.PowerGrant;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.powers.PowersBase;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.util.Hasher;
|
||||
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.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
@@ -32,7 +31,7 @@ public class PowerReq extends AbstractGameObject implements Comparable<PowerReq>
|
||||
private short level;
|
||||
private ConcurrentHashMap<Integer, Byte> powerReqs;
|
||||
private ConcurrentHashMap<Integer, Byte> skillReqs;
|
||||
private static ConcurrentHashMap<Integer, ArrayList<PowerReq>> runePowers = fillRunePowers();
|
||||
private static ConcurrentHashMap<Integer, ArrayList<PowerReq>> runePowers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
@@ -64,81 +63,52 @@ public class PowerReq extends AbstractGameObject implements Comparable<PowerReq>
|
||||
this.token = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public PowerReq(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
this.token = rs.getInt("powerToken");
|
||||
public PowerReq(PowerGrant powerGrant) {
|
||||
super();
|
||||
this.token = Hasher.SBStringHash(powerGrant.power_type);
|
||||
this.powersBase = PowersManager.getPowerByToken(this.token);
|
||||
this.level = rs.getShort("level");
|
||||
int type = rs.getInt("type");
|
||||
this.level = (short) powerGrant.power_value;
|
||||
this.powerReqs = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
this.skillReqs = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
if (type == 1)
|
||||
this.skillReqs.put(rs.getInt("requiredToken"), rs.getByte("requiredAmount"));
|
||||
else if (type == 2)
|
||||
this.powerReqs.put(rs.getInt("requiredToken"), rs.getByte("requiredAmount"));
|
||||
|
||||
for (Map.Entry<String, Integer> entry : powerGrant.power_granted_powers.entrySet())
|
||||
this.powerReqs.put(Hasher.SBStringHash(entry.getKey()), entry.getValue().byteValue());
|
||||
|
||||
for (Map.Entry<String, Integer> entry : powerGrant.power_granted_skills.entrySet())
|
||||
this.skillReqs.put(Hasher.SBStringHash(entry.getKey()), entry.getValue().byteValue());
|
||||
}
|
||||
|
||||
public static ArrayList<PowerReq> getPowerReqsForRune(int id) {
|
||||
// if (PowerReq.runePowers == null)
|
||||
// fillRunePowers();
|
||||
if (PowerReq.runePowers.containsKey(id))
|
||||
return PowerReq.runePowers.get(id);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public static ConcurrentHashMap<Integer, ArrayList<PowerReq>> fillRunePowers() {
|
||||
// item_power_grant power_value is the level the power unlocks at
|
||||
public static void loadRunePowers() {
|
||||
|
||||
ArrayList<PowerReq> runePR;
|
||||
int entryCount = 0;
|
||||
|
||||
PowerReq.runePowers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
try (Connection connection = DbManager.getConnection();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_power_powerrequirement")) {
|
||||
for (RuneTemplate rune : RuneTemplate._runes.values()) {
|
||||
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
if (rune.item_power_grant.isEmpty())
|
||||
continue;
|
||||
|
||||
if (PowerReq.runePowers.size() > 0) {
|
||||
return PowerReq.runePowers;
|
||||
}
|
||||
runePR = new ArrayList<>();
|
||||
|
||||
while (rs.next()) {
|
||||
ArrayList<PowerReq> runePR = null;
|
||||
int runeID = rs.getInt("runeID");
|
||||
int token = rs.getInt("powerToken");
|
||||
if (PowerReq.runePowers.containsKey(runeID))
|
||||
runePR = PowerReq.runePowers.get(runeID);
|
||||
else {
|
||||
runePR = new ArrayList<>();
|
||||
PowerReq.runePowers.put(runeID, runePR);
|
||||
}
|
||||
boolean found = false;
|
||||
for (PowerReq pr : runePR) {
|
||||
if (pr.token == token) {
|
||||
int type = rs.getInt("type");
|
||||
if (type == 1)
|
||||
pr.addSkill(rs.getInt("requiredToken"), rs.getByte("requiredAmount"));
|
||||
else
|
||||
pr.addPower(rs.getInt("requiredToken"), rs.getByte("requiredAmount"));
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
PowerReq pr = new PowerReq(rs);
|
||||
runePR.add(pr);
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
for (PowerGrant powerGrant : rune.item_power_grant)
|
||||
runePR.add(new PowerReq(powerGrant));
|
||||
|
||||
//order the lists by level so prerequisites are met
|
||||
for (ArrayList<PowerReq> runePR : PowerReq.runePowers.values()) {
|
||||
Collections.sort(runePR);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Logger.error("SQL Error number: " + e.getErrorCode(), e);
|
||||
//order the list by level so prerequisites are met
|
||||
Collections.sort(runePR);
|
||||
PowerReq.runePowers.put(rune.template_id, runePR);
|
||||
entryCount += runePR.size();
|
||||
}
|
||||
|
||||
return PowerReq.runePowers;
|
||||
Logger.info("Loaded " + entryCount + " power requirements for " + PowerReq.runePowers.size() + " runes");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -167,14 +137,6 @@ public class PowerReq extends AbstractGameObject implements Comparable<PowerReq>
|
||||
return this.token;
|
||||
}
|
||||
|
||||
private void addPower(int token, byte amount) {
|
||||
this.powerReqs.put(token, amount);
|
||||
}
|
||||
|
||||
private void addSkill(int token, byte amount) {
|
||||
this.skillReqs.put(token, amount);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Database
|
||||
|
||||
@@ -10,8 +10,13 @@
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.mbEnums.GameObjectType;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.parsers.cache.CObjectIndex;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.util.Hasher;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@@ -28,11 +33,6 @@ public class PromotionClass extends AbstractGameObject {
|
||||
private final ArrayList<Integer> allowedRunes;
|
||||
private final ArrayList<SkillReq> skillsGranted;
|
||||
private final ArrayList<PowerReq> powersGranted;
|
||||
private final ArrayList<RuneBaseEffect> effectsGranted;
|
||||
private final ArrayList<RuneBaseEffect> effectsGrantedFighter;
|
||||
private final ArrayList<RuneBaseEffect> effectsGrantedHealer;
|
||||
private final ArrayList<RuneBaseEffect> effectsGrantedRogue;
|
||||
private final ArrayList<RuneBaseEffect> effectsGrantedMage;
|
||||
private int token = 0;
|
||||
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
||||
|
||||
@@ -50,11 +50,6 @@ public class PromotionClass extends AbstractGameObject {
|
||||
this.healthMod = 0f;
|
||||
this.manaMod = 0f;
|
||||
this.staminaMod = 0f;
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
this.effectsGrantedFighter = new ArrayList<>();
|
||||
this.effectsGrantedHealer = new ArrayList<>();
|
||||
this.effectsGrantedRogue = new ArrayList<>();
|
||||
this.effectsGrantedMage = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,15 +66,11 @@ public class PromotionClass extends AbstractGameObject {
|
||||
this.healthMod = 0f;
|
||||
this.manaMod = 0f;
|
||||
this.staminaMod = 0f;
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
this.effectsGrantedFighter = new ArrayList<>();
|
||||
this.effectsGrantedHealer = new ArrayList<>();
|
||||
this.effectsGrantedRogue = new ArrayList<>();
|
||||
this.effectsGrantedMage = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
* Only the CSR/admin rows 2901+ load from the DB; they have no promotion rune and allow no runes.
|
||||
*/
|
||||
public PromotionClass(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
@@ -90,19 +81,82 @@ public class PromotionClass extends AbstractGameObject {
|
||||
this.healthMod = rs.getFloat("healthMod");
|
||||
this.manaMod = rs.getFloat("manaMod");
|
||||
this.staminaMod = rs.getFloat("staminaMod");
|
||||
this.allowedRunes = DbManager.PromotionQueries.GET_ALLOWED_RUNES(this);
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.getObjectUUID());
|
||||
this.allowedRunes = new ArrayList<>();
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.getObjectUUID());
|
||||
this.effectsGrantedFighter = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2500);
|
||||
this.effectsGrantedHealer = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2501);
|
||||
this.effectsGrantedRogue = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2502);
|
||||
this.effectsGrantedMage = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2503);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID());
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(this.getObjectUUID());
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Rune Template Constructor
|
||||
*/
|
||||
public PromotionClass(RuneTemplate rune) {
|
||||
super(rune.template_id);
|
||||
|
||||
this.name = rune.obj_name;
|
||||
this.description = rune.rune_dsc;
|
||||
this.token = Hasher.SBStringHash(rune.rune_sub_type);
|
||||
this.healthMod = rune.rune_health;
|
||||
this.manaMod = rune.rune_mana;
|
||||
this.staminaMod = rune.rune_stamina;
|
||||
this.allowedRunes = getAllowedRuneTokens(rune);
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(this.getObjectUUID());
|
||||
}
|
||||
|
||||
// Promotions are the CLASS runes that require a base class; this skips the creation classes and Pet 2522.
|
||||
|
||||
public static boolean isPromotionRune(RuneTemplate rune) {
|
||||
return rune.rune_type == mbEnums.RuneType.CLASS && !rune.rune_is_standard_character_creation
|
||||
&& !rune.item_class_req.isEmpty();
|
||||
}
|
||||
|
||||
// Race and base class tokens are SBStringHash(rune_sub_type) of the runes named in the req lists.
|
||||
// Every promotion rune's lists are whitelists (restrict false).
|
||||
|
||||
private static ArrayList<Integer> getAllowedRuneTokens(RuneTemplate rune) {
|
||||
|
||||
ArrayList<Integer> tokens = new ArrayList<>();
|
||||
Integer classRuneId;
|
||||
int token;
|
||||
|
||||
for (mbEnums.MonsterType race : rune.item_race_req)
|
||||
for (int raceRuneId : CObjectIndex.getRaceRuneIds(race)) {
|
||||
token = Hasher.SBStringHash(RuneTemplate._runes.get(raceRuneId).rune_sub_type);
|
||||
if (!tokens.contains(token))
|
||||
tokens.add(token);
|
||||
}
|
||||
|
||||
for (mbEnums.ClassType classType : rune.item_class_req) {
|
||||
classRuneId = CObjectIndex.getClassRuneId(classType);
|
||||
if (classRuneId != null)
|
||||
tokens.add(Hasher.SBStringHash(RuneTemplate._runes.get(classRuneId).rune_sub_type));
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
public static void LoadAllPromotions() {
|
||||
|
||||
int loadedCount = 0;
|
||||
|
||||
for (RuneTemplate rune : RuneTemplate._runes.values()) {
|
||||
if (!isPromotionRune(rune))
|
||||
continue;
|
||||
|
||||
DbManager.addToCache(new PromotionClass(rune));
|
||||
loadedCount++;
|
||||
}
|
||||
|
||||
Logger.info("Loaded " + loadedCount + " promotion classes from runes");
|
||||
|
||||
// The CSR/admin rows 2901+ have no promotion rune; the DB loader skips ids already cached
|
||||
DbManager.PromotionQueries.GET_ALL_PROMOTIONS();
|
||||
}
|
||||
|
||||
public static void serializeForClientMsg(PromotionClass promotionClass, ByteBufferWriter writer) {
|
||||
writer.putInt(3); // For BaseClass
|
||||
writer.putInt(0); // Pad
|
||||
@@ -169,23 +223,6 @@ public class PromotionClass extends AbstractGameObject {
|
||||
* Serializing
|
||||
*/
|
||||
|
||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
||||
return this.effectsGranted;
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseEffect> getEffectsGranted(int baseClassID) {
|
||||
if (baseClassID == 2500)
|
||||
return this.effectsGrantedFighter;
|
||||
else if (baseClassID == 2501)
|
||||
return this.effectsGrantedHealer;
|
||||
else if (baseClassID == 2502)
|
||||
return this.effectsGrantedRogue;
|
||||
else if (baseClassID == 2503)
|
||||
return this.effectsGrantedMage;
|
||||
else
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
// TODO Create update logic.
|
||||
|
||||
+101
-45
@@ -11,14 +11,18 @@ package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.mbEnums.RaceType;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.parsers.cache.CacheParserUtil;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.util.Hasher;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class Race {
|
||||
@@ -27,6 +31,9 @@ public class Race {
|
||||
|
||||
private static ConcurrentHashMap<Integer, Race> _raceByID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
// Creation points before the race rune's rune_creation_cost is taken off
|
||||
private static final int STARTING_POINT_POOL = 30;
|
||||
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final int raceRuneID;
|
||||
@@ -64,57 +71,114 @@ public class Race {
|
||||
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
* Rune Template Constructor
|
||||
* minHeight and strHeightMod are server-only and come from the static_rune_race row.
|
||||
*/
|
||||
public Race(ResultSet rs) throws SQLException {
|
||||
public Race(RuneTemplate rune, float[] heights) {
|
||||
|
||||
this.raceRuneID = rs.getInt("ID");
|
||||
this.raceRuneID = rune.template_id;
|
||||
this.raceType = mbEnums.RaceType.getRaceTypebyRuneID(raceRuneID);
|
||||
this.name = rs.getString("name");
|
||||
this.description = rs.getString("description");
|
||||
this.strStart = rs.getShort("strStart");
|
||||
this.strMin = rs.getShort("strMin");
|
||||
this.strMax = rs.getShort("strMax");
|
||||
this.dexStart = rs.getShort("dexStart");
|
||||
this.dexMin = rs.getShort("dexMin");
|
||||
this.dexMax = rs.getShort("dexMax");
|
||||
this.conStart = rs.getShort("conStart");
|
||||
this.conMin = rs.getShort("conMin");
|
||||
this.conMax = rs.getShort("conMax");
|
||||
this.intStart = rs.getShort("intStart");
|
||||
this.intMin = rs.getShort("intMin");
|
||||
this.intMax = rs.getShort("intMax");
|
||||
this.spiStart = rs.getShort("spiStart");
|
||||
this.spiMin = rs.getShort("spiMin");
|
||||
this.spiMax = rs.getShort("spiMax");
|
||||
this.token = rs.getInt("token");
|
||||
this.healthBonus = rs.getShort("healthBonus");
|
||||
this.manaBonus = rs.getShort("manaBonus");
|
||||
this.staminaBonus = rs.getShort("staminaBonus");
|
||||
this.startingPoints = rs.getByte("startingPoints");
|
||||
this.raceType = RaceType.getRaceTypebyRuneID(this.raceRuneID);
|
||||
this.minHeight = rs.getFloat("minHeight");
|
||||
this.strHeightMod = rs.getFloat("strHeightMod");
|
||||
this.hairStyles = DbManager.RaceQueries.HAIR_STYLES_FOR_RACE(raceRuneID);
|
||||
this.beardStyles = DbManager.RaceQueries.BEARD_STYLES_FOR_RACE(raceRuneID);
|
||||
this.name = rune.obj_name;
|
||||
this.description = rune.rune_dsc;
|
||||
this.strStart = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Strength, 0).shortValue();
|
||||
this.strMin = 0;
|
||||
this.strMax = rune.rune_max_attr_adj.getOrDefault(mbEnums.AttributeType.Strength, 0).shortValue();
|
||||
this.dexStart = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Dexterity, 0).shortValue();
|
||||
this.dexMin = 0;
|
||||
this.dexMax = rune.rune_max_attr_adj.getOrDefault(mbEnums.AttributeType.Dexterity, 0).shortValue();
|
||||
this.conStart = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Constitution, 0).shortValue();
|
||||
this.conMin = 0;
|
||||
this.conMax = rune.rune_max_attr_adj.getOrDefault(mbEnums.AttributeType.Constitution, 0).shortValue();
|
||||
this.intStart = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Intelligence, 0).shortValue();
|
||||
this.intMin = 0;
|
||||
this.intMax = rune.rune_max_attr_adj.getOrDefault(mbEnums.AttributeType.Intelligence, 0).shortValue();
|
||||
this.spiStart = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Spirit, 0).shortValue();
|
||||
this.spiMin = 0;
|
||||
this.spiMax = rune.rune_max_attr_adj.getOrDefault(mbEnums.AttributeType.Spirit, 0).shortValue();
|
||||
this.token = Hasher.SBStringHash(rune.rune_sub_type);
|
||||
this.healthBonus = (short) rune.rune_health;
|
||||
this.manaBonus = (short) rune.rune_mana;
|
||||
this.staminaBonus = (short) rune.rune_stamina;
|
||||
this.startingPoints = (byte) (STARTING_POINT_POOL - rune.rune_creation_cost);
|
||||
this.minHeight = heights[0];
|
||||
this.strHeightMod = heights[1];
|
||||
this.hairStyles = new HashSet<>(rune.rune_hair);
|
||||
this.beardStyles = new HashSet<>(rune.rune_beard);
|
||||
this.skinColors = DbManager.RaceQueries.SKIN_COLOR_FOR_RACE(raceRuneID);
|
||||
this.beardColors = DbManager.RaceQueries.BEARD_COLORS_FOR_RACE(raceRuneID);
|
||||
this.hairColors = DbManager.RaceQueries.HAIR_COLORS_FOR_RACE(raceRuneID);
|
||||
this.baseClasses = DbManager.BaseClassQueries.GET_BASECLASS_FOR_RACE(raceRuneID);
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(raceRuneID);
|
||||
this.baseClasses = getBaseClassesForRace(rune);
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(raceRuneID);
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(raceRuneID);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.raceRuneID);
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(this.raceRuneID);
|
||||
|
||||
// Races without hair styles (Aracoix, Shade) select style 0, which creation validates
|
||||
if (this.hairStyles.isEmpty())
|
||||
this.hairStyles.add(0);
|
||||
}
|
||||
|
||||
// Base classes are the creation class runes whose item_race_req names this race's sub type.
|
||||
// Every creation class rune's race list is a whitelist (restrict false).
|
||||
|
||||
private static ArrayList<BaseClass> getBaseClassesForRace(RuneTemplate rune) {
|
||||
|
||||
ArrayList<BaseClass> baseClasses = new ArrayList<>();
|
||||
mbEnums.MonsterType monsterType;
|
||||
BaseClass baseClass;
|
||||
|
||||
monsterType = CacheParserUtil.readEnum(mbEnums.MonsterType.class, rune.rune_sub_type, rune.template_id, "rune_sub_type");
|
||||
|
||||
for (RuneTemplate classRune : RuneTemplate._runes.values()) {
|
||||
if (classRune.rune_type != mbEnums.RuneType.CLASS || !classRune.rune_is_standard_character_creation)
|
||||
continue;
|
||||
|
||||
if (!classRune.item_race_req.contains(monsterType))
|
||||
continue;
|
||||
|
||||
baseClass = DbManager.BaseClassQueries.GET_BASE_CLASS(classRune.template_id);
|
||||
|
||||
if (baseClass != null)
|
||||
baseClasses.add(baseClass);
|
||||
}
|
||||
|
||||
return baseClasses;
|
||||
}
|
||||
|
||||
// Iterates the static_rune_race rows: no rune field separates 2018-2021 from the mob race runes,
|
||||
// and each row still holds the server-only heights.
|
||||
|
||||
public static void loadAllRaces() {
|
||||
Race._raceByID = DbManager.RaceQueries.LOAD_ALL_RACES();
|
||||
|
||||
HashMap<Integer, float[]> raceHeights;
|
||||
ConcurrentHashMap<Integer, Race> races;
|
||||
RuneTemplate rune;
|
||||
|
||||
raceHeights = DbManager.RaceQueries.LOAD_RACE_HEIGHTS();
|
||||
races = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
for (Map.Entry<Integer, float[]> raceRow : raceHeights.entrySet()) {
|
||||
rune = RuneTemplate._runes.get(raceRow.getKey());
|
||||
|
||||
if (rune == null || rune.rune_type != mbEnums.RuneType.RACE) {
|
||||
Logger.warn("Race " + raceRow.getKey() + " in static_rune_race has no race rune; skipped");
|
||||
continue;
|
||||
}
|
||||
|
||||
races.put(rune.template_id, new Race(rune, raceRow.getValue()));
|
||||
}
|
||||
|
||||
Race._raceByID = races;
|
||||
Logger.info("Loaded " + races.size() + " races from runes");
|
||||
}
|
||||
|
||||
public static Race getRace(int id) {
|
||||
return _raceByID.get(id);
|
||||
}
|
||||
|
||||
public static Collection<Race> getAllRaces() {
|
||||
return _raceByID.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
|
||||
@@ -258,10 +322,6 @@ public class Race {
|
||||
return this.powersGranted;
|
||||
}
|
||||
|
||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
||||
return RuneBaseEffect.RuneIDBaseEffectMap.get(this.raceRuneID);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validators
|
||||
*/
|
||||
@@ -290,10 +350,6 @@ public class Race {
|
||||
if (this.getAllowedRunes() != null)
|
||||
if (this.getAllowedRunes().contains(rb.getObjectUUID()))
|
||||
return true;
|
||||
if (RuneBase.AllowedBaseClassRunesMap.containsKey(111111)) {
|
||||
if (RuneBase.AllowedRaceRunesMap.get(111111).contains(rb.getObjectUUID()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,22 +10,19 @@
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.mbEnums.ModType;
|
||||
import engine.mbEnums.SourceType;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class Resists {
|
||||
|
||||
private static ConcurrentHashMap<Integer, Resists> mobResists = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private ConcurrentHashMap<mbEnums.DamageType, Float> resists = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private ConcurrentHashMap<mbEnums.DamageType, Boolean> immuneTo = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private mbEnums.DamageType protection;
|
||||
@@ -78,26 +75,6 @@ public class Resists {
|
||||
setGenericResists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Database Constructor
|
||||
*/
|
||||
public Resists(ResultSet rs) throws SQLException {
|
||||
this.immuneToAll = false;
|
||||
this.resists.put(mbEnums.DamageType.SLASHING, rs.getFloat("slash"));
|
||||
this.resists.put(mbEnums.DamageType.CRUSHING, rs.getFloat("crush"));
|
||||
this.resists.put(mbEnums.DamageType.PIERCING, rs.getFloat("pierce"));
|
||||
this.resists.put(mbEnums.DamageType.MAGIC, rs.getFloat("magic"));
|
||||
this.resists.put(mbEnums.DamageType.BLEEDING, rs.getFloat("bleed"));
|
||||
this.resists.put(mbEnums.DamageType.POISON, rs.getFloat("poison"));
|
||||
this.resists.put(mbEnums.DamageType.MENTAL, rs.getFloat("mental"));
|
||||
this.resists.put(mbEnums.DamageType.HOLY, rs.getFloat("holy"));
|
||||
this.resists.put(mbEnums.DamageType.UNHOLY, rs.getFloat("unholy"));
|
||||
this.resists.put(mbEnums.DamageType.LIGHTNING, rs.getFloat("lightning"));
|
||||
this.resists.put(mbEnums.DamageType.FIRE, rs.getFloat("fire"));
|
||||
this.resists.put(mbEnums.DamageType.COLD, rs.getFloat("cold"));
|
||||
this.resists.put(mbEnums.DamageType.HEALING, 0f);
|
||||
}
|
||||
|
||||
//Handle Fortitudes
|
||||
private static float handleFortitude(AbstractCharacter target, mbEnums.DamageType type, float damage) {
|
||||
if (target == null || !(target.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)))
|
||||
@@ -159,37 +136,21 @@ public class Resists {
|
||||
|
||||
private static float[] getArmorResists(Item armor, float[] phys) {
|
||||
|
||||
EnumMap<mbEnums.DamageType, Float> armorResists;
|
||||
|
||||
if (armor == null)
|
||||
return phys;
|
||||
|
||||
if (armor.template.item_type.equals(mbEnums.ItemType.ARMOR)) {
|
||||
phys[0] += armor.template.combat_attack_resist.get("SLASHING");
|
||||
phys[1] += armor.template.combat_attack_resist.get("CRUSHING");
|
||||
phys[2] += armor.template.combat_attack_resist.get("PIERCING");
|
||||
if (armor.template.getItemType().equals(mbEnums.ItemType.ARMOR)) {
|
||||
armorResists = armor.template.getCombatAttackResist();
|
||||
phys[0] += armorResists.getOrDefault(mbEnums.DamageType.SLASHING, 0f);
|
||||
phys[1] += armorResists.getOrDefault(mbEnums.DamageType.CRUSHING, 0f);
|
||||
phys[2] += armorResists.getOrDefault(mbEnums.DamageType.PIERCING, 0f);
|
||||
}
|
||||
|
||||
return phys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mob resists from db if there, otherwise set defaults
|
||||
*/
|
||||
public static Resists getResists(int resistID) {
|
||||
//check cache first
|
||||
if (mobResists.containsKey(resistID))
|
||||
return new Resists(mobResists.get(resistID));
|
||||
|
||||
//get from database
|
||||
Resists resists = DbManager.ResistQueries.GET_RESISTS_FOR_MOB(resistID);
|
||||
if (resists != null) {
|
||||
mobResists.put(resistID, resists);
|
||||
return new Resists(resists);
|
||||
}
|
||||
|
||||
//failed, may want to debug this
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create generic resists for buildings
|
||||
*/
|
||||
@@ -310,14 +271,6 @@ public class Resists {
|
||||
this.immuneToAll = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* set resists from mobbase
|
||||
*/
|
||||
public void setMobResists(int resistID) {
|
||||
//TODO add this in later
|
||||
//calls `static_npc_mob_resists` table WHERE `ID`='resistID'
|
||||
}
|
||||
|
||||
/**
|
||||
* get Damage after resist
|
||||
* Expects heals as negative damage and damage as positive damage for fortitudes.
|
||||
|
||||
@@ -11,11 +11,13 @@ package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.mbEnums;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.parsers.cache.CObjectIndex;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.parsers.objects.wpak.CharCreateRuneList;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.util.Hasher;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -27,55 +29,83 @@ public class RuneBase extends AbstractGameObject {
|
||||
public static HashMap<Integer, ArrayList<Integer>> AllowedRaceRunesMap = new HashMap<>();
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final int type;
|
||||
private final byte subtype;
|
||||
private final ConcurrentHashMap<Integer, Boolean> race = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private final ConcurrentHashMap<Integer, Boolean> baseClass = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private final ConcurrentHashMap<Integer, Boolean> promotionClass = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private final ConcurrentHashMap<Integer, Boolean> discipline = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
private final ArrayList<Integer> overwrite = new ArrayList<>();
|
||||
private int levelRequired = 1;
|
||||
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
||||
private mbEnums.RuneType runeType;
|
||||
private int subTypeToken;
|
||||
private int rank;
|
||||
private boolean raceRestrict;
|
||||
private boolean classRestrict;
|
||||
private boolean discRestrict;
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
* Rune Template Constructor
|
||||
* Talents with the same sub type token replace each other by rank (client 0x4695D0), so no overwrite list.
|
||||
*/
|
||||
public RuneBase(String name, String description, int type, byte subtype, ArrayList<RuneBaseAttribute> attrs) {
|
||||
super();
|
||||
public RuneBase(RuneTemplate rune) {
|
||||
super(rune.template_id);
|
||||
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.type = type;
|
||||
this.subtype = subtype;
|
||||
Integer classRuneID;
|
||||
Integer discRuneID;
|
||||
ArrayList<Integer> raceRuneIDs;
|
||||
RuneTemplate classRune;
|
||||
|
||||
}
|
||||
this.name = rune.item_base_name;
|
||||
this.description = rune.rune_dsc;
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(rune.template_id);
|
||||
this.runeType = rune.rune_type;
|
||||
this.rank = rune.rune_rank;
|
||||
this.levelRequired = rune.item_level_req;
|
||||
this.raceRestrict = rune.item_race_req_restrict;
|
||||
this.classRestrict = rune.item_class_req_restrict;
|
||||
this.discRestrict = rune.item_disc_req_restrict;
|
||||
|
||||
/**
|
||||
* Normal Constructor
|
||||
*/
|
||||
public RuneBase(String name, String description, int type, byte subtype, ArrayList<RuneBaseAttribute> attrs, int newUUID) {
|
||||
super(newUUID);
|
||||
for (mbEnums.MonsterType raceType : rune.item_race_req) {
|
||||
raceRuneIDs = CObjectIndex.getRaceRuneIds(raceType);
|
||||
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.type = type;
|
||||
this.subtype = subtype;
|
||||
if (raceRuneIDs.isEmpty())
|
||||
Logger.warn("RuneBase " + rune.template_id + ": race " + raceType + " has no race rune");
|
||||
|
||||
}
|
||||
for (int raceRuneID : raceRuneIDs)
|
||||
this.race.put(raceRuneID, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Constructor
|
||||
*/
|
||||
public RuneBase(ResultSet rs) throws SQLException {
|
||||
super(rs);
|
||||
for (mbEnums.ClassType classType : rune.item_class_req) {
|
||||
classRuneID = CObjectIndex.getClassRuneId(classType);
|
||||
|
||||
this.name = rs.getString("name");
|
||||
this.description = rs.getString("description");
|
||||
this.type = rs.getInt("type");
|
||||
this.subtype = rs.getByte("subtype");
|
||||
if (classRuneID == null) {
|
||||
Logger.warn("RuneBase " + rune.template_id + ": class " + classType + " has no class rune");
|
||||
continue;
|
||||
}
|
||||
|
||||
DbManager.RuneBaseQueries.GET_RUNE_REQS(this);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID());
|
||||
classRune = RuneTemplate._runes.get(classRuneID);
|
||||
|
||||
if (classRune.rune_is_standard_character_creation)
|
||||
this.baseClass.put(classRuneID, true);
|
||||
else
|
||||
this.promotionClass.put(classRuneID, true);
|
||||
}
|
||||
|
||||
for (mbEnums.DisciplineType discType : rune.item_disc_req) {
|
||||
discRuneID = CObjectIndex.getDisciplineRuneId(discType);
|
||||
|
||||
if (discRuneID == null) {
|
||||
Logger.warn("RuneBase " + rune.template_id + ": discipline " + discType + " has no discipline rune");
|
||||
continue;
|
||||
}
|
||||
|
||||
this.discipline.put(discRuneID, true);
|
||||
}
|
||||
|
||||
// Same token as CObjectIndex: unresolved sub types are stored as their hash
|
||||
if (!rune.rune_sub_type.isEmpty())
|
||||
this.subTypeToken = Hasher.SBStringHash(rune.rune_sub_type);
|
||||
else
|
||||
this.subTypeToken = rune.rune_sub_type_hash;
|
||||
}
|
||||
|
||||
public static RuneBase getRuneBase(int tableId) {
|
||||
@@ -83,28 +113,114 @@ public class RuneBase extends AbstractGameObject {
|
||||
if (tableId == 0)
|
||||
return null;
|
||||
|
||||
RuneBase rb = (RuneBase) DbManager.getFromCache(mbEnums.GameObjectType.RuneBase, tableId);
|
||||
|
||||
if (rb != null)
|
||||
return rb;
|
||||
|
||||
return DbManager.RuneBaseQueries.GET_RUNEBASE(tableId);
|
||||
return (RuneBase) DbManager.getFromCache(mbEnums.GameObjectType.RuneBase, tableId);
|
||||
}
|
||||
|
||||
public static void serializeForClientMsg(RuneBase runeBase, ByteBufferWriter writer) {
|
||||
writer.putInt(runeBase.type);
|
||||
writer.putInt(0); // Pad
|
||||
writer.putInt(runeBase.getObjectUUID());
|
||||
writer.putInt(runeBase.getObjectType().ordinal());
|
||||
writer.putInt(runeBase.getObjectUUID());
|
||||
|
||||
}
|
||||
// Rune bases are every non-RACE rune: the classes, disciplines and talents (the 315 former static_rune_runebase rows).
|
||||
|
||||
public static void LoadAllRuneBases() {
|
||||
|
||||
DbManager.RuneBaseQueries.LOAD_ALL_RUNEBASES();
|
||||
RuneBase.AllowedBaseClassRunesMap = DbManager.RuneBaseQueries.LOAD_ALLOWED_STARTING_RUNES_FOR_BASECLASS();
|
||||
RuneBase.AllowedRaceRunesMap = DbManager.RuneBaseQueries.LOAD_ALLOWED_STARTING_RUNES_FOR_RACE();
|
||||
ArrayList<RuneBaseAttribute> attributes;
|
||||
int loadedCount = 0;
|
||||
|
||||
RuneBaseAttribute.runeBaseAttributeMap.clear();
|
||||
|
||||
for (RuneTemplate rune : RuneTemplate._runes.values()) {
|
||||
|
||||
if (rune.rune_type == mbEnums.RuneType.RACE)
|
||||
continue;
|
||||
|
||||
DbManager.addToCache(new RuneBase(rune));
|
||||
attributes = RuneBaseAttribute.getAttributesForRune(rune);
|
||||
|
||||
// getAttrs() returns null for a rune without attributes
|
||||
if (!attributes.isEmpty())
|
||||
RuneBaseAttribute.runeBaseAttributeMap.put(rune.template_id, attributes);
|
||||
|
||||
loadedCount++;
|
||||
}
|
||||
|
||||
Logger.info("Loaded " + loadedCount + " rune bases from runes");
|
||||
|
||||
loadCreationTalents();
|
||||
}
|
||||
|
||||
// Every creation race and class gets an explicit list; there is no "any" entry.
|
||||
|
||||
private static void loadCreationTalents() {
|
||||
|
||||
ArrayList<Integer> creationRaceIDs = new ArrayList<>();
|
||||
ArrayList<Integer> creationClassIDs = new ArrayList<>();
|
||||
ArrayList<Integer> listedRaceIDs;
|
||||
ArrayList<Integer> listedClassIDs;
|
||||
Integer classRuneID;
|
||||
boolean listed;
|
||||
boolean allowed;
|
||||
int talentCount = 0;
|
||||
|
||||
AllowedRaceRunesMap = new HashMap<>();
|
||||
AllowedBaseClassRunesMap = new HashMap<>();
|
||||
|
||||
for (RuneTemplate rune : RuneTemplate._runes.values()) {
|
||||
|
||||
if (!rune.rune_is_standard_character_creation)
|
||||
continue;
|
||||
|
||||
if (rune.rune_type == mbEnums.RuneType.RACE) {
|
||||
creationRaceIDs.add(rune.template_id);
|
||||
AllowedRaceRunesMap.put(rune.template_id, new ArrayList<>());
|
||||
}
|
||||
|
||||
if (rune.rune_type == mbEnums.RuneType.CLASS) {
|
||||
creationClassIDs.add(rune.template_id);
|
||||
AllowedBaseClassRunesMap.put(rune.template_id, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
for (RuneTemplate rune : RuneTemplate._runes.values()) {
|
||||
|
||||
if (!rune.rune_is_standard_character_creation || rune.rune_type != mbEnums.RuneType.TALENT)
|
||||
continue;
|
||||
|
||||
// ATTRRUNES leaves out flagged admin runes 2910/2911, unused duplicates and Proficient with Bows
|
||||
if (!CharCreateRuneList._runeList.attr_runes.contains(rune.template_id))
|
||||
continue;
|
||||
|
||||
listedRaceIDs = new ArrayList<>();
|
||||
listedClassIDs = new ArrayList<>();
|
||||
|
||||
for (mbEnums.MonsterType raceType : rune.item_race_req)
|
||||
listedRaceIDs.addAll(CObjectIndex.getRaceRuneIds(raceType));
|
||||
|
||||
for (mbEnums.ClassType classType : rune.item_class_req) {
|
||||
classRuneID = CObjectIndex.getClassRuneId(classType);
|
||||
|
||||
if (classRuneID != null)
|
||||
listedClassIDs.add(classRuneID);
|
||||
}
|
||||
|
||||
// restrict true = blacklist, false = whitelist (ArcItemRestrict_Check 0x4BAC60)
|
||||
for (int raceRuneID : creationRaceIDs) {
|
||||
listed = listedRaceIDs.contains(raceRuneID);
|
||||
allowed = rune.item_race_req_restrict ? !listed : listed;
|
||||
|
||||
if (allowed)
|
||||
AllowedRaceRunesMap.get(raceRuneID).add(rune.template_id);
|
||||
}
|
||||
|
||||
for (int baseClassID : creationClassIDs) {
|
||||
listed = listedClassIDs.contains(baseClassID);
|
||||
allowed = rune.item_class_req_restrict ? !listed : listed;
|
||||
|
||||
if (allowed)
|
||||
AllowedBaseClassRunesMap.get(baseClassID).add(rune.template_id);
|
||||
}
|
||||
|
||||
talentCount++;
|
||||
}
|
||||
|
||||
Logger.info("Loaded " + talentCount + " creation talents for " + creationRaceIDs.size() + " races and "
|
||||
+ creationClassIDs.size() + " classes from runes");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -124,15 +240,6 @@ public class RuneBase extends AbstractGameObject {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.type != rbObj.type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.subtype != rbObj.subtype) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -150,17 +257,6 @@ public class RuneBase extends AbstractGameObject {
|
||||
return description;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the subtype
|
||||
*/
|
||||
public byte getSubtype() {
|
||||
return subtype;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the attrs
|
||||
*/
|
||||
@@ -184,8 +280,30 @@ public class RuneBase extends AbstractGameObject {
|
||||
return this.discipline;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getOverwrite() {
|
||||
return this.overwrite;
|
||||
public mbEnums.RuneType getRuneType() {
|
||||
return this.runeType;
|
||||
}
|
||||
|
||||
// 0 when the rune has no sub type; talents sharing a non-zero token replace each other
|
||||
public int getSubTypeToken() {
|
||||
return this.subTypeToken;
|
||||
}
|
||||
|
||||
public int getRank() {
|
||||
return this.rank;
|
||||
}
|
||||
|
||||
// restrict true: the list is a blacklist; false: a whitelist
|
||||
public boolean isRaceRestrict() {
|
||||
return this.raceRestrict;
|
||||
}
|
||||
|
||||
public boolean isClassRestrict() {
|
||||
return this.classRestrict;
|
||||
}
|
||||
|
||||
public boolean isDiscRestrict() {
|
||||
return this.discRestrict;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Loaded 100 of 265 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user