Compare commits
73
Commits
No files matched your search
@@ -13,13 +13,7 @@ import engine.gameManager.DbManager;
|
|||||||
import engine.mbEnums;
|
import engine.mbEnums;
|
||||||
import engine.mbEnums.GameObjectType;
|
import engine.mbEnums.GameObjectType;
|
||||||
import engine.objects.BaseClass;
|
import engine.objects.BaseClass;
|
||||||
import org.pmw.tinylog.Logger;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class dbBaseClassHandler extends dbHandlerBase {
|
public class dbBaseClassHandler extends dbHandlerBase {
|
||||||
|
|
||||||
@@ -33,59 +27,6 @@ public class dbBaseClassHandler extends dbHandlerBase {
|
|||||||
if (id == 0)
|
if (id == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
BaseClass baseClass = (BaseClass) DbManager.getFromCache(GameObjectType.BaseClass, id);
|
return (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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,8 +16,6 @@ import engine.mbEnums.ItemType;
|
|||||||
import engine.objects.AbstractCharacter;
|
import engine.objects.AbstractCharacter;
|
||||||
import engine.objects.CharacterItemManager;
|
import engine.objects.CharacterItemManager;
|
||||||
import engine.objects.Item;
|
import engine.objects.Item;
|
||||||
import engine.objects.ItemTemplate;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
@@ -177,47 +175,23 @@ public class dbItemHandler extends dbHandlerBase {
|
|||||||
return itemList;
|
return itemList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LOAD_ITEM_TEMPLATES() {
|
public HashMap<Integer, Integer> LOAD_TEMPLATE_MODTABLES() {
|
||||||
|
|
||||||
HashMap<ItemType, Integer> templateTCountMap = new HashMap<>();
|
HashMap<Integer, Integer> modTables = new HashMap<>();
|
||||||
|
|
||||||
try (Connection connection = DbManager.getConnection();
|
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_item_templates`;");
|
|
||||||
ResultSet rs = preparedStatement.executeQuery()) {
|
|
||||||
|
|
||||||
while (rs.next()) {
|
|
||||||
int templateID = rs.getInt("id");
|
|
||||||
JSONObject jsonObject = new JSONObject(rs.getString("template"));
|
|
||||||
ItemTemplate itemTemplate = new ItemTemplate(jsonObject);
|
|
||||||
itemTemplate.template_id = templateID;
|
|
||||||
ItemTemplate.templates.put(templateID, itemTemplate);
|
|
||||||
|
|
||||||
templateTCountMap.merge(itemTemplate.item_type, 1, Integer::sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info(templateTCountMap.toString());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Logger.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LOAD_TEMPLATE_MODTABLES() {
|
|
||||||
|
|
||||||
try (Connection connection = DbManager.getConnection();
|
try (Connection connection = DbManager.getConnection();
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_vendor_items`;");
|
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_vendor_items`;");
|
||||||
ResultSet rs = preparedStatement.executeQuery()) {
|
ResultSet rs = preparedStatement.executeQuery()) {
|
||||||
|
|
||||||
while (rs.next()) {
|
while (rs.next())
|
||||||
int templateID = rs.getInt("templateID");
|
modTables.put(rs.getInt("templateID"), rs.getInt("modTable"));
|
||||||
int modTable = rs.getInt("modTable");
|
|
||||||
ItemTemplate template = ItemTemplate.templates.get(templateID);
|
|
||||||
template.modTable = modTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logger.error(e);
|
Logger.error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.info("read: " + modTables.size());
|
||||||
|
return modTables;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item GET_ITEM(final int itemUUID) {
|
public Item GET_ITEM(final int itemUUID) {
|
||||||
@@ -325,7 +299,7 @@ public class dbItemHandler extends dbHandlerBase {
|
|||||||
|
|
||||||
for (Item item : inventory) {
|
for (Item item : inventory) {
|
||||||
|
|
||||||
if (item.template.item_type.equals(ItemType.GOLD))
|
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
try (Connection connection = DbManager.getConnection();
|
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) {
|
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;
|
return false;
|
||||||
|
|
||||||
try (Connection connection = DbManager.getConnection();
|
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
|
// Write 0 if we will not modify the value from template
|
||||||
|
|
||||||
if (value == item.template.item_value)
|
if (value == item.template.getItemValue())
|
||||||
value = 0;
|
value = 0;
|
||||||
|
|
||||||
try (Connection connection = DbManager.getConnection();
|
try (Connection connection = DbManager.getConnection();
|
||||||
|
|||||||
@@ -27,30 +27,17 @@ public class dbPromotionClassHandler extends dbHandlerBase {
|
|||||||
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
|
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Integer> GET_ALLOWED_RUNES(final PromotionClass pc) {
|
|
||||||
|
|
||||||
ArrayList<Integer> runeList = new ArrayList<>();
|
|
||||||
|
|
||||||
try (Connection connection = DbManager.getConnection();
|
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_promotionrunereq` WHERE `promoID`=?")) {
|
|
||||||
|
|
||||||
preparedStatement.setInt(1, pc.getObjectUUID());
|
|
||||||
|
|
||||||
ResultSet rs = preparedStatement.executeQuery();
|
|
||||||
|
|
||||||
while (rs.next())
|
|
||||||
runeList.add(rs.getInt("runereqID"));
|
|
||||||
|
|
||||||
} catch (SQLException e) {
|
|
||||||
Logger.error(e);
|
|
||||||
|
|
||||||
}
|
|
||||||
return runeList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PromotionClass GET_PROMOTION_CLASS(final int objectUUID) {
|
public PromotionClass GET_PROMOTION_CLASS(final int objectUUID) {
|
||||||
|
|
||||||
PromotionClass promotionClass = 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();
|
try (Connection connection = DbManager.getConnection();
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_promotion` WHERE `ID` = ?")) {
|
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_promotion` WHERE `ID` = ?")) {
|
||||||
|
|||||||
@@ -10,15 +10,14 @@
|
|||||||
package engine.db.handlers;
|
package engine.db.handlers;
|
||||||
|
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
import engine.objects.Race;
|
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
public class dbRaceHandler extends dbHandlerBase {
|
public class dbRaceHandler extends dbHandlerBase {
|
||||||
|
|
||||||
@@ -46,27 +45,6 @@ public class dbRaceHandler extends dbHandlerBase {
|
|||||||
return integerSet;
|
return integerSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashSet<Integer> BEARD_STYLES_FOR_RACE(final int id) {
|
|
||||||
|
|
||||||
HashSet<Integer> integerSet = new HashSet<>();
|
|
||||||
|
|
||||||
try (Connection connection = DbManager.getConnection();
|
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `beardStyle` FROM `static_rune_racebeardstyle` WHERE `RaceID` = ?")) {
|
|
||||||
|
|
||||||
preparedStatement.setInt(1, id);
|
|
||||||
|
|
||||||
ResultSet rs = preparedStatement.executeQuery();
|
|
||||||
|
|
||||||
while (rs.next())
|
|
||||||
integerSet.add(rs.getInt(1));
|
|
||||||
|
|
||||||
} catch (SQLException e) {
|
|
||||||
Logger.error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return integerSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashSet<Integer> HAIR_COLORS_FOR_RACE(final int id) {
|
public HashSet<Integer> HAIR_COLORS_FOR_RACE(final int id) {
|
||||||
|
|
||||||
HashSet<Integer> integerSet = new HashSet<>();
|
HashSet<Integer> integerSet = new HashSet<>();
|
||||||
@@ -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) {
|
public HashSet<Integer> SKIN_COLOR_FOR_RACE(final int id) {
|
||||||
|
|
||||||
HashSet<Integer> integerSet = new HashSet<>();
|
HashSet<Integer> integerSet = new HashSet<>();
|
||||||
@@ -132,32 +88,23 @@ public class dbRaceHandler extends dbHandlerBase {
|
|||||||
return integerSet;
|
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;
|
HashMap<Integer, float[]> raceHeights = new HashMap<>();
|
||||||
Race thisRace;
|
|
||||||
|
|
||||||
races = new ConcurrentHashMap<>();
|
|
||||||
int recordsRead = 0;
|
|
||||||
|
|
||||||
try (Connection connection = DbManager.getConnection();
|
try (Connection connection = DbManager.getConnection();
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_race")) {
|
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_race")) {
|
||||||
|
|
||||||
ResultSet rs = preparedStatement.executeQuery();
|
ResultSet rs = preparedStatement.executeQuery();
|
||||||
|
|
||||||
while (rs.next()) {
|
while (rs.next())
|
||||||
|
raceHeights.put(rs.getInt("ID"), new float[]{rs.getFloat("minHeight"), rs.getFloat("strHeightMod")});
|
||||||
recordsRead++;
|
|
||||||
thisRace = new Race(rs);
|
|
||||||
|
|
||||||
races.put(thisRace.getRaceRuneID(), thisRace);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
Logger.error(e);
|
Logger.error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info("read: " + recordsRead + " cached: " + races.size());
|
return raceHeights;
|
||||||
return races;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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,9 +11,12 @@ package engine.db.handlers;
|
|||||||
|
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
import engine.mbEnums;
|
import engine.mbEnums;
|
||||||
|
import engine.objects.AbstractGameObject;
|
||||||
|
import engine.objects.BaseClass;
|
||||||
|
import engine.objects.PromotionClass;
|
||||||
|
import engine.objects.Race;
|
||||||
import engine.objects.RuneBase;
|
import engine.objects.RuneBase;
|
||||||
import engine.powers.RunePowerEntry;
|
import engine.powers.RunePowerEntry;
|
||||||
import engine.powers.RuneSkillAdjustEntry;
|
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
@@ -69,192 +72,57 @@ public class dbRuneBaseHandler extends dbHandlerBase {
|
|||||||
return mobPowers;
|
return mobPowers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> LOAD_RUNE_SKILL_ADJUSTS() {
|
// 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<RuneSkillAdjustEntry>> runeSkillAdjusts = new HashMap<>();
|
int rowsWritten = 0;
|
||||||
RuneSkillAdjustEntry runeSkillAdjustEntry;
|
|
||||||
|
|
||||||
int rune_id;
|
|
||||||
int recordsRead = 0;
|
|
||||||
|
|
||||||
try (Connection connection = DbManager.getConnection();
|
try (Connection connection = DbManager.getConnection();
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_skill_adjusts")) {
|
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++;
|
for (Race race : Race.getAllRaces()) {
|
||||||
|
addRuneLookupRow(insertStatement, race.getRaceRuneID(), "RACE", race.getName());
|
||||||
rune_id = rs.getInt("rune_id");
|
rowsWritten++;
|
||||||
runeSkillAdjustEntry = new RuneSkillAdjustEntry(rs);
|
|
||||||
|
|
||||||
if (runeSkillAdjusts.get(rune_id) == null) {
|
|
||||||
ArrayList<RuneSkillAdjustEntry> skillAdjustList = new ArrayList<>();
|
|
||||||
skillAdjustList.add(runeSkillAdjustEntry);
|
|
||||||
runeSkillAdjusts.put(rune_id, skillAdjustList);
|
|
||||||
} else {
|
|
||||||
ArrayList<RuneSkillAdjustEntry> powerList = runeSkillAdjusts.get(rune_id);
|
|
||||||
powerList.add(runeSkillAdjustEntry);
|
|
||||||
runeSkillAdjusts.put(rune_id, powerList);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
Logger.error(e);
|
|
||||||
return runeSkillAdjusts;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info("read: " + recordsRead + " cached: " + runeSkillAdjusts.size());
|
for (AbstractGameObject baseClass : DbManager.getMap(mbEnums.GameObjectType.BaseClass).values()) {
|
||||||
return runeSkillAdjusts;
|
addRuneLookupRow(insertStatement, baseClass.getObjectUUID(), "BASECLASS", ((BaseClass) baseClass).getName());
|
||||||
}
|
rowsWritten++;
|
||||||
|
|
||||||
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) {
|
} catch (Exception e) {
|
||||||
Logger.error(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) {
|
private static void addRuneLookupRow(PreparedStatement insertStatement, int runeID, String type, String name) throws SQLException {
|
||||||
|
insertStatement.setInt(1, runeID);
|
||||||
RuneBase runeBase = null;
|
insertStatement.setString(2, type);
|
||||||
|
insertStatement.setString(3, name);
|
||||||
try (Connection connection = DbManager.getConnection();
|
insertStatement.addBatch();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,6 @@ package engine.db.handlers;
|
|||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
import engine.mbEnums;
|
import engine.mbEnums;
|
||||||
import engine.mbEnums.GameObjectType;
|
import engine.mbEnums.GameObjectType;
|
||||||
import engine.objects.MaxSkills;
|
|
||||||
import engine.objects.SkillsBase;
|
import engine.objects.SkillsBase;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
@@ -20,8 +19,6 @@ import java.sql.Connection;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
public class dbSkillBaseHandler extends dbHandlerBase {
|
public class dbSkillBaseHandler extends dbHandlerBase {
|
||||||
|
|
||||||
@@ -98,55 +95,4 @@ public class dbSkillBaseHandler extends dbHandlerBase {
|
|||||||
SkillsBase.putInCache(skillsBase);
|
SkillsBase.putInCache(skillsBase);
|
||||||
return skillsBase;
|
return skillsBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LOAD_ALL_MAX_SKILLS_FOR_CONTRACT() {
|
|
||||||
|
|
||||||
try (Connection connection = DbManager.getConnection();
|
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_rune_maxskills`")) {
|
|
||||||
|
|
||||||
ResultSet rs = preparedStatement.executeQuery();
|
|
||||||
|
|
||||||
while (rs.next()) {
|
|
||||||
|
|
||||||
MaxSkills maxSKills = new MaxSkills(rs);
|
|
||||||
|
|
||||||
if (MaxSkills.MaxSkillsSet.get(maxSKills.getRuneID()) == null) {
|
|
||||||
ArrayList<MaxSkills> newMaxSkillsList = new ArrayList<>();
|
|
||||||
newMaxSkillsList.add(maxSKills);
|
|
||||||
MaxSkills.MaxSkillsSet.put(maxSKills.getRuneID(), newMaxSkillsList);
|
|
||||||
} else
|
|
||||||
MaxSkills.MaxSkillsSet.get(maxSKills.getRuneID()).add(maxSKills);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (SQLException e) {
|
|
||||||
Logger.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void LOAD_ALL_RUNE_SKILLS() {
|
|
||||||
|
|
||||||
try (Connection connection = DbManager.getConnection();
|
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_skill_skillsgranted`")) {
|
|
||||||
|
|
||||||
ResultSet rs = preparedStatement.executeQuery();
|
|
||||||
|
|
||||||
while (rs.next()) {
|
|
||||||
|
|
||||||
int runeID = rs.getInt("runeID");
|
|
||||||
int token = rs.getInt("token");
|
|
||||||
int amount = rs.getInt("amount");
|
|
||||||
|
|
||||||
if (SkillsBase.runeSkillsCache.get(runeID) == null)
|
|
||||||
SkillsBase.runeSkillsCache.put(runeID, new HashMap<>());
|
|
||||||
|
|
||||||
SkillsBase.runeSkillsCache.get(runeID).put(token, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (SQLException e) {
|
|
||||||
Logger.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -76,24 +76,4 @@ public class dbSkillReqHandler extends dbHandlerBase {
|
|||||||
Logger.error(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -15,8 +15,8 @@ import engine.gameManager.DbManager;
|
|||||||
import engine.mbEnums;
|
import engine.mbEnums;
|
||||||
import engine.objects.AbstractGameObject;
|
import engine.objects.AbstractGameObject;
|
||||||
import engine.objects.Item;
|
import engine.objects.Item;
|
||||||
import engine.objects.ItemTemplate;
|
|
||||||
import engine.objects.PlayerCharacter;
|
import engine.objects.PlayerCharacter;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,7 +38,7 @@ public class CreateItemCmd extends AbstractDevCmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int templateID = Integer.parseInt(words[0]);
|
int templateID = Integer.parseInt(words[0]);
|
||||||
ItemTemplate template = ItemTemplate.templates.get(templateID);
|
CObjectTemplate template = CObjectTemplate.lookup(templateID);
|
||||||
|
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
ChatManager.chatSystemInfo(playerCharacter, "No such template found.");
|
ChatManager.chatSystemInfo(playerCharacter, "No such template found.");
|
||||||
@@ -51,7 +51,7 @@ public class CreateItemCmd extends AbstractDevCmd {
|
|||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
|
|
||||||
if (!playerCharacter.charItemManager.hasRoomInventory(template.item_wt)) {
|
if (!playerCharacter.charItemManager.hasRoomInventory(template.getItemWt())) {
|
||||||
ChatManager.chatSystemInfo(playerCharacter, "You are encumbered!.");
|
ChatManager.chatSystemInfo(playerCharacter, "You are encumbered!.");
|
||||||
break;
|
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.GameObjectType;
|
||||||
import engine.mbEnums.TargetColor;
|
import engine.mbEnums.TargetColor;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.util.StringUtils;
|
import engine.util.StringUtils;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
@@ -507,17 +508,17 @@ public class InfoCmd extends AbstractDevCmd {
|
|||||||
case Item: //intentional passthrough
|
case Item: //intentional passthrough
|
||||||
case MobLoot:
|
case MobLoot:
|
||||||
Item item = (Item) target;
|
Item item = (Item) target;
|
||||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||||
output += StringUtils.addWS("Template: " + template.template_id, 20);
|
output += StringUtils.addWS("Template: " + template.getTemplateId(), 20);
|
||||||
output += "Weight: " + template.item_wt;
|
output += "Weight: " + template.getItemWt();
|
||||||
output += newline;
|
output += newline;
|
||||||
DecimalFormat df = new DecimalFormat("###,###,###,###,##0");
|
DecimalFormat df = new DecimalFormat("###,###,###,###,##0");
|
||||||
output += StringUtils.addWS("Qty: "
|
output += StringUtils.addWS("Qty: "
|
||||||
+ df.format(item.getNumOfItems()), 20);
|
+ df.format(item.getNumOfItems()), 20);
|
||||||
output += "Charges: " + (byte) item.chargesRemaining
|
output += "Charges: " + (byte) item.chargesRemaining
|
||||||
+ '/' + item.template.item_initial_charges;
|
+ '/' + item.template.getItemInitialCharges();
|
||||||
output += newline;
|
output += newline;
|
||||||
output += "Name: " + template.item_base_name;
|
output += "Name: " + template.getItemBaseName();
|
||||||
output += newline;
|
output += newline;
|
||||||
output += item.getContainerInfo();
|
output += item.getContainerInfo();
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ package engine.devcmd.cmds;
|
|||||||
|
|
||||||
import engine.devcmd.AbstractDevCmd;
|
import engine.devcmd.AbstractDevCmd;
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
|
import engine.mbEnums.ItemContainerType;
|
||||||
import engine.mbEnums.ItemType;
|
import engine.mbEnums.ItemType;
|
||||||
import engine.mbEnums.OwnerType;
|
import engine.mbEnums.OwnerType;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.powers.EffectsBase;
|
import engine.powers.EffectsBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,17 +61,17 @@ public class MakeItemCmd extends AbstractDevCmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int templateID;
|
int templateID;
|
||||||
ItemTemplate template;
|
CObjectTemplate template;
|
||||||
try {
|
try {
|
||||||
templateID = Integer.parseInt(words[0]);
|
templateID = Integer.parseInt(words[0]);
|
||||||
template = ItemTemplate.templates.get(templateID);
|
template = CObjectTemplate.lookup(templateID);
|
||||||
|
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
throwbackError(pc, "No item template with id " + words[0]);
|
throwbackError(pc, "No item template with id " + words[0]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (template.item_type == ItemType.GOLD) {
|
if (template.getItemType() == ItemType.GOLD) {
|
||||||
this.throwbackInfo(pc, "use /addgold to add gold.");
|
this.throwbackInfo(pc, "use /addgold to add gold.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -131,7 +133,7 @@ public class MakeItemCmd extends AbstractDevCmd {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template = ItemTemplate.templates.get(templateID);
|
template = CObjectTemplate.lookup(templateID);
|
||||||
|
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
throwbackError(pc, "Unable to find template " + templateID);
|
throwbackError(pc, "Unable to find template " + templateID);
|
||||||
@@ -139,8 +141,8 @@ public class MakeItemCmd extends AbstractDevCmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((numItems > 1)
|
if ((numItems > 1)
|
||||||
&& (template.item_type.equals(ItemType.RESOURCE) == false)
|
&& (template.getItemType().equals(ItemType.RESOURCE) == false)
|
||||||
&& (template.item_type.equals(ItemType.OFFERING)) == false)
|
&& (template.getItemType().equals(ItemType.OFFERING)) == false)
|
||||||
numItems = 1;
|
numItems = 1;
|
||||||
|
|
||||||
CharacterItemManager cim = pc.charItemManager;
|
CharacterItemManager cim = pc.charItemManager;
|
||||||
@@ -154,7 +156,7 @@ public class MakeItemCmd extends AbstractDevCmd {
|
|||||||
|
|
||||||
for (int i = 0; i < quantity; i++) {
|
for (int i = 0; i < quantity; i++) {
|
||||||
|
|
||||||
int weight = template.item_wt;
|
int weight = template.getItemWt();
|
||||||
|
|
||||||
if (!cim.hasRoomInventory(weight)) {
|
if (!cim.hasRoomInventory(weight)) {
|
||||||
throwbackError(pc, "Not enough room in inventory for any more of this item. " + i + " produced.");
|
throwbackError(pc, "Not enough room in inventory for any more of this item. " + i + " produced.");
|
||||||
@@ -168,6 +170,7 @@ public class MakeItemCmd extends AbstractDevCmd {
|
|||||||
Item item = new Item(templateID);
|
Item item = new Item(templateID);
|
||||||
item.ownerID = pc.getObjectUUID();
|
item.ownerID = pc.getObjectUUID();
|
||||||
item.ownerType = OwnerType.PlayerCharacter;
|
item.ownerType = OwnerType.PlayerCharacter;
|
||||||
|
item.containerType = ItemContainerType.INVENTORY;
|
||||||
|
|
||||||
if (numItems > 1)
|
if (numItems > 1)
|
||||||
item.setNumOfItems(numItems);
|
item.setNumOfItems(numItems);
|
||||||
@@ -179,6 +182,11 @@ public class MakeItemCmd extends AbstractDevCmd {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item == null) {
|
||||||
|
throwbackError(pc, "DB error 2: Unable to create item " + templateID + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//create prefix
|
//create prefix
|
||||||
if (!prefix.isEmpty())
|
if (!prefix.isEmpty())
|
||||||
item.addPermanentEnchantmentForDev(prefix, 0);
|
item.addPermanentEnchantmentForDev(prefix, 0);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ package engine.devcmd.cmds;
|
|||||||
|
|
||||||
import engine.devcmd.AbstractDevCmd;
|
import engine.devcmd.AbstractDevCmd;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@@ -52,8 +53,8 @@ public class PrintBankCmd extends AbstractDevCmd {
|
|||||||
throwbackInfo(pc, "Bank for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
throwbackInfo(pc, "Bank for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
||||||
|
|
||||||
for (Item item : list) {
|
for (Item item : list) {
|
||||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||||
throwbackInfo(pc, " " + template.item_base_name + ", count: " + item.getNumOfItems());
|
throwbackInfo(pc, " " + template.getItemBaseName() + ", count: " + item.getNumOfItems());
|
||||||
}
|
}
|
||||||
|
|
||||||
Item gold = cim.getGoldBank();
|
Item gold = cim.getGoldBank();
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import engine.devcmd.AbstractDevCmd;
|
|||||||
import engine.gameManager.ChatManager;
|
import engine.gameManager.ChatManager;
|
||||||
import engine.mbEnums.GameObjectType;
|
import engine.mbEnums.GameObjectType;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||||
|
|
||||||
public class PrintBonusesCmd extends AbstractDevCmd {
|
public class PrintBonusesCmd extends AbstractDevCmd {
|
||||||
@@ -33,8 +34,8 @@ public class PrintBonusesCmd extends AbstractDevCmd {
|
|||||||
if (target instanceof Item) {
|
if (target instanceof Item) {
|
||||||
type = "Item";
|
type = "Item";
|
||||||
tar = (Item) target;
|
tar = (Item) target;
|
||||||
ItemTemplate template = ItemTemplate.templates.get(((Item) tar).templateID);
|
CObjectTemplate template = CObjectTemplate.lookup(((Item) tar).templateID);
|
||||||
name = template.item_base_name;
|
name = template.getItemBaseName();
|
||||||
} else if (target instanceof AbstractCharacter) {
|
} else if (target instanceof AbstractCharacter) {
|
||||||
tar = (AbstractCharacter) target;
|
tar = (AbstractCharacter) target;
|
||||||
name = ((AbstractCharacter) tar).getFirstName();
|
name = ((AbstractCharacter) tar).getFirstName();
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class PrintEquipCmd extends AbstractDevCmd {
|
|||||||
throwbackInfo(pc, "Equip for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
throwbackInfo(pc, "Equip for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
||||||
for (mbEnums.EquipSlotType slot : tarMob.charItemManager.equipped.keySet()) {
|
for (mbEnums.EquipSlotType slot : tarMob.charItemManager.equipped.keySet()) {
|
||||||
Item equip = tarMob.charItemManager.equipped.get(slot);
|
Item equip = tarMob.charItemManager.equipped.get(slot);
|
||||||
throwbackInfo(pc, equip.templateID + " : " + equip.template.item_base_name + ", slot: " + slot);
|
throwbackInfo(pc, equip.templateID + " : " + equip.template.getItemBaseName() + ", slot: " + slot);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ public class PrintEquipCmd extends AbstractDevCmd {
|
|||||||
throwbackInfo(pc, "Equip for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
throwbackInfo(pc, "Equip for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
||||||
for (mbEnums.EquipSlotType slot : tarMob.charItemManager.equipped.keySet()) {
|
for (mbEnums.EquipSlotType slot : tarMob.charItemManager.equipped.keySet()) {
|
||||||
Item equip = tarMob.charItemManager.equipped.get(slot);
|
Item equip = tarMob.charItemManager.equipped.get(slot);
|
||||||
throwbackInfo(pc, equip.templateID + " : " + equip.template.item_base_name + ", slot: " + slot);
|
throwbackInfo(pc, equip.templateID + " : " + equip.template.getItemBaseName() + ", slot: " + slot);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ public class PrintEquipCmd extends AbstractDevCmd {
|
|||||||
|
|
||||||
for (mbEnums.EquipSlotType slot : list.keySet()) {
|
for (mbEnums.EquipSlotType slot : list.keySet()) {
|
||||||
Item item = list.get(slot);
|
Item item = list.get(slot);
|
||||||
throwbackInfo(pc, " " + item.template.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.devcmd.AbstractDevCmd;
|
||||||
import engine.mbEnums.ItemType;
|
import engine.mbEnums.ItemType;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -75,18 +76,18 @@ public class PrintInventoryCmd extends AbstractDevCmd {
|
|||||||
int goldCount = 0;
|
int goldCount = 0;
|
||||||
|
|
||||||
for (Item item : inventory) {
|
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 = "";
|
String chargeInfo = "";
|
||||||
int chargeMax = template.item_initial_charges;
|
int chargeMax = template.getItemInitialCharges();
|
||||||
|
|
||||||
if (chargeMax > 0) {
|
if (chargeMax > 0) {
|
||||||
int charges = item.chargesRemaining;
|
int charges = item.chargesRemaining;
|
||||||
chargeInfo = " charges: " + charges + '/' + chargeMax;
|
chargeInfo = " charges: " + charges + '/' + chargeMax;
|
||||||
}
|
}
|
||||||
throwbackInfo(pc, " " + template.item_base_name + ", count: " + item.getNumOfItems() + chargeInfo);
|
throwbackInfo(pc, " " + template.getItemBaseName() + ", count: " + item.getNumOfItems() + chargeInfo);
|
||||||
} else
|
} else
|
||||||
goldCount += item.getNumOfItems();
|
goldCount += item.getNumOfItems();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ package engine.devcmd.cmds;
|
|||||||
|
|
||||||
import engine.devcmd.AbstractDevCmd;
|
import engine.devcmd.AbstractDevCmd;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@@ -50,8 +51,8 @@ public class PrintVaultCmd extends AbstractDevCmd {
|
|||||||
ArrayList<Item> list = cim.getVault();
|
ArrayList<Item> list = cim.getVault();
|
||||||
throwbackInfo(pc, "Vault for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
throwbackInfo(pc, "Vault for " + type + ' ' + name + " (" + tar.getObjectUUID() + ')');
|
||||||
for (Item item : list) {
|
for (Item item : list) {
|
||||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||||
throwbackInfo(pc, " " + template.item_base_name + ", count: " + item.getNumOfItems());
|
throwbackInfo(pc, " " + template.getItemBaseName() + ", count: " + item.getNumOfItems());
|
||||||
}
|
}
|
||||||
Item gold = cim.getGoldVault();
|
Item gold = cim.getGoldVault();
|
||||||
if (gold != null)
|
if (gold != null)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import engine.gameManager.LootManager;
|
|||||||
import engine.gameManager.ZoneManager;
|
import engine.gameManager.ZoneManager;
|
||||||
import engine.loot.BootySetEntry;
|
import engine.loot.BootySetEntry;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
@@ -34,10 +35,10 @@ public class SimulateBootyCmd extends AbstractDevCmd {
|
|||||||
if (mob.bootySet != 0) {
|
if (mob.bootySet != 0) {
|
||||||
for (BootySetEntry entry : LootManager._bootySetMap.get(mob.bootySet)) {
|
for (BootySetEntry entry : LootManager._bootySetMap.get(mob.bootySet)) {
|
||||||
|
|
||||||
ItemTemplate template = ItemTemplate.templates.get(entry.templateID);
|
CObjectTemplate template = CObjectTemplate.lookup(entry.templateID);
|
||||||
|
|
||||||
if (template != null)
|
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 {
|
try {
|
||||||
mob.loadInventory();
|
mob.loadInventory();
|
||||||
for (Item lootItem : mob.charItemManager.getInventory()) {
|
for (Item lootItem : mob.charItemManager.getInventory()) {
|
||||||
switch (lootItem.template.item_type) {
|
switch (lootItem.template.getItemType()) {
|
||||||
case EMPLOYMENTCONTRACT: //CONTRACT
|
case EMPLOYMENTCONTRACT: //CONTRACT
|
||||||
Contracts.add(lootItem);
|
Contracts.add(lootItem);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import engine.mbEnums.BuildingGroup;
|
|||||||
import engine.mbEnums.GameObjectType;
|
import engine.mbEnums.GameObjectType;
|
||||||
import engine.net.client.msg.ErrorPopupMsg;
|
import engine.net.client.msg.ErrorPopupMsg;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
@@ -199,12 +200,12 @@ public enum BuildingManager {
|
|||||||
return false;
|
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;
|
return false;
|
||||||
|
|
||||||
if (!ItemManager.MakeItemForPlayer(template.template_id, player, amount))
|
if (!ItemManager.MakeItemForPlayer(template.getTemplateId(), player, amount))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
shrine.setFavors(0);
|
shrine.setFavors(0);
|
||||||
@@ -218,12 +219,12 @@ public enum BuildingManager {
|
|||||||
|
|
||||||
for (mbEnums.ResourceType resourceType : EnumSet.allOf(mbEnums.ResourceType.class)) {
|
for (mbEnums.ResourceType resourceType : EnumSet.allOf(mbEnums.ResourceType.class)) {
|
||||||
|
|
||||||
ItemTemplate resourceTemplate = ItemTemplate.templates.get(resourceType.templateID);
|
CObjectTemplate resourceTemplate = CObjectTemplate.lookup(resourceType.templateID);
|
||||||
|
|
||||||
if (resourceTemplate == null)
|
if (resourceTemplate == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!player.charItemManager.hasRoomInventory(resourceTemplate.item_wt)) {
|
if (!player.charItemManager.hasRoomInventory(resourceTemplate.getItemWt())) {
|
||||||
ChatManager.chatSystemInfo(player, "You can not carry any more of that item.");
|
ChatManager.chatSystemInfo(player, "You can not carry any more of that item.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import engine.net.client.ClientConnection;
|
|||||||
import engine.net.client.handlers.ClientAdminCommandMsgHandler;
|
import engine.net.client.handlers.ClientAdminCommandMsgHandler;
|
||||||
import engine.net.client.msg.chat.*;
|
import engine.net.client.msg.chat.*;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
import engine.server.world.WorldServer;
|
import engine.server.world.WorldServer;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
@@ -535,12 +536,12 @@ public enum ChatManager {
|
|||||||
if (item != null) //Steal
|
if (item != null) //Steal
|
||||||
if (success) {
|
if (success) {
|
||||||
String name = "";
|
String name = "";
|
||||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD))
|
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD))
|
||||||
name = amount + " gold ";
|
name = amount + " gold ";
|
||||||
else {
|
else {
|
||||||
String vowels = "aeiou";
|
String vowels = "aeiou";
|
||||||
ItemTemplate template = ItemTemplate.templates.get(item.templateID);
|
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
|
||||||
String iName = template.item_base_name;
|
String iName = template.getItemBaseName();
|
||||||
if (iName.length() > 0)
|
if (iName.length() > 0)
|
||||||
if (vowels.indexOf(iName.substring(0, 1).toLowerCase()) >= 0)
|
if (vowels.indexOf(iName.substring(0, 1).toLowerCase()) >= 0)
|
||||||
name = "an " + iName + ' ';
|
name = "an " + iName + ' ';
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import engine.net.client.msg.PowerProjectileMsg;
|
|||||||
import engine.net.client.msg.TargetedActionMsg;
|
import engine.net.client.msg.TargetedActionMsg;
|
||||||
import engine.net.client.msg.UpdateStateMsg;
|
import engine.net.client.msg.UpdateStateMsg;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
|
import engine.parsers.objects.RuneTemplate;
|
||||||
import engine.powers.DamageShield;
|
import engine.powers.DamageShield;
|
||||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||||
import engine.powers.effectmodifiers.WeaponProcEffectModifier;
|
import engine.powers.effectmodifiers.WeaponProcEffectModifier;
|
||||||
@@ -92,25 +94,25 @@ public enum CombatManager {
|
|||||||
return;
|
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
|
//swing left hand only
|
||||||
processAttack(attacker, target, mbEnums.EquipSlotType.LHELD);
|
processAttack(attacker, target, mbEnums.EquipSlotType.LHELD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mainWeapon == null && offWeapon != null && offWeapon.template.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
|
//no weapon equipped with a shield, punch with one hand
|
||||||
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
|
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mainWeapon != null && offWeapon != null && offWeapon.template.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
|
//one weapon equipped with a shield, swing with one hand
|
||||||
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
|
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mainWeapon != null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) {
|
if (mainWeapon != null && offWeapon != null && !offWeapon.template.getItemSkillUsed().equals("Block")) {
|
||||||
//two weapons equipped, swing both hands
|
//two weapons equipped, swing both hands
|
||||||
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
|
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
|
||||||
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter))
|
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter))
|
||||||
@@ -146,7 +148,7 @@ public enum CombatManager {
|
|||||||
if (bonus != null)
|
if (bonus != null)
|
||||||
rangeMod += bonus.getFloatPercentAll(mbEnums.ModType.WeaponRange, mbEnums.SourceType.None);
|
rangeMod += bonus.getFloatPercentAll(mbEnums.ModType.WeaponRange, mbEnums.SourceType.None);
|
||||||
|
|
||||||
attackRange += 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)) {
|
} else if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) {
|
||||||
|
|
||||||
//unarmed mob, add the natural attack range from its rune (0 for most melee mobs)
|
//unarmed mob, add the natural attack range from its rune (0 for most melee mobs)
|
||||||
@@ -211,7 +213,7 @@ public enum CombatManager {
|
|||||||
|
|
||||||
if (weapon != null) {
|
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
|
if (weapon.getBonusPercent(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None) != 0f) //add weapon speed bonus
|
||||||
wepSpeed *= (1 + weapon.getBonus(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None));
|
wepSpeed *= (1 + weapon.getBonus(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None));
|
||||||
@@ -270,13 +272,13 @@ public enum CombatManager {
|
|||||||
if (weapon != null && !attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) {
|
if (weapon != null && !attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) {
|
||||||
//check if Out of Stamina
|
//check if Out of Stamina
|
||||||
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) {
|
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) {
|
||||||
if (attacker.getStamina() < (weapon.template.item_wt / 3f)) {
|
if (attacker.getStamina() < (weapon.template.getItemWt() / 3f)) {
|
||||||
//set auto attack job
|
//set auto attack job
|
||||||
setAutoAttackJob(attacker, slot, delay);
|
setAutoAttackJob(attacker, slot, delay);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float stam = weapon.template.item_wt / 3f;
|
float stam = weapon.template.getItemWt() / 3f;
|
||||||
stam = (stam < 1) ? 1 : stam;
|
stam = (stam < 1) ? 1 : stam;
|
||||||
attacker.modifyStamina(-(stam), attacker, true);
|
attacker.modifyStamina(-(stam), attacker, true);
|
||||||
} else
|
} else
|
||||||
@@ -416,7 +418,7 @@ public enum CombatManager {
|
|||||||
if (((Mob) attacker).isSiege())
|
if (((Mob) attacker).isSiege())
|
||||||
damageType = mbEnums.DamageType.SIEGE;
|
damageType = mbEnums.DamageType.SIEGE;
|
||||||
} else {
|
} 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
|
//get resists
|
||||||
@@ -577,13 +579,14 @@ public enum CombatManager {
|
|||||||
target.setCombatTarget(attacker);
|
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
|
//No weapon, return default animation
|
||||||
if (wb == null)
|
if (wb == null)
|
||||||
return 75;
|
return 75;
|
||||||
|
|
||||||
int token;
|
int token;
|
||||||
|
engine.parsers.objects.ItemTemplate.Weapon weapon = engine.parsers.objects.ItemTemplate.getWeapon(wb.getTemplateId());
|
||||||
|
|
||||||
if (dpj != null) {
|
if (dpj != null) {
|
||||||
|
|
||||||
@@ -594,7 +597,7 @@ public enum CombatManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Item has no equipment slots and should not try to return an animation, return default instead
|
//Item has no equipment slots and should not try to return an animation, return default instead
|
||||||
if (wb.item_eq_slots_or == null || wb.item_eq_slots_or.isEmpty()) {
|
if (wb.getItemEqSlotsOr().isEmpty()) {
|
||||||
return 75;
|
return 75;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -603,18 +606,18 @@ public enum CombatManager {
|
|||||||
int random;
|
int random;
|
||||||
|
|
||||||
//Item can only be equipped in one slot, return animation for that slot
|
//Item can only be equipped in one slot, return animation for that slot
|
||||||
if (wb.item_eq_slots_or.size() == 1) {
|
if (wb.getItemEqSlotsOr().size() == 1) {
|
||||||
if (wb.item_eq_slots_or.iterator().next().equals(mbEnums.EquipSlotType.RHELD)) {
|
if (wb.getItemEqSlotsOr().iterator().next().equals(mbEnums.EquipSlotType.RHELD)) {
|
||||||
anim = wb.weapon_attack_anim_right.get(0)[0];
|
anim = weapon.weapon_attack_anim_right.get(0)[0];
|
||||||
if (dpj != null) {
|
if (dpj != null) {
|
||||||
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_right.size());
|
random = ThreadLocalRandom.current().nextInt(weapon.weapon_attack_anim_right.size());
|
||||||
anim = wb.weapon_attack_anim_right.get(random)[0];
|
anim = weapon.weapon_attack_anim_right.get(random)[0];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
anim = wb.weapon_attack_anim_left.get(0)[0];
|
anim = weapon.weapon_attack_anim_left.get(0)[0];
|
||||||
if (dpj != null) {
|
if (dpj != null) {
|
||||||
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_left.size());
|
random = ThreadLocalRandom.current().nextInt(weapon.weapon_attack_anim_left.size());
|
||||||
anim = wb.weapon_attack_anim_left.get(random)[0];
|
anim = weapon.weapon_attack_anim_left.get(random)[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return anim;
|
return anim;
|
||||||
@@ -622,16 +625,16 @@ public enum CombatManager {
|
|||||||
|
|
||||||
//Item can be equipped in either hand, and should have animation sets for each hand
|
//Item can be equipped in either hand, and should have animation sets for each hand
|
||||||
if (slot.equals(mbEnums.EquipSlotType.RHELD)) {
|
if (slot.equals(mbEnums.EquipSlotType.RHELD)) {
|
||||||
anim = wb.weapon_attack_anim_right.get(0)[0];
|
anim = weapon.weapon_attack_anim_right.get(0)[0];
|
||||||
if (dpj != null) {
|
if (dpj != null) {
|
||||||
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_right.size());
|
random = ThreadLocalRandom.current().nextInt(weapon.weapon_attack_anim_right.size());
|
||||||
anim = wb.weapon_attack_anim_right.get(random)[0];
|
anim = weapon.weapon_attack_anim_right.get(random)[0];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
anim = wb.weapon_attack_anim_left.get(0)[0];
|
anim = weapon.weapon_attack_anim_left.get(0)[0];
|
||||||
if (dpj != null) {
|
if (dpj != null) {
|
||||||
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_left.size());
|
random = ThreadLocalRandom.current().nextInt(weapon.weapon_attack_anim_left.size());
|
||||||
anim = wb.weapon_attack_anim_left.get(random)[0];
|
anim = weapon.weapon_attack_anim_left.get(random)[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return anim;
|
return anim;
|
||||||
@@ -713,7 +716,7 @@ public enum CombatManager {
|
|||||||
// Mobs use their mobbase rune, players use their race rune.
|
// Mobs use their mobbase rune, players use their race rune.
|
||||||
|
|
||||||
int runeID;
|
int runeID;
|
||||||
ItemTemplate rune;
|
RuneTemplate rune;
|
||||||
int hand = slot.equals(mbEnums.EquipSlotType.LHELD) ? 2 : 1;
|
int hand = slot.equals(mbEnums.EquipSlotType.LHELD) ? 2 : 1;
|
||||||
|
|
||||||
switch (attacker.getObjectType()) {
|
switch (attacker.getObjectType()) {
|
||||||
@@ -727,18 +730,18 @@ public enum CombatManager {
|
|||||||
return null;
|
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;
|
return null;
|
||||||
|
|
||||||
for (float[] attack : rune.rune_natural_attacks)
|
for (float[] attack : rune.rune_naturalattacks)
|
||||||
if (attack.length > 3 && (int) attack[3] == hand)
|
if (attack.length > 3 && (int) attack[3] == hand)
|
||||||
return attack;
|
return attack;
|
||||||
|
|
||||||
// No entry for this hand, fall back to the first natural 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) {
|
public static int calculatePetDamage(AbstractCharacter agent) {
|
||||||
|
|||||||
@@ -166,14 +166,6 @@ public enum ConfigManager {
|
|||||||
|
|
||||||
regex.put(MB_LOGIN_FNAME_REGEX, Pattern.compile(MB_LOGIN_FNAME_REGEX.getValue()));
|
regex.put(MB_LOGIN_FNAME_REGEX, Pattern.compile(MB_LOGIN_FNAME_REGEX.getValue()));
|
||||||
|
|
||||||
Logger.info("Loading WPAK data");
|
|
||||||
|
|
||||||
// *** Needs powermanager collection
|
|
||||||
// defined before activation.
|
|
||||||
// EffectsParser.parseWpakFile();
|
|
||||||
// PowersParser.parseWpakFile();
|
|
||||||
// PowerActionParser.parseWpakFile();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,8 +58,6 @@ public enum DbManager {
|
|||||||
public static final dbPromotionClassHandler PromotionQueries = new dbPromotionClassHandler();
|
public static final dbPromotionClassHandler PromotionQueries = new dbPromotionClassHandler();
|
||||||
public static final dbRaceHandler RaceQueries = new dbRaceHandler();
|
public static final dbRaceHandler RaceQueries = new dbRaceHandler();
|
||||||
public static final dbResistHandler ResistQueries = new dbResistHandler();
|
public static final dbResistHandler ResistQueries = new dbResistHandler();
|
||||||
public static final dbRuneBaseAttributeHandler RuneBaseAttributeQueries = new dbRuneBaseAttributeHandler();
|
|
||||||
public static final dbRuneBaseEffectHandler RuneBaseEffectQueries = new dbRuneBaseEffectHandler();
|
|
||||||
public static final dbRuneBaseHandler RuneBaseQueries = new dbRuneBaseHandler();
|
public static final dbRuneBaseHandler RuneBaseQueries = new dbRuneBaseHandler();
|
||||||
public static final dbSkillBaseHandler SkillsBaseQueries = new dbSkillBaseHandler();
|
public static final dbSkillBaseHandler SkillsBaseQueries = new dbSkillBaseHandler();
|
||||||
public static final dbSkillReqHandler SkillReqQueries = new dbSkillReqHandler();
|
public static final dbSkillReqHandler SkillReqQueries = new dbSkillReqHandler();
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ public enum DevCmdManager {
|
|||||||
DevCmdManager.registerDevCmd(new SetAdminRuneCmd());
|
DevCmdManager.registerDevCmd(new SetAdminRuneCmd());
|
||||||
DevCmdManager.registerDevCmd(new SetInvulCmd());
|
DevCmdManager.registerDevCmd(new SetInvulCmd());
|
||||||
DevCmdManager.registerDevCmd(new MakeItemCmd());
|
DevCmdManager.registerDevCmd(new MakeItemCmd());
|
||||||
|
DevCmdManager.registerDevCmd(new FillCmd());
|
||||||
DevCmdManager.registerDevCmd(new SetSubRaceCmd());
|
DevCmdManager.registerDevCmd(new SetSubRaceCmd());
|
||||||
// Admin
|
// Admin
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import engine.mbEnums;
|
|||||||
import engine.net.client.msg.ItemProductionMsg;
|
import engine.net.client.msg.ItemProductionMsg;
|
||||||
import engine.objects.City;
|
import engine.objects.City;
|
||||||
import engine.objects.Item;
|
import engine.objects.Item;
|
||||||
import engine.objects.ItemTemplate;
|
|
||||||
import engine.objects.NPC;
|
import engine.objects.NPC;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.powers.EffectsBase;
|
import engine.powers.EffectsBase;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
@@ -49,6 +49,9 @@ public enum ForgeManager implements Runnable {
|
|||||||
public static final ConcurrentHashMap<NPC, ConcurrentHashMap.KeySetView<WorkOrder, Boolean>> vendorWorkOrderLookup = new ConcurrentHashMap<>();
|
public static final ConcurrentHashMap<NPC, ConcurrentHashMap.KeySetView<WorkOrder, Boolean>> vendorWorkOrderLookup = new ConcurrentHashMap<>();
|
||||||
public static final ConcurrentHashMap<Item, WorkOrder> itemWorkOrderLookup = new ConcurrentHashMap<>();
|
public static final ConcurrentHashMap<Item, WorkOrder> itemWorkOrderLookup = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// Server-only data from static_vendor_items; the client templates have no mod table.
|
||||||
|
public static HashMap<Integer, Integer> vendorModTables = new HashMap<>();
|
||||||
|
|
||||||
public static void start() {
|
public static void start() {
|
||||||
|
|
||||||
Thread forgeManager;
|
Thread forgeManager;
|
||||||
@@ -222,12 +225,12 @@ public enum ForgeManager implements Runnable {
|
|||||||
// Calculate production cost for a single run of the workOrder
|
// Calculate production cost for a single run of the workOrder
|
||||||
|
|
||||||
HashMap<mbEnums.ResourceType, Integer> production_cost = new HashMap<>();
|
HashMap<mbEnums.ResourceType, Integer> production_cost = new HashMap<>();
|
||||||
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
|
CObjectTemplate template = CObjectTemplate.lookup(workOrder.templateID);
|
||||||
|
|
||||||
// Add gold and resource costs from template
|
// Add gold and resource costs from template
|
||||||
|
|
||||||
production_cost.put(mbEnums.ResourceType.GOLD, template.item_value);
|
production_cost.put(mbEnums.ResourceType.GOLD, template.getItemValue());
|
||||||
production_cost.putAll(template.item_resource_cost);
|
production_cost.putAll(template.getItemResourceCosts());
|
||||||
|
|
||||||
// Calculate cost of prefix and suffix
|
// Calculate cost of prefix and suffix
|
||||||
|
|
||||||
@@ -248,8 +251,8 @@ public enum ForgeManager implements Runnable {
|
|||||||
|
|
||||||
// Create new virtual item from specified template
|
// Create new virtual item from specified template
|
||||||
|
|
||||||
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
|
|
||||||
Item forgedItem = new Item(workOrder.templateID);
|
Item forgedItem = new Item(workOrder.templateID);
|
||||||
|
int modTable = getVendorModTable(workOrder.templateID);
|
||||||
|
|
||||||
// forgedItem gets a negative id; a virtual item which is not persisted
|
// forgedItem gets a negative id; a virtual item which is not persisted
|
||||||
|
|
||||||
@@ -264,13 +267,13 @@ public enum ForgeManager implements Runnable {
|
|||||||
|
|
||||||
// Assign a prefix and suffix to this item if random rolled
|
// Assign a prefix and suffix to this item if random rolled
|
||||||
|
|
||||||
if (workOrder.prefixToken == 0 && workOrder.vendor.getItemModTable().contains((template.modTable)))
|
if (workOrder.prefixToken == 0 && workOrder.vendor.getItemModTable().contains(modTable))
|
||||||
forgedItem.prefixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.PREFIX, template.modTable);
|
forgedItem.prefixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.PREFIX, modTable);
|
||||||
else
|
else
|
||||||
forgedItem.prefixToken = workOrder.prefixToken;
|
forgedItem.prefixToken = workOrder.prefixToken;
|
||||||
|
|
||||||
if (workOrder.suffixToken == 0 && workOrder.vendor.getItemModTable().contains((template.modTable)))
|
if (workOrder.suffixToken == 0 && workOrder.vendor.getItemModTable().contains(modTable))
|
||||||
forgedItem.suffixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.SUFFIX, template.modTable);
|
forgedItem.suffixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.SUFFIX, modTable);
|
||||||
else
|
else
|
||||||
forgedItem.suffixToken = workOrder.suffixToken;
|
forgedItem.suffixToken = workOrder.suffixToken;
|
||||||
|
|
||||||
@@ -364,6 +367,10 @@ public enum ForgeManager implements Runnable {
|
|||||||
DbManager.WarehouseQueries.WRITE_WORKORDER(workOrder);
|
DbManager.WarehouseQueries.WRITE_WORKORDER(workOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getVendorModTable(int templateID) {
|
||||||
|
return vendorModTables.getOrDefault(templateID, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public static int calcRandomMod(NPC vendor, mbEnums.ItemModType itemModType, int modTable) {
|
public static int calcRandomMod(NPC vendor, mbEnums.ItemModType itemModType, int modTable) {
|
||||||
|
|
||||||
// Random prefix or suffix token based on item.template.modtable
|
// Random prefix or suffix token based on item.template.modtable
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ public enum GroupManager {
|
|||||||
return false;
|
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;
|
return false;
|
||||||
|
|
||||||
Group group = getGroup(pc);
|
Group group = getGroup(pc);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package engine.gameManager;
|
|||||||
|
|
||||||
import engine.mbEnums;
|
import engine.mbEnums;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.powers.EffectsBase;
|
import engine.powers.EffectsBase;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
@@ -21,66 +22,46 @@ public enum ItemManager {
|
|||||||
|
|
||||||
public static final AtomicInteger lastNegativeID = new AtomicInteger(0);
|
public static final AtomicInteger lastNegativeID = new AtomicInteger(0);
|
||||||
|
|
||||||
|
// restrict true: the set is a blacklist; false: a whitelist. An empty set allows everyone.
|
||||||
|
|
||||||
public static Boolean ValidRace(Item item, mbEnums.MonsterType race) {
|
public static Boolean ValidRace(Item item, mbEnums.MonsterType race) {
|
||||||
|
|
||||||
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;
|
return true;
|
||||||
|
|
||||||
if (item.template.item_race_req.isEmpty() == false)
|
return races.contains(race) != restrict;
|
||||||
if (item.template.item_race_req.contains(race))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (item.template.item_race_res.isEmpty() == false)
|
|
||||||
if (item.template.item_race_res.contains(race) == false)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean ValidClass(Item item, mbEnums.ClassType base, mbEnums.ClassType profession) {
|
public static Boolean ValidClass(Item item, mbEnums.ClassType base, mbEnums.ClassType profession) {
|
||||||
|
|
||||||
// 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;
|
return true;
|
||||||
|
|
||||||
if (item.template.item_class_req.isEmpty() == false)
|
listed = classes.contains(base) || classes.contains(profession);
|
||||||
if (item.template.item_class_req.contains(base) || item.template.item_class_req.contains(profession))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (item.template.item_class_res.isEmpty() == false)
|
return listed != restrict;
|
||||||
if (item.template.item_class_res.contains(base) == false && item.template.item_class_res.contains(profession) == false)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean ValidDiscipline(Item item, EnumSet<mbEnums.DisciplineType> discs) {
|
public static Boolean ValidDiscipline(Item item, EnumSet<mbEnums.DisciplineType> discs) {
|
||||||
|
|
||||||
// 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;
|
return true;
|
||||||
|
|
||||||
EnumSet<mbEnums.DisciplineType> workSet = EnumSet.copyOf(discs);
|
workSet = EnumSet.copyOf(discs);
|
||||||
|
workSet.retainAll(disciplines);
|
||||||
|
|
||||||
if (item.template.item_disc_req.isEmpty() == false) {
|
return workSet.isEmpty() == restrict;
|
||||||
|
|
||||||
workSet.retainAll(item.template.item_disc_req);
|
|
||||||
|
|
||||||
if (workSet.isEmpty() == false)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.template.item_disc_res.isEmpty() == false) {
|
|
||||||
|
|
||||||
workSet.retainAll(item.template.item_disc_res);
|
|
||||||
|
|
||||||
if (workSet.isEmpty() == false)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean canCharacterEquip(Item item, AbstractCharacter character) {
|
public static Boolean canCharacterEquip(Item item, AbstractCharacter character) {
|
||||||
@@ -91,12 +72,12 @@ public enum ItemManager {
|
|||||||
|
|
||||||
CharacterSkill characterSkill;
|
CharacterSkill characterSkill;
|
||||||
|
|
||||||
if (item.template.item_skill_required.isEmpty())
|
if (item.template.getItemSkillReq().isEmpty())
|
||||||
return true;
|
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);
|
characterSkill = skills.get(skillRequired);
|
||||||
|
|
||||||
if (characterSkill == null)
|
if (characterSkill == null)
|
||||||
@@ -112,31 +93,31 @@ public enum ItemManager {
|
|||||||
|
|
||||||
public static boolean isTwoHanded(Item item) {
|
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 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 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) {
|
public static boolean isShield(Item item) {
|
||||||
|
|
||||||
if (item.template.item_skill_required.containsKey("Block"))
|
if (item.template.getItemSkillReq().containsKey("Block"))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
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 true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -150,7 +131,7 @@ public enum ItemManager {
|
|||||||
return false;
|
return false;
|
||||||
//Item not valid for slot
|
//Item not valid for slot
|
||||||
|
|
||||||
if (item.template.item_eq_slots_or.contains(slot) == false)
|
if (item.template.getItemEqSlotsOr().contains(slot) == false)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Slot is taken
|
// Slot is taken
|
||||||
@@ -165,7 +146,7 @@ public enum ItemManager {
|
|||||||
(slot == mbEnums.EquipSlotType.RHELD && equipped.get(mbEnums.EquipSlotType.LHELD) != null)))
|
(slot == mbEnums.EquipSlotType.RHELD && equipped.get(mbEnums.EquipSlotType.LHELD) != null)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (item.template.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)
|
if (equipped.get(slot) != null && equipped.get(slot).equals(item) == false)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -197,7 +178,7 @@ public enum ItemManager {
|
|||||||
|
|
||||||
//players can't wear 0 value items.
|
//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.ErrorPopupMsg;
|
||||||
import engine.net.client.msg.chat.ChatSystemMsg;
|
import engine.net.client.msg.chat.ChatSystemMsg;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -91,8 +92,8 @@ public enum LootManager {
|
|||||||
//lastly, check mobs inventory for godly or disc runes to send a server announcement
|
//lastly, check mobs inventory for godly or disc runes to send a server announcement
|
||||||
for (Item item : mob.getInventory()) {
|
for (Item item : mob.getInventory()) {
|
||||||
|
|
||||||
if ((item.templateID > 2499 && item.templateID <= 3050) || item.template.item_base_name.toLowerCase().contains("of the gods")) {
|
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.item_base_name + ". Are you tough enough to take it?");
|
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.setMessageType(10);
|
||||||
chatMsg.setChannel(mbEnums.ChatChannelType.SYSTEM.getChannelID());
|
chatMsg.setChannel(mbEnums.ChatChannelType.SYSTEM.getChannelID());
|
||||||
DispatchManager.dispatchMsgToAll(chatMsg);
|
DispatchManager.dispatchMsgToAll(chatMsg);
|
||||||
@@ -179,12 +180,12 @@ public enum LootManager {
|
|||||||
if (itemUUID == 0)
|
if (itemUUID == 0)
|
||||||
return null;
|
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);
|
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)
|
if (selectedRow.pModTable != 0)
|
||||||
try {
|
try {
|
||||||
@@ -374,7 +375,7 @@ public enum LootManager {
|
|||||||
if (chanceRoll > bse.dropChance)
|
if (chanceRoll > bse.dropChance)
|
||||||
return;
|
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)
|
if (lootItem != null)
|
||||||
mob.charItemManager.addItemToInventory(lootItem);
|
mob.charItemManager.addItemToInventory(lootItem);
|
||||||
@@ -422,14 +423,14 @@ public enum LootManager {
|
|||||||
|
|
||||||
//create the item from the table, quantity is always 1
|
//create the item from the table, quantity is always 1
|
||||||
|
|
||||||
MobLoot winnings = new MobLoot(playerCharacter, ItemTemplate.templates.get(selectedItem.templateID), 1, false);
|
MobLoot winnings = new MobLoot(playerCharacter, CObjectTemplate.lookup(selectedItem.templateID), 1, false);
|
||||||
|
|
||||||
if (winnings == null)
|
if (winnings == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//early exit if the inventory of the player will not old the item
|
//early exit if the inventory of the player will not old the item
|
||||||
|
|
||||||
if (itemMan.hasRoomInventory(winnings.template.item_wt) == false) {
|
if (itemMan.hasRoomInventory(winnings.template.getItemWt()) == false) {
|
||||||
ErrorPopupMsg.sendErrorPopup(playerCharacter, 21);
|
ErrorPopupMsg.sendErrorPopup(playerCharacter, 21);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,12 +19,14 @@ import engine.net.client.ClientConnection;
|
|||||||
import engine.net.client.msg.ErrorPopupMsg;
|
import engine.net.client.msg.ErrorPopupMsg;
|
||||||
import engine.net.client.msg.PetMsg;
|
import engine.net.client.msg.PetMsg;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.powers.EffectsBase;
|
import engine.powers.EffectsBase;
|
||||||
import engine.powers.RuneSkillAdjustEntry;
|
import engine.powers.RuneSkillAdjustEntry;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumMap;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
@@ -315,26 +317,26 @@ public enum NPCManager {
|
|||||||
//has main hand weapon
|
//has main hand weapon
|
||||||
Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD);
|
Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD);
|
||||||
|
|
||||||
if (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();
|
primaryStat = guard.getStatStrCurrent();
|
||||||
else
|
else
|
||||||
primaryStat = guard.getStatDexCurrent();
|
primaryStat = guard.getStatDexCurrent();
|
||||||
|
|
||||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + weapon.template.item_weapon_damage.values().iterator().next()[0]) * rankModifier) + primaryStat;
|
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() + weapon.template.item_weapon_damage.values().iterator().next()[1]) * 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 = weapon.template.item_weapon_wepspeed;
|
guard.speedHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed;
|
||||||
guard.rangeHandOne = weapon.template.item_weapon_max_range;
|
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)) {
|
} else if (guard.charItemManager.equipped.containsKey(mbEnums.EquipSlotType.LHELD) && !ItemManager.isShield(guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template)) {
|
||||||
//has off hand weapon
|
//has off hand weapon
|
||||||
Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD);
|
Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD);
|
||||||
if (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();
|
primaryStat = guard.getStatStrCurrent();
|
||||||
else
|
else
|
||||||
primaryStat = guard.getStatDexCurrent();
|
primaryStat = guard.getStatDexCurrent();
|
||||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + weapon.template.item_weapon_damage.values().iterator().next()[0]) * rankModifier) + primaryStat;
|
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() + weapon.template.item_weapon_damage.values().iterator().next()[1]) * 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 = weapon.template.item_weapon_wepspeed;
|
guard.speedHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed;
|
||||||
guard.rangeHandOne = weapon.template.item_weapon_max_range;
|
guard.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range;
|
||||||
} else {
|
} else {
|
||||||
primaryStat = guard.getStatStrCurrent();
|
primaryStat = guard.getStatStrCurrent();
|
||||||
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin()) * rankModifier) + primaryStat;
|
guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin()) * rankModifier) + primaryStat;
|
||||||
@@ -352,8 +354,8 @@ public enum NPCManager {
|
|||||||
int baseDef = guard.mobBase.getDefenseRating();
|
int baseDef = guard.mobBase.getDefenseRating();
|
||||||
int armorDefense = 0;
|
int armorDefense = 0;
|
||||||
for (Item equipped : guard.charItemManager.equipped.values())
|
for (Item equipped : guard.charItemManager.equipped.values())
|
||||||
if (equipped.template.item_type.equals(mbEnums.ItemType.ARMOR) || ItemManager.isShield(equipped.template))
|
if (equipped.template.getItemType().equals(mbEnums.ItemType.ARMOR) || ItemManager.isShield(equipped.template))
|
||||||
armorDefense += equipped.template.item_defense_rating;
|
armorDefense += engine.parsers.objects.ItemTemplate._items.get(equipped.templateID).item_defense_rating;
|
||||||
guard.defenseRating = dexterity + baseDef + armorDefense;
|
guard.defenseRating = dexterity + baseDef + armorDefense;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,9 +363,9 @@ public enum NPCManager {
|
|||||||
int strength = guard.getStatStrCurrent();
|
int strength = guard.getStatStrCurrent();
|
||||||
int baseAtr = guard.mobBase.getAttackRating();
|
int baseAtr = guard.mobBase.getAttackRating();
|
||||||
if (guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD) != null)
|
if (guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD) != null)
|
||||||
guard.atrHandOne = baseAtr + (int) ((strength * 0.5f) + ((int) guard.charItemManager.equipped.get(mbEnums.EquipSlotType.RHELD).template.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))
|
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
|
else
|
||||||
guard.atrHandOne = baseAtr;
|
guard.atrHandOne = baseAtr;
|
||||||
}
|
}
|
||||||
@@ -438,14 +440,17 @@ public enum NPCManager {
|
|||||||
|
|
||||||
public static void applyEquipmentResists(Mob mob) {
|
public static void applyEquipmentResists(Mob mob) {
|
||||||
|
|
||||||
|
EnumMap<mbEnums.DamageType, Float> armorResists;
|
||||||
|
|
||||||
if (mob.charItemManager.equipped.isEmpty())
|
if (mob.charItemManager.equipped.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (Item equipped : mob.charItemManager.equipped.values()) {
|
for (Item equipped : mob.charItemManager.equipped.values()) {
|
||||||
if (equipped.template.item_type.equals(mbEnums.ItemType.ARMOR)) {
|
if (equipped.template.getItemType().equals(mbEnums.ItemType.ARMOR)) {
|
||||||
mob.resists.setResist(mbEnums.DamageType.SLASHING, mob.resists.getResist(mbEnums.DamageType.SLASHING, 0) + equipped.template.combat_attack_resist.get("SLASHING"));
|
armorResists = equipped.template.getCombatAttackResist();
|
||||||
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.SLASHING, mob.resists.getResist(mbEnums.DamageType.SLASHING, 0) + armorResists.getOrDefault(mbEnums.DamageType.SLASHING, 0f));
|
||||||
mob.resists.setResist(mbEnums.DamageType.PIERCING, mob.resists.getResist(mbEnums.DamageType.PIERCING, 0) + equipped.template.combat_attack_resist.get("PIERCING"));
|
mob.resists.setResist(mbEnums.DamageType.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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,7 +471,7 @@ public enum NPCManager {
|
|||||||
if (skillBase == null)
|
if (skillBase == null)
|
||||||
continue;
|
continue;
|
||||||
if (entry.level <= mob.level)
|
if (entry.level <= mob.level)
|
||||||
if (mob.skills.containsKey(entry.name) == false)
|
if (mob.skills.containsKey(entry.skill_type) == false)
|
||||||
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank));
|
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank));
|
||||||
else
|
else
|
||||||
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank + mob.skills.get(entry.skill_type).getNumTrains()));
|
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank + mob.skills.get(entry.skill_type).getNumTrains()));
|
||||||
@@ -541,14 +546,14 @@ public enum NPCManager {
|
|||||||
|
|
||||||
public static long calcRollingDuration(NPC vendor, int templateID) {
|
public static long calcRollingDuration(NPC vendor, int templateID) {
|
||||||
|
|
||||||
ItemTemplate template = ItemTemplate.templates.get(templateID);
|
CObjectTemplate template = CObjectTemplate.lookup(templateID);
|
||||||
float rollingDuration;
|
float rollingDuration;
|
||||||
|
|
||||||
if (template == null)
|
if (template == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (template.item_bane_rank > 0)
|
if (template.getItemBaneRank() > 0)
|
||||||
return (long) (template.item_bane_rank * 60 * 60 * 3 * 1000 * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()));
|
return (long) (template.getItemBaneRank() * 60 * 60 * 3 * 1000 * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()));
|
||||||
|
|
||||||
if (vendor.building == null)
|
if (vendor.building == null)
|
||||||
return 600;
|
return 600;
|
||||||
|
|||||||
@@ -2255,12 +2255,12 @@ public enum PowersManager {
|
|||||||
if (pb.targetItem())
|
if (pb.targetItem())
|
||||||
return true;
|
return true;
|
||||||
// TODO add these checks later
|
// TODO add these checks later
|
||||||
else if (pb.targetArmor() && item.template.item_type.equals(ItemType.ARMOR))
|
else if (pb.targetArmor() && item.template.getItemType().equals(ItemType.ARMOR))
|
||||||
return true;
|
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;
|
return true;
|
||||||
else
|
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
|
} // How did we get here? all valid targets have been covered
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ import engine.gameManager.DbManager;
|
|||||||
import engine.gameManager.ForgeManager;
|
import engine.gameManager.ForgeManager;
|
||||||
import engine.mbEnums;
|
import engine.mbEnums;
|
||||||
import engine.objects.Item;
|
import engine.objects.Item;
|
||||||
import engine.objects.ItemTemplate;
|
|
||||||
import engine.objects.NPC;
|
import engine.objects.NPC;
|
||||||
import engine.objects.Warehouse;
|
import engine.objects.Warehouse;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
@@ -127,16 +127,16 @@ public class WorkOrder implements Delayed {
|
|||||||
|
|
||||||
int validation_result = 0;
|
int validation_result = 0;
|
||||||
|
|
||||||
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
|
CObjectTemplate template = CObjectTemplate.lookup(workOrder.templateID);
|
||||||
|
|
||||||
if (workOrder.vendor.getBuilding() == null)
|
if (workOrder.vendor.getBuilding() == null)
|
||||||
return 58; //58: The formula is beyond the means of this facility
|
return 58; //58: The formula is beyond the means of this facility
|
||||||
|
|
||||||
if (!workOrder.vendor.charItemManager.hasRoomInventory(template.item_wt))
|
if (!workOrder.vendor.charItemManager.hasRoomInventory(template.getItemWt()))
|
||||||
return 30; //30: That person cannot carry that item
|
return 30; //30: That person cannot carry that item
|
||||||
|
|
||||||
if ((workOrder.prefixToken != 0 || workOrder.suffixToken != 0) &&
|
if ((workOrder.prefixToken != 0 || workOrder.suffixToken != 0) &&
|
||||||
!workOrder.vendor.getItemModTable().contains((template.modTable)))
|
!workOrder.vendor.getItemModTable().contains(ForgeManager.getVendorModTable(workOrder.templateID)))
|
||||||
return 59; //59: This hireling does not have this formula
|
return 59; //59: This hireling does not have this formula
|
||||||
|
|
||||||
if (!Warehouse.calcCostOverrun(workOrder).isEmpty())
|
if (!Warehouse.calcCostOverrun(workOrder).isEmpty())
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class ActivateNPCMsgHandler extends AbstractClientMsgHandler {
|
|||||||
// Filter hirelings by slot type
|
// Filter hirelings by slot type
|
||||||
|
|
||||||
for (Item hirelings : player.getInventory()) {
|
for (Item hirelings : player.getInventory()) {
|
||||||
if (hirelings.template.item_type.equals(ItemType.EMPLOYMENTCONTRACT)) {
|
if (hirelings.template.getItemType().equals(ItemType.EMPLOYMENTCONTRACT)) {
|
||||||
|
|
||||||
contract = DbManager.ContractQueries.GET_CONTRACT(hirelings.templateID);
|
contract = DbManager.ContractQueries.GET_CONTRACT(hirelings.templateID);
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ public class AddItemToTradeWindowMsgHandler extends AbstractClientMsgHandler {
|
|||||||
if (!item.validForInventory(source.getClientConnection(), source, source.charItemManager))
|
if (!item.validForInventory(source.getClientConnection(), source, source.charItemManager))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!tradingWith.hasRoomTrade(item.template.item_wt)) {
|
if (!tradingWith.hasRoomTrade(item.template.getItemWt())) {
|
||||||
dispatch = Dispatch.borrow(source, msg);
|
dispatch = Dispatch.borrow(source, msg);
|
||||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import engine.net.client.msg.guild.GuildInfoMsg;
|
|||||||
import engine.objects.Guild;
|
import engine.objects.Guild;
|
||||||
import engine.objects.Item;
|
import engine.objects.Item;
|
||||||
import engine.objects.PlayerCharacter;
|
import engine.objects.PlayerCharacter;
|
||||||
|
import engine.parsers.objects.DeedTemplate;
|
||||||
import engine.util.StringUtils;
|
import engine.util.StringUtils;
|
||||||
|
|
||||||
public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
|
public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
|
||||||
@@ -42,6 +43,7 @@ public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
|
|||||||
Guild playerGuild;
|
Guild playerGuild;
|
||||||
|
|
||||||
Item charter;
|
Item charter;
|
||||||
|
DeedTemplate charterDeed;
|
||||||
Dispatch dispatch;
|
Dispatch dispatch;
|
||||||
|
|
||||||
msg = (GuildCreationFinalizeMsg) baseMsg;
|
msg = (GuildCreationFinalizeMsg) baseMsg;
|
||||||
@@ -65,7 +67,9 @@ public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler {
|
|||||||
|
|
||||||
// Item must be a valid charterType (type 10 in db)
|
// Item must be a valid charterType (type 10 in db)
|
||||||
|
|
||||||
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);
|
ErrorPopupMsg.sendErrorPopup(player, GuildManager.NO_CHARTER_FOUND);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,10 +238,10 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
|||||||
if (targetItem == null)
|
if (targetItem == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (targetItem.template.item_type.equals(ItemType.GOLD))
|
if (targetItem.template.getItemType().equals(ItemType.GOLD))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!vendor.charItemManager.hasRoomInventory(targetItem.template.item_wt)) {
|
if (!vendor.charItemManager.hasRoomInventory(targetItem.template.getItemWt())) {
|
||||||
ErrorPopupMsg.sendErrorPopup(player, 21);
|
ErrorPopupMsg.sendErrorPopup(player, 21);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -319,7 +319,7 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
|||||||
if (targetItem == null)
|
if (targetItem == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (targetItem.template.item_type.equals(ItemType.GOLD))
|
if (targetItem.template.getItemType().equals(ItemType.GOLD))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!vendor.charItemManager.doesCharOwnThisItem(targetItem.getObjectUUID()))
|
if (!vendor.charItemManager.doesCharOwnThisItem(targetItem.getObjectUUID()))
|
||||||
@@ -328,14 +328,14 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
|||||||
if (!vendor.charItemManager.inventoryContains(targetItem))
|
if (!vendor.charItemManager.inventoryContains(targetItem))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
itemValue = targetItem.template.item_value;
|
itemValue = targetItem.template.getItemValue();
|
||||||
|
|
||||||
if (vendor.getBuilding().getStrongboxValue() + itemValue > vendor.getBuilding().getMaxGold()) {
|
if (vendor.getBuilding().getStrongboxValue() + itemValue > vendor.getBuilding().getMaxGold()) {
|
||||||
ErrorPopupMsg.sendErrorPopup(player, 201);
|
ErrorPopupMsg.sendErrorPopup(player, 201);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (targetItem.template.item_type) {
|
switch (targetItem.template.getItemType()) {
|
||||||
case EMPLOYMENTCONTRACT:
|
case EMPLOYMENTCONTRACT:
|
||||||
case CHARTER:
|
case CHARTER:
|
||||||
case DEED:
|
case DEED:
|
||||||
@@ -465,13 +465,13 @@ public class ItemProductionMsgHandler extends AbstractClientMsgHandler {
|
|||||||
if (targetItem == null)
|
if (targetItem == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (targetItem.template.item_type.equals(ItemType.GOLD))
|
if (targetItem.template.getItemType().equals(ItemType.GOLD))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!vendor.charItemManager.inventoryContains(targetItem))
|
if (!vendor.charItemManager.inventoryContains(targetItem))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!player.charItemManager.hasRoomInventory(targetItem.template.item_wt))
|
if (!player.charItemManager.hasRoomInventory(targetItem.template.getItemWt()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
player.charItemManager.buyFromNPC(targetItem, vendor);
|
player.charItemManager.buyFromNPC(targetItem, vendor);
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
|
|||||||
if (itemRet == null)
|
if (itemRet == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
|
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) {
|
||||||
// this is done to prevent the temporary goldItem item
|
// this is done to prevent the temporary goldItem item
|
||||||
// (from the mob) from appearing in player's inventory.
|
// (from the mob) from appearing in player's inventory.
|
||||||
// It also updates the goldItem quantity display
|
// It also updates the goldItem quantity display
|
||||||
@@ -187,7 +187,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
|
|||||||
//TODO send group loot message if player is grouped and visible
|
//TODO send group loot message if player is grouped and visible
|
||||||
Group group = GroupManager.getGroup(player);
|
Group group = GroupManager.getGroup(player);
|
||||||
|
|
||||||
if (group != null && group.getSplitGold() && (item.template.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 name = item.getName();
|
||||||
String text = player.getFirstName() + " has looted " + name + '.';
|
String text = player.getFirstName() + " has looted " + name + '.';
|
||||||
ChatManager.chatGroupInfoCanSee(player, text);
|
ChatManager.chatGroupInfoCanSee(player, text);
|
||||||
@@ -202,7 +202,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
|
|||||||
if (itemRet == null)
|
if (itemRet == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
|
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) {
|
||||||
// this is done to prevent the temporary goldItem item
|
// this is done to prevent the temporary goldItem item
|
||||||
// (from the mob) from appearing in player's inventory.
|
// (from the mob) from appearing in player's inventory.
|
||||||
// It also updates the goldItem quantity display
|
// It also updates the goldItem quantity display
|
||||||
@@ -241,7 +241,7 @@ public class LootMsgHandler extends AbstractClientMsgHandler {
|
|||||||
//TODO send group loot message if player is grouped and visible
|
//TODO send group loot message if player is grouped and visible
|
||||||
Group group = GroupManager.getGroup(player);
|
Group group = GroupManager.getGroup(player);
|
||||||
|
|
||||||
if (group != null && group.getSplitGold() && (item.template.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 name = item.getName();
|
||||||
String text = player.getFirstName() + " has looted " + name + '.';
|
String text = player.getFirstName() + " has looted " + name + '.';
|
||||||
ChatManager.chatGroupInfoCanSee(player, text);
|
ChatManager.chatGroupInfoCanSee(player, text);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import engine.net.Dispatch;
|
|||||||
import engine.net.client.ClientConnection;
|
import engine.net.client.ClientConnection;
|
||||||
import engine.net.client.msg.*;
|
import engine.net.client.msg.*;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.DeedTemplate;
|
||||||
import engine.powers.PowersBase;
|
import engine.powers.PowersBase;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -78,7 +79,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
|||||||
|
|
||||||
int uuid = item.templateID;
|
int uuid = item.templateID;
|
||||||
|
|
||||||
switch (item.template.item_type) {
|
switch (item.template.getItemType()) {
|
||||||
|
|
||||||
case DEED: //buildings
|
case DEED: //buildings
|
||||||
//Call add building screen here, ib.getUseID() get's building ID
|
//Call add building screen here, ib.getUseID() get's building ID
|
||||||
@@ -99,7 +100,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
|||||||
pam.setX(loc.getX() + 64); //offset grid from tol
|
pam.setX(loc.getX() + 64); //offset grid from tol
|
||||||
pam.setY(loc.getY());
|
pam.setY(loc.getY());
|
||||||
pam.setZ(loc.getZ() + 64); //offset grid from tol
|
pam.setZ(loc.getZ() + 64); //offset grid from tol
|
||||||
pam.addPlacementInfo(item.template.deed_structure_id);
|
pam.addPlacementInfo(DeedTemplate._deeds.get(item.templateID).deed_structure_id);
|
||||||
|
|
||||||
dispatch = Dispatch.borrow(player, pam);
|
dispatch = Dispatch.borrow(player, pam);
|
||||||
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
|
DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
|
||||||
@@ -187,14 +188,14 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
|||||||
if (uuid > 680069 && uuid < 680074) //Handle Charter, Deed, Petition, Warrant here
|
if (uuid > 680069 && uuid < 680074) //Handle Charter, Deed, Petition, Warrant here
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (item.template.item_bane_rank > 0) {
|
if (item.template.getItemBaneRank() > 0) {
|
||||||
|
|
||||||
// Only one banestone at a time
|
// Only one banestone at a time
|
||||||
|
|
||||||
lock.writeLock().lock();
|
lock.writeLock().lock();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (Bane.summonBanestone(player, origin, item.template.item_bane_rank) == true)
|
if (Bane.summonBanestone(player, origin, item.template.getItemBaneRank()) == true)
|
||||||
itemMan.consume(item);
|
itemMan.consume(item);
|
||||||
} finally {
|
} finally {
|
||||||
lock.writeLock().unlock();
|
lock.writeLock().unlock();
|
||||||
@@ -225,7 +226,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
|||||||
|
|
||||||
// Bypass for waterbuckets
|
// 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
|
// test for valid target type
|
||||||
if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter)
|
if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter)
|
||||||
@@ -250,10 +251,9 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (waterbucketBypass == false) {
|
if (waterbucketBypass == false) {
|
||||||
String powerString = item.template.item_power_grant.keySet().iterator().next();
|
engine.parsers.objects.PowerGrant powerGrant = item.template.getItemPowerGrant().get(0);
|
||||||
PowersBase powerAction = PowersManager.powersBaseByIDString.get(powerString);
|
PowersBase powerAction = PowersManager.powersBaseByIDString.get(powerGrant.power_type);
|
||||||
int powerValue = item.template.item_power_grant.get(powerString);
|
PowersManager.applyPower(player, target, Vector3fImmutable.ZERO, powerAction.getToken(), powerGrant.power_value, true);
|
||||||
PowersManager.applyPower(player, target, Vector3fImmutable.ZERO, powerAction.getToken(), powerValue, true);
|
|
||||||
}
|
}
|
||||||
itemMan.consume(item);
|
itemMan.consume(item);
|
||||||
} else //just remove the item at this point
|
} else //just remove the item at this point
|
||||||
@@ -266,7 +266,8 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
|||||||
case RUNE:
|
case RUNE:
|
||||||
if(ApplyRuneMsg.applyRune(uuid, origin, player)) {
|
if(ApplyRuneMsg.applyRune(uuid, origin, player)) {
|
||||||
itemMan.consume(item);
|
itemMan.consume(item);
|
||||||
}
|
} else
|
||||||
|
ErrorPopupMsg.sendErrorPopup(player, 161);
|
||||||
break;
|
break;
|
||||||
default: //shouldn't be here, consume item
|
default: //shouldn't be here, consume item
|
||||||
dispatch = Dispatch.borrow(player, msg);
|
dispatch = Dispatch.borrow(player, msg);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import engine.net.client.msg.ErrorPopupMsg;
|
|||||||
import engine.net.client.msg.PlaceAssetMsg;
|
import engine.net.client.msg.PlaceAssetMsg;
|
||||||
import engine.net.client.msg.PlaceAssetMsg.PlacementInfo;
|
import engine.net.client.msg.PlaceAssetMsg.PlacementInfo;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.DeedTemplate;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
@@ -356,8 +357,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
|||||||
Item contract = null;
|
Item contract = null;
|
||||||
|
|
||||||
for (Item inventoryItem : playerCharacter.getInventory()) {
|
for (Item inventoryItem : playerCharacter.getInventory()) {
|
||||||
if (inventoryItem.template.item_type.equals(ItemType.DEED) &&
|
if (inventoryItem.template.getItemType().equals(ItemType.DEED) &&
|
||||||
inventoryItem.template.deed_structure_id == buildingList.getBlueprintUUID()) {
|
DeedTemplate._deeds.get(inventoryItem.templateID).deed_structure_id == buildingList.getBlueprintUUID()) {
|
||||||
contract = inventoryItem;
|
contract = inventoryItem;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public class RepairMsgHandler extends AbstractClientMsgHandler {
|
|||||||
//make sure item is damaged and not destroyed
|
//make sure item is damaged and not destroyed
|
||||||
|
|
||||||
short dur = (short) toRepair.combat_health_current;
|
short dur = (short) toRepair.combat_health_current;
|
||||||
short max = (short) toRepair.template.combat_health_full;
|
short max = (short) toRepair.template.getCombatHealthFull();
|
||||||
|
|
||||||
//account for durability modifications
|
//account for durability modifications
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class TransferItemFromBankMsgHandler extends AbstractClientMsgHandler {
|
|||||||
return true;
|
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()))
|
if (!itemManager.moveGoldToInventory(item, msg.getNumItems()))
|
||||||
return true;
|
return true;
|
||||||
@@ -85,7 +85,7 @@ public class TransferItemFromBankMsgHandler extends AbstractClientMsgHandler {
|
|||||||
|
|
||||||
// Not gold, process update here
|
// Not gold, process update here
|
||||||
|
|
||||||
if (!itemManager.hasRoomInventory(item.template.item_wt))
|
if (!itemManager.hasRoomInventory(item.template.getItemWt()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (itemManager.moveItemToInventory(item) == false)
|
if (itemManager.moveItemToInventory(item) == false)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class TransferItemToBankMsgHandler extends AbstractClientMsgHandler {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (item.containerType == mbEnums.ItemContainerType.INVENTORY && itemManager.isBankOpen())
|
if (item.containerType == mbEnums.ItemContainerType.INVENTORY && itemManager.isBankOpen())
|
||||||
if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) {
|
if (item.template.getItemType().equals(mbEnums.ItemType.GOLD)) {
|
||||||
if (!itemManager.moveGoldToBank(item, msg.getNumItems()))
|
if (!itemManager.moveGoldToBank(item, msg.getNumItems()))
|
||||||
return true;
|
return true;
|
||||||
UpdateGoldMsg goldMes = new UpdateGoldMsg(player);
|
UpdateGoldMsg goldMes = new UpdateGoldMsg(player);
|
||||||
@@ -76,7 +76,7 @@ public class TransferItemToBankMsgHandler extends AbstractClientMsgHandler {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (!itemManager.hasRoomBank(item.template.item_wt))
|
if (!itemManager.hasRoomBank(item.template.getItemWt()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!itemManager.moveItemToBank(item))
|
if (!itemManager.moveItemToBank(item))
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class VendorBuyMsgHandler extends AbstractClientMsgHandler {
|
|||||||
if (me.objectUUID == vendorBuyMsg.getItemID()) {
|
if (me.objectUUID == vendorBuyMsg.getItemID()) {
|
||||||
|
|
||||||
//test room available for item
|
//test room available for item
|
||||||
if (!itemMan.hasRoomInventory(me.template.item_wt))
|
if (!itemMan.hasRoomInventory(me.template.getItemWt()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
int cost = me.getValue();
|
int cost = me.getValue();
|
||||||
@@ -148,10 +148,10 @@ public class VendorBuyMsgHandler extends AbstractClientMsgHandler {
|
|||||||
|
|
||||||
//test room available for item
|
//test room available for item
|
||||||
|
|
||||||
if (!itemMan.hasRoomInventory(vendorItem.template.item_wt))
|
if (!itemMan.hasRoomInventory(vendorItem.template.getItemWt()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
int cost = vendorItem.template.item_value;
|
int cost = vendorItem.template.getItemValue();
|
||||||
|
|
||||||
if (vendorItem.flags.contains(mbEnums.ItemFlags.Identified) || vendorItem.isCustomValue())
|
if (vendorItem.flags.contains(mbEnums.ItemFlags.Identified) || vendorItem.isCustomValue())
|
||||||
cost = vendorItem.magicValue;
|
cost = vendorItem.magicValue;
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class VendorSellMsgHandler extends AbstractClientMsgHandler {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (npc.getParentZone() != null && npc.getParentZone().playerCityUUID != 0)
|
if (npc.getParentZone() != null && npc.getParentZone().playerCityUUID != 0)
|
||||||
if (!npc.charItemManager.hasRoomInventory(sell.template.item_wt)) {
|
if (!npc.charItemManager.hasRoomInventory(sell.template.getItemWt())) {
|
||||||
ErrorPopupMsg.sendErrorPopup(player, 21);
|
ErrorPopupMsg.sendErrorPopup(player, 21);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ public class VendorSellMsgHandler extends AbstractClientMsgHandler {
|
|||||||
|
|
||||||
//get goldItem cost to sell
|
//get goldItem cost to sell
|
||||||
|
|
||||||
cost = (int) (sell.template.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 bargain = player.getBargain();
|
||||||
float profit = npc.getBuyPercent(player) + bargain;
|
float profit = npc.getBuyPercent(player) + bargain;
|
||||||
|
|||||||
@@ -22,10 +22,17 @@ import engine.server.MBServerStatics;
|
|||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.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 {
|
public class ApplyRuneMsg extends ClientNetMsg {
|
||||||
|
|
||||||
|
// Client ArcCharacter_AddRune (0x4695D0)
|
||||||
|
private static final int MAX_TALENTS = 8;
|
||||||
|
|
||||||
private int targetType;
|
private int targetType;
|
||||||
private int targetID;
|
private int targetID;
|
||||||
private int removeRuneBase;
|
private int removeRuneBase;
|
||||||
@@ -78,67 +85,28 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check race is met
|
|
||||||
ConcurrentHashMap<Integer, Boolean> races = rb.getRace();
|
|
||||||
if (races.size() > 0) {
|
|
||||||
int raceID = playerCharacter.getRaceID();
|
|
||||||
boolean valid = false;
|
|
||||||
for (int validID : races.keySet()) {
|
|
||||||
if (validID == raceID) {
|
|
||||||
valid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!valid) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check base class is met
|
|
||||||
ConcurrentHashMap<Integer, Boolean> baseClasses = rb.getBaseClass();
|
|
||||||
if (baseClasses.size() > 0) {
|
|
||||||
int baseClassID = playerCharacter.getBaseClassID();
|
|
||||||
boolean valid = false;
|
|
||||||
for (int validID : baseClasses.keySet()) {
|
|
||||||
if (validID == baseClassID) {
|
|
||||||
valid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!valid) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check promotion class is met
|
|
||||||
ConcurrentHashMap<Integer, Boolean> promotionClasses = rb.getPromotionClass();
|
|
||||||
if (promotionClasses.size() > 0) {
|
|
||||||
int promotionClassID = playerCharacter.getPromotionClassID();
|
|
||||||
boolean valid = false;
|
|
||||||
for (int validID : promotionClasses.keySet()) {
|
|
||||||
if (validID == promotionClassID) {
|
|
||||||
valid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!valid) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check disciplines are met
|
|
||||||
ArrayList<CharacterRune> runes = playerCharacter.getRunes();
|
ArrayList<CharacterRune> runes = playerCharacter.getRunes();
|
||||||
ConcurrentHashMap<Integer, Boolean> disciplines = rb.getDiscipline();
|
HashSet<Integer> classIDs = new HashSet<>();
|
||||||
if (disciplines.size() > 0) {
|
HashSet<Integer> heldDiscIDs = new HashSet<>();
|
||||||
for (CharacterRune cr : runes) {
|
|
||||||
int runeBaseID = cr.getRuneBaseID();
|
// Client ArcCharacter_MeetsItemReqs (0x475F40)
|
||||||
for (Integer prohID : disciplines.keySet()) {
|
if (!meetsListReq(rb.getRace().keySet(), rb.isRaceRestrict(), Collections.singleton(playerCharacter.getRaceID())))
|
||||||
if (runeBaseID == prohID) {
|
return false;
|
||||||
return false; //Prohibited rune
|
|
||||||
}
|
// A listed base class covers its promotions: base or promotion listed is enough
|
||||||
}
|
classIDs.addAll(rb.getBaseClass().keySet());
|
||||||
}
|
classIDs.addAll(rb.getPromotionClass().keySet());
|
||||||
}
|
|
||||||
|
if (!meetsListReq(classIDs, rb.isClassRestrict(), Arrays.asList(playerCharacter.getBaseClassID(), playerCharacter.getPromotionClassID())))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Only the new rune's list is checked, not the held discs' lists
|
||||||
|
for (CharacterRune cr : runes)
|
||||||
|
if (isDiscipline(cr.getRuneBaseID()))
|
||||||
|
heldDiscIDs.add(cr.getRuneBaseID());
|
||||||
|
|
||||||
|
if (!meetsListReq(rb.getDiscipline().keySet(), rb.isDiscRestrict(), heldDiscIDs))
|
||||||
|
return false;
|
||||||
|
|
||||||
int discCount = 0;
|
int discCount = 0;
|
||||||
for (CharacterRune cr : runes) {
|
for (CharacterRune cr : runes) {
|
||||||
@@ -158,6 +126,32 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Client 0x4768D0 refuses a talent unless its rank beats the held one with the same sub type (rank 0 included);
|
||||||
|
// AddRune (0x4695D0) then replaces the held talent
|
||||||
|
CharacterRune replacedRune = null;
|
||||||
|
|
||||||
|
if (rb.getRuneType() == mbEnums.RuneType.TALENT) {
|
||||||
|
int talentCount = 0;
|
||||||
|
|
||||||
|
for (CharacterRune cr : runes) {
|
||||||
|
RuneBase heldRuneBase = cr.getRuneBase();
|
||||||
|
|
||||||
|
if (heldRuneBase == null || heldRuneBase.getRuneType() != mbEnums.RuneType.TALENT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
talentCount++;
|
||||||
|
|
||||||
|
if (rb.getSubTypeToken() != 0 && heldRuneBase.getSubTypeToken() == rb.getSubTypeToken())
|
||||||
|
replacedRune = cr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replacedRune != null) {
|
||||||
|
if (rb.getRank() <= replacedRune.getRuneBase().getRank())
|
||||||
|
return false;
|
||||||
|
} else if (talentCount >= MAX_TALENTS)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int strTotal = 0;
|
int strTotal = 0;
|
||||||
int dexTotal = 0;
|
int dexTotal = 0;
|
||||||
int conTotal = 0;
|
int conTotal = 0;
|
||||||
@@ -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 discipline, check number applied
|
||||||
if (isDiscipline(runeID)) {
|
if (isDiscipline(runeID)) {
|
||||||
if (playerCharacter.getLevel() < 70) {
|
if (playerCharacter.getLevel() < 70) {
|
||||||
@@ -259,13 +248,10 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//remove any overridden runes from player
|
//remove the replaced talent from player
|
||||||
ArrayList<Integer> overwrite = rb.getOverwrite();
|
|
||||||
CharacterRune toRemove = null;
|
CharacterRune toRemove = null;
|
||||||
if (overwrite.size() > 0) {
|
if (replacedRune != null) {
|
||||||
for (int overwriteID : overwrite) {
|
toRemove = playerCharacter.removeRune(replacedRune.getRuneBaseID());
|
||||||
toRemove = playerCharacter.removeRune(overwriteID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//add rune to player
|
//add rune to player
|
||||||
@@ -331,6 +317,21 @@ public class ApplyRuneMsg extends ClientNetMsg {
|
|||||||
return runeID > 3000 && runeID < 3050;
|
return runeID > 3000 && runeID < 3050;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Client ArcItemRestrict_Check (0x4BAC60). An empty list has no requirement; no rune has an empty whitelist.
|
||||||
|
private static boolean meetsListReq(Set<Integer> listedIDs, boolean restrict, Collection<Integer> heldIDs) {
|
||||||
|
|
||||||
|
boolean listed = false;
|
||||||
|
|
||||||
|
if (listedIDs.isEmpty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (int heldID : heldIDs)
|
||||||
|
if (listedIDs.contains(heldID))
|
||||||
|
listed = true;
|
||||||
|
|
||||||
|
return listed != restrict;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serializes the subclass specific items to the supplied NetMsgWriter.
|
* Serializes the subclass specific items to the supplied NetMsgWriter.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import engine.net.ByteBufferReader;
|
|||||||
import engine.net.ByteBufferWriter;
|
import engine.net.ByteBufferWriter;
|
||||||
import engine.net.Protocol;
|
import engine.net.Protocol;
|
||||||
import engine.objects.*;
|
import engine.objects.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.Period;
|
import org.joda.time.Period;
|
||||||
import org.joda.time.Seconds;
|
import org.joda.time.Seconds;
|
||||||
@@ -420,17 +421,18 @@ public class ManageNPCMsg extends ClientNetMsg {
|
|||||||
writer.putInt(rollableSet.size());
|
writer.putInt(rollableSet.size());
|
||||||
|
|
||||||
for (int templateID : rollableSet) {
|
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.put((byte) 1);
|
||||||
writer.putInt(0);
|
writer.putInt(0);
|
||||||
writer.putInt(templateID); //itemID
|
writer.putInt(templateID); //itemID
|
||||||
writer.putInt(template.item_value);
|
writer.putInt(template.getItemValue());
|
||||||
writer.putInt(600);
|
writer.putInt(600);
|
||||||
writer.put((byte) 1);
|
writer.put((byte) 1);
|
||||||
writer.put((byte) template.modTable);
|
writer.put((byte) modTable);
|
||||||
writer.put((byte) template.modTable);
|
writer.put((byte) modTable);
|
||||||
writer.put((byte) template.modTable);
|
writer.put((byte) modTable);
|
||||||
writer.put((byte) template.modTable);//EffectItemType
|
writer.put((byte) modTable);//EffectItemType
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<Item> cooking = NPCManager.getAllCookingForVendor(npc);
|
ArrayList<Item> cooking = NPCManager.getAllCookingForVendor(npc);
|
||||||
@@ -444,7 +446,7 @@ public class ManageNPCMsg extends ClientNetMsg {
|
|||||||
|
|
||||||
writer.putInt(0);
|
writer.putInt(0);
|
||||||
writer.putInt(item.templateID);
|
writer.putInt(item.templateID);
|
||||||
writer.putInt(item.template.item_value);
|
writer.putInt(item.template.getItemValue());
|
||||||
|
|
||||||
long timeLife = item.getDateToUpgrade() - System.currentTimeMillis();
|
long timeLife = item.getDateToUpgrade() - System.currentTimeMillis();
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class UpdateInventoryMsg extends ClientNetMsg {
|
|||||||
|
|
||||||
|
|
||||||
for (Item item : list) {
|
for (Item item : list) {
|
||||||
if (item.template.item_type.equals(ItemType.GOLD)) {
|
if (item.template.getItemType().equals(ItemType.GOLD)) {
|
||||||
if (item.getNumOfItems() == 0)
|
if (item.getNumOfItems() == 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import engine.net.ByteBufferWriter;
|
|||||||
import engine.net.Protocol;
|
import engine.net.Protocol;
|
||||||
import engine.objects.Item;
|
import engine.objects.Item;
|
||||||
import engine.objects.PlayerCharacter;
|
import engine.objects.PlayerCharacter;
|
||||||
|
import engine.parsers.objects.DeedTemplate;
|
||||||
|
|
||||||
|
|
||||||
public class UseCharterMsg extends ClientNetMsg {
|
public class UseCharterMsg extends ClientNetMsg {
|
||||||
@@ -61,9 +62,13 @@ public class UseCharterMsg extends ClientNetMsg {
|
|||||||
|
|
||||||
public void configure() {
|
public void configure() {
|
||||||
|
|
||||||
|
DeedTemplate charterDeed;
|
||||||
|
|
||||||
if (close) {
|
if (close) {
|
||||||
for (Item i : player.getInventory()) {
|
for (Item i : player.getInventory()) {
|
||||||
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();
|
charterUUID = i.getObjectUUID();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ public class VendorBuyWindowMsg extends ClientNetMsg {
|
|||||||
for (Item item : inventory) {
|
for (Item item : inventory) {
|
||||||
if (item.getOwnerID() != ownerID)
|
if (item.getOwnerID() != ownerID)
|
||||||
continue;
|
continue;
|
||||||
if (item.template.item_type.equals(ItemType.GOLD)) {
|
if (item.template.getItemType().equals(ItemType.GOLD)) {
|
||||||
if (item.getNumOfItems() == 0)
|
if (item.getNumOfItems() == 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ import engine.net.Dispatch;
|
|||||||
import engine.net.client.ClientConnection;
|
import engine.net.client.ClientConnection;
|
||||||
import engine.net.client.msg.ApplyRuneMsg;
|
import engine.net.client.msg.ApplyRuneMsg;
|
||||||
import engine.net.client.msg.UpdateStateMsg;
|
import engine.net.client.msg.UpdateStateMsg;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
|
import engine.parsers.objects.RuneTemplate;
|
||||||
import engine.powers.EffectsBase;
|
import engine.powers.EffectsBase;
|
||||||
import engine.powers.PowersBase;
|
import engine.powers.PowersBase;
|
||||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||||
@@ -652,11 +654,11 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
AssignDefenseValue(abstractCharacter);
|
AssignDefenseValue(abstractCharacter);
|
||||||
// calculate atr and damage for each hand
|
// calculate atr and damage for each hand
|
||||||
ConcurrentHashMap<EquipSlotType, Item> equipped = abstractCharacter.charItemManager.getEquipped();
|
ConcurrentHashMap<EquipSlotType, Item> equipped = abstractCharacter.charItemManager.getEquipped();
|
||||||
AssignDamageAtrForPlayers(abstractCharacter, equipped.get(EquipSlotType.RHELD), true, equipped.get(EquipSlotType.RHELD));
|
AssignDamageAtrForPlayers(abstractCharacter, equipped.get(EquipSlotType.RHELD), true, equipped.get(EquipSlotType.LHELD));
|
||||||
AssignDamageAtrForPlayers(abstractCharacter, equipped.get(EquipSlotType.LHELD), false, equipped.get(EquipSlotType.LHELD));
|
AssignDamageAtrForPlayers(abstractCharacter, equipped.get(EquipSlotType.LHELD), false, equipped.get(EquipSlotType.RHELD));
|
||||||
if (abstractCharacter.getObjectType().equals(GameObjectType.Mob)) {
|
if (abstractCharacter.getObjectType().equals(GameObjectType.Mob)) {
|
||||||
Mob mob = (Mob) abstractCharacter;
|
Mob mob = (Mob) abstractCharacter;
|
||||||
ItemTemplate rune = ItemTemplate.templates.get(mob.loadID);
|
RuneTemplate rune = RuneTemplate._runes.get(mob.loadID);
|
||||||
float minDamage = mob.mobBase.getDamageMin();
|
float minDamage = mob.mobBase.getDamageMin();
|
||||||
float maxDamage = mob.mobBase.getDamageMax();
|
float maxDamage = mob.mobBase.getDamageMax();
|
||||||
int attackRating = mob.mobBase.getAttackRating();
|
int attackRating = mob.mobBase.getAttackRating();
|
||||||
@@ -691,16 +693,17 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
|
|
||||||
// make sure weapon exists
|
// make sure weapon exists
|
||||||
boolean noWeapon = false;
|
boolean noWeapon = false;
|
||||||
ItemTemplate weaponTemplate = null;
|
CObjectTemplate weaponTemplate = null;
|
||||||
|
engine.parsers.objects.ItemTemplate.Damage damage;
|
||||||
|
|
||||||
if (weapon == null)
|
if (weapon == null)
|
||||||
noWeapon = true;
|
noWeapon = true;
|
||||||
else {
|
else {
|
||||||
ItemTemplate itemTemplate = weapon.template;
|
CObjectTemplate itemTemplate = weapon.template;
|
||||||
|
|
||||||
if (itemTemplate == null)
|
if (itemTemplate == null)
|
||||||
noWeapon = true;
|
noWeapon = true;
|
||||||
else if (!weapon.template.item_type.equals(ItemType.WEAPON)) {
|
else if (!weapon.template.getItemType().equals(ItemType.WEAPON)) {
|
||||||
defaultAtrAndDamage(abstractCharacter, mainHand);
|
defaultAtrAndDamage(abstractCharacter, mainHand);
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
@@ -717,7 +720,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
if (noWeapon) {
|
if (noWeapon) {
|
||||||
if (mainHand) {
|
if (mainHand) {
|
||||||
Item off = abstractCharacter.charItemManager.getEquipped().get(EquipSlotType.LHELD);
|
Item off = abstractCharacter.charItemManager.getEquipped().get(EquipSlotType.LHELD);
|
||||||
if (off != null && off.template != null && off.template.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
|
abstractCharacter.rangeHandOne = 10 * (1 + (abstractCharacter.statStrBase / 600)); // Set
|
||||||
// to
|
// to
|
||||||
// no
|
// no
|
||||||
@@ -750,9 +753,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (mainHand)
|
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
|
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) {
|
if (abstractCharacter.bonuses != null) {
|
||||||
float range_bonus = 1 + abstractCharacter.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.None);
|
float range_bonus = 1 + abstractCharacter.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.None);
|
||||||
@@ -764,20 +767,20 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
skillPercentage = getModifiedAmount(abstractCharacter.skills.get(weapon.template.item_skill_used));
|
skillPercentage = getModifiedAmount(abstractCharacter.skills.get(weapon.template.getItemSkillUsed()));
|
||||||
masteryPercentage = getModifiedAmount(abstractCharacter.skills.get(weaponTemplate.item_skill_mastery_used));
|
masteryPercentage = getModifiedAmount(abstractCharacter.skills.get(weaponTemplate.getItemSkillMasteryUsed()));
|
||||||
|
|
||||||
if (masteryPercentage == 0f)
|
if (masteryPercentage == 0f)
|
||||||
mastDam = 0f;
|
mastDam = 0f;
|
||||||
// mastDam = CharacterSkill.getQuickMastery(this, wb.getMastery());
|
// mastDam = CharacterSkill.getQuickMastery(this, wb.getMastery());
|
||||||
else
|
else
|
||||||
mastDam = masteryPercentage;
|
mastDam = masteryPercentage;
|
||||||
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];
|
min = damage.damage_min;
|
||||||
max = damages[1];
|
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"))
|
if (abstractCharacter.effects != null && abstractCharacter.effects.containsKey("DeathShroud"))
|
||||||
@@ -826,7 +829,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
|
|
||||||
//calculate speed
|
//calculate speed
|
||||||
if (weaponTemplate != null)
|
if (weaponTemplate != null)
|
||||||
speed = weaponTemplate.item_weapon_wepspeed;
|
speed = engine.parsers.objects.ItemTemplate.getWeapon(weaponTemplate.getTemplateId()).weapon_wepspeed;
|
||||||
else
|
else
|
||||||
speed = 20f; //unarmed attack speed
|
speed = 20f; //unarmed attack speed
|
||||||
if (weapon != null)
|
if (weapon != null)
|
||||||
@@ -881,15 +884,12 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
max *= percentMaxDamage;
|
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) {
|
if (!noWeapon && otherHand != null && otherHand.template != null
|
||||||
ItemTemplate ibo = otherHand.template;
|
&& otherHand.template.getItemType().equals(ItemType.WEAPON)) {
|
||||||
|
min *= 0.7f;
|
||||||
if (ibo != null && otherHand.template.equals(ItemType.WEAPON)) {
|
max *= 0.7f;
|
||||||
min *= 0.7f;
|
|
||||||
max *= 0.7f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate damage
|
// calculate damage
|
||||||
@@ -955,7 +955,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
if (ItemManager.isShield(shield) == false)
|
if (ItemManager.isShield(shield) == false)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ItemTemplate template = shield.template;
|
CObjectTemplate template = shield.template;
|
||||||
|
|
||||||
if (template == null)
|
if (template == null)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -969,7 +969,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
} else
|
} else
|
||||||
skillMod = blockSkill.getModifiedAmount();
|
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
|
//apply item defense bonuses
|
||||||
|
|
||||||
@@ -991,29 +991,30 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
if (armor == null)
|
if (armor == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ItemTemplate template = armor.template;
|
CObjectTemplate template = armor.template;
|
||||||
|
|
||||||
if (template == null)
|
if (template == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!armor.template.item_type.equals(ItemType.ARMOR))
|
if (!armor.template.getItemType().equals(ItemType.ARMOR))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (armor.template.item_skill_used.isEmpty())
|
// "Cloth" is a placeholder in Skills.cfg (token 0) that no character learns
|
||||||
return template.item_defense_rating;
|
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) {
|
if (abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter) && armorSkill == null) {
|
||||||
Logger.error("Player " + abstractCharacter.getObjectUUID()
|
Logger.error("Player " + abstractCharacter.getObjectUUID()
|
||||||
+ " has armor equipped without the nescessary skill to equip it");
|
+ " has armor equipped without the nescessary skill to equip it");
|
||||||
return template.item_defense_rating;
|
return engine.parsers.objects.ItemTemplate._items.get(armor.templateID).item_defense_rating;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (armorSkill == null)
|
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
|
//apply item defense bonuses
|
||||||
|
|
||||||
@@ -1031,7 +1032,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
private static float getWeaponDefense(AbstractCharacter abstractCharacter, ConcurrentHashMap<EquipSlotType, Item> equipped) {
|
private static float getWeaponDefense(AbstractCharacter abstractCharacter, ConcurrentHashMap<EquipSlotType, Item> equipped) {
|
||||||
|
|
||||||
Item weapon = equipped.get(EquipSlotType.RHELD);
|
Item weapon = equipped.get(EquipSlotType.RHELD);
|
||||||
ItemTemplate weaponTemplate = null;
|
CObjectTemplate weaponTemplate = null;
|
||||||
CharacterSkill skill, mastery;
|
CharacterSkill skill, mastery;
|
||||||
float val = 0;
|
float val = 0;
|
||||||
boolean unarmed = false;
|
boolean unarmed = false;
|
||||||
@@ -1052,8 +1053,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
skill = abstractCharacter.skills.get("Unarmed Combat");
|
skill = abstractCharacter.skills.get("Unarmed Combat");
|
||||||
mastery = abstractCharacter.skills.get("Unarmed Combat Mastery");
|
mastery = abstractCharacter.skills.get("Unarmed Combat Mastery");
|
||||||
} else {
|
} else {
|
||||||
skill = abstractCharacter.skills.get(weapon.template.item_skill_used);
|
skill = abstractCharacter.skills.get(weapon.template.getItemSkillUsed());
|
||||||
mastery = abstractCharacter.skills.get(weaponTemplate.item_skill_mastery_used);
|
mastery = abstractCharacter.skills.get(weaponTemplate.getItemSkillMasteryUsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skill != null)
|
if (skill != null)
|
||||||
@@ -1088,7 +1089,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
|
|
||||||
for (Item item : equipped.values()) {
|
for (Item item : equipped.values()) {
|
||||||
|
|
||||||
ItemTemplate ib = item.template;
|
CObjectTemplate ib = item.template;
|
||||||
|
|
||||||
if (ib == null)
|
if (ib == null)
|
||||||
continue;
|
continue;
|
||||||
@@ -1507,9 +1508,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
|
|||||||
}
|
}
|
||||||
float range = 8;
|
float range = 8;
|
||||||
if ((this).charItemManager.equipped.get(EquipSlotType.RHELD) != null) {
|
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) {
|
} 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 {
|
} else {
|
||||||
|
|
||||||
// Unarmed: use the rune natural attack range when it has one (e.g. Gasser 150), not clamped.
|
// 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());
|
this.vault = DbManager.ItemQueries.GET_ITEMS_FOR_ACCOUNT(this.getObjectUUID());
|
||||||
|
|
||||||
for (Item item : this.vault) {
|
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;
|
this.vaultGold = item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,7 +216,7 @@ public class Account extends AbstractGameObject {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (item.containerType == mbEnums.ItemContainerType.INVENTORY && player.charItemManager.isVaultOpen()) {
|
if (item.containerType == mbEnums.ItemContainerType.INVENTORY && player.charItemManager.isVaultOpen()) {
|
||||||
if (!player.charItemManager.hasRoomVault(item.template.item_wt)) {
|
if (!player.charItemManager.hasRoomVault(item.template.getItemWt())) {
|
||||||
ItemToVaultMsgHandler.forceTransferFromVaultToInventory(msg, origin, "There is no room in your vault.");
|
ItemToVaultMsgHandler.forceTransferFromVaultToInventory(msg, origin, "There is no room in your vault.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -262,7 +262,7 @@ public class Account extends AbstractGameObject {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (item.containerType == mbEnums.ItemContainerType.VAULT && itemManager.isVaultOpen()) {
|
if (item.containerType == mbEnums.ItemContainerType.VAULT && itemManager.isVaultOpen()) {
|
||||||
if (!itemManager.hasRoomInventory(item.template.item_wt)) {
|
if (!itemManager.hasRoomInventory(item.template.getItemWt())) {
|
||||||
ItemFromVaultMsgHandler.forceTransferFromInventoryToVault(msg, origin, "There is no room in your inventory.");
|
ItemFromVaultMsgHandler.forceTransferFromInventoryToVault(msg, origin, "There is no room in your inventory.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,12 @@
|
|||||||
package engine.objects;
|
package engine.objects;
|
||||||
|
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
|
import engine.mbEnums;
|
||||||
import engine.net.ByteBufferWriter;
|
import engine.net.ByteBufferWriter;
|
||||||
|
import engine.parsers.objects.RuneTemplate;
|
||||||
|
import engine.util.Hasher;
|
||||||
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
||||||
@@ -82,30 +84,41 @@ public class BaseClass extends AbstractGameObject {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ResultSet Constructor
|
* Rune Template Constructor
|
||||||
*/
|
*/
|
||||||
public BaseClass(ResultSet rs) throws SQLException {
|
public BaseClass(RuneTemplate rune) {
|
||||||
super(rs);
|
super(rune.template_id);
|
||||||
|
|
||||||
this.name = rs.getString("name");
|
this.name = rune.obj_name;
|
||||||
this.description = rs.getString("description");
|
this.description = rune.rune_dsc;
|
||||||
this.strMod = rs.getByte("strMod");
|
this.strMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Strength, 0).byteValue();
|
||||||
this.dexMod = rs.getByte("dexMod");
|
this.dexMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Dexterity, 0).byteValue();
|
||||||
this.conMod = rs.getByte("conMod");
|
this.conMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Constitution, 0).byteValue();
|
||||||
this.intMod = rs.getByte("intMod");
|
this.intMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Intelligence, 0).byteValue();
|
||||||
this.spiMod = rs.getByte("spiMod");
|
this.spiMod = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Spirit, 0).byteValue();
|
||||||
this.token = rs.getInt("token");
|
this.token = Hasher.SBStringHash(rune.rune_sub_type);
|
||||||
this.healthMod = rs.getInt("healthMod");
|
this.healthMod = rune.rune_health;
|
||||||
this.manaMod = rs.getInt("manaMod");
|
this.manaMod = rune.rune_mana;
|
||||||
this.staminaMod = rs.getInt("staminaMod");
|
this.staminaMod = rune.rune_stamina;
|
||||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.getObjectUUID());
|
this.skillsGranted = SkillReq.getSkillReqsForRune(this.getObjectUUID());
|
||||||
this.powersGranted = PowerReq.getPowerReqsForRune(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() {
|
public static void LoadAllBaseClasses() {
|
||||||
DbManager.BaseClassQueries.GET_ALL_BASE_CLASSES();
|
|
||||||
|
int loadedCount = 0;
|
||||||
|
|
||||||
|
// Promotion classes and the Pet class are also CLASS runes, but not standard creation runes
|
||||||
|
for (RuneTemplate rune : RuneTemplate._runes.values()) {
|
||||||
|
if (rune.rune_type != mbEnums.RuneType.CLASS || !rune.rune_is_standard_character_creation)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DbManager.addToCache(new BaseClass(rune));
|
||||||
|
loadedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info("Loaded " + loadedCount + " base classes from runes");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void serializeForClientMsg(BaseClass baseClass, ByteBufferWriter writer) {
|
public static void serializeForClientMsg(BaseClass baseClass, ByteBufferWriter writer) {
|
||||||
@@ -187,10 +200,6 @@ public class BaseClass extends AbstractGameObject {
|
|||||||
return this.powersGranted;
|
return this.powersGranted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
|
||||||
return RuneBaseEffect.RuneIDBaseEffectMap.get(this.getObjectUUID());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utils
|
* Utils
|
||||||
*/
|
*/
|
||||||
@@ -199,10 +208,6 @@ public class BaseClass extends AbstractGameObject {
|
|||||||
if (this.getRuneList().contains(rb.getObjectUUID()))
|
if (this.getRuneList().contains(rb.getObjectUUID()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (RuneBase.AllowedBaseClassRunesMap.containsKey(111111)) {
|
|
||||||
if (RuneBase.AllowedBaseClassRunesMap.get(111111).contains(rb.getObjectUUID()))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import engine.mbEnums.ItemType;
|
|||||||
import engine.net.Dispatch;
|
import engine.net.Dispatch;
|
||||||
import engine.net.client.ClientConnection;
|
import engine.net.client.ClientConnection;
|
||||||
import engine.net.client.msg.*;
|
import engine.net.client.msg.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
@@ -130,19 +131,19 @@ public class CharacterItemManager {
|
|||||||
this.equipped.put(i.equipSlot, i);
|
this.equipped.put(i.equipSlot, i);
|
||||||
break;
|
break;
|
||||||
case BANK:
|
case BANK:
|
||||||
if (i.template.item_type.equals(ItemType.GOLD))
|
if (i.template.getItemType().equals(ItemType.GOLD))
|
||||||
this.goldBank = i;
|
this.goldBank = i;
|
||||||
else if (this.bank.contains(i) == false)
|
else if (this.bank.contains(i) == false)
|
||||||
this.bank.add(i);
|
this.bank.add(i);
|
||||||
break;
|
break;
|
||||||
case INVENTORY:
|
case INVENTORY:
|
||||||
if (i.template.item_type.equals(ItemType.GOLD))
|
if (i.template.getItemType().equals(ItemType.GOLD))
|
||||||
this.goldInventory = i;
|
this.goldInventory = i;
|
||||||
else if (this.inventory.contains(i) == false)
|
else if (this.inventory.contains(i) == false)
|
||||||
this.inventory.add(i);
|
this.inventory.add(i);
|
||||||
break;
|
break;
|
||||||
case VAULT:
|
case VAULT:
|
||||||
if (i.template.item_type.equals(ItemType.GOLD))
|
if (i.template.getItemType().equals(ItemType.GOLD))
|
||||||
this.goldVault = i;
|
this.goldVault = i;
|
||||||
else if (this.vault.contains(i) == false)
|
else if (this.vault.contains(i) == false)
|
||||||
this.vault.add(i);
|
this.vault.add(i);
|
||||||
@@ -175,13 +176,13 @@ public class CharacterItemManager {
|
|||||||
this.equipped.put(i.equipSlot, i);
|
this.equipped.put(i.equipSlot, i);
|
||||||
break;
|
break;
|
||||||
case BANK:
|
case BANK:
|
||||||
if (i.template.item_type.equals(ItemType.GOLD))
|
if (i.template.getItemType().equals(ItemType.GOLD))
|
||||||
this.goldBank = i;
|
this.goldBank = i;
|
||||||
else if (this.bank.contains(i) == false)
|
else if (this.bank.contains(i) == false)
|
||||||
this.bank.add(i);
|
this.bank.add(i);
|
||||||
break;
|
break;
|
||||||
case INVENTORY:
|
case INVENTORY:
|
||||||
if (i.template.item_type.equals(ItemType.GOLD))
|
if (i.template.getItemType().equals(ItemType.GOLD))
|
||||||
this.goldInventory = i;
|
this.goldInventory = i;
|
||||||
else if (this.inventory.contains(i) == false)
|
else if (this.inventory.contains(i) == false)
|
||||||
this.inventory.add(i);
|
this.inventory.add(i);
|
||||||
@@ -511,7 +512,7 @@ public class CharacterItemManager {
|
|||||||
if (i == null)
|
if (i == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (i.template.item_type.equals(ItemType.GOLD)) {
|
if (i.template.getItemType().equals(ItemType.GOLD)) {
|
||||||
if (this.getGoldInventory() != null) {
|
if (this.getGoldInventory() != null) {
|
||||||
if (i.getObjectUUID() == this.getGoldInventory().getObjectUUID())
|
if (i.getObjectUUID() == this.getGoldInventory().getObjectUUID())
|
||||||
this.goldInventory = null;
|
this.goldInventory = null;
|
||||||
@@ -541,7 +542,7 @@ public class CharacterItemManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private synchronized boolean junk(Item i, boolean updateInventory) {
|
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 (this.getGoldInventory().getObjectUUID() == i.getObjectUUID())
|
||||||
if (DbManager.ItemQueries.UPDATE_GOLD(i, 0)) {
|
if (DbManager.ItemQueries.UPDATE_GOLD(i, 0)) {
|
||||||
this.getGoldInventory().setNumOfItems(0);
|
this.getGoldInventory().setNumOfItems(0);
|
||||||
@@ -596,7 +597,7 @@ public class CharacterItemManager {
|
|||||||
|
|
||||||
if (equippedContains(item)) {
|
if (equippedContains(item)) {
|
||||||
fromEquip = true;
|
fromEquip = true;
|
||||||
if (item.template.item_type.equals(ItemType.GOLD))
|
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||||
this.absCharacter.cancelOnUnEquip();
|
this.absCharacter.cancelOnUnEquip();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -814,7 +815,7 @@ public class CharacterItemManager {
|
|||||||
|
|
||||||
// This removes ingame item from inventory for loot.
|
// This removes ingame item from inventory for loot.
|
||||||
private synchronized boolean removeItemFromInventory(Item i) {
|
private synchronized boolean removeItemFromInventory(Item i) {
|
||||||
if (i.template.item_type.equals(ItemType.GOLD)) {
|
if (i.template.getItemType().equals(ItemType.GOLD)) {
|
||||||
if (i.getObjectUUID() != this.getGoldInventory().getObjectUUID())
|
if (i.getObjectUUID() != this.getGoldInventory().getObjectUUID())
|
||||||
return false;
|
return false;
|
||||||
if (!DbManager.ItemQueries.UPDATE_GOLD(this.goldInventory, 0)) {
|
if (!DbManager.ItemQueries.UPDATE_GOLD(this.goldInventory, 0)) {
|
||||||
@@ -837,7 +838,7 @@ public class CharacterItemManager {
|
|||||||
|
|
||||||
// This adds item to inventory for loot. Validity checks already handled
|
// This adds item to inventory for loot. Validity checks already handled
|
||||||
public synchronized boolean addItemToInventory(Item i) {
|
public synchronized boolean addItemToInventory(Item i) {
|
||||||
if (i.template.item_type.equals(ItemType.GOLD))
|
if (i.template.getItemType().equals(ItemType.GOLD))
|
||||||
if (this.absCharacter.getObjectType() == GameObjectType.Mob) {
|
if (this.absCharacter.getObjectType() == GameObjectType.Mob) {
|
||||||
if (this.goldInventory == null)
|
if (this.goldInventory == null)
|
||||||
loadGoldItems();
|
loadGoldItems();
|
||||||
@@ -856,7 +857,7 @@ public class CharacterItemManager {
|
|||||||
this.itemIDtoType.put(i.getObjectUUID(), i.getObjectType().ordinal());
|
this.itemIDtoType.put(i.getObjectUUID(), i.getObjectType().ordinal());
|
||||||
|
|
||||||
if (i.template != null)
|
if (i.template != null)
|
||||||
this.inventoryWeight += i.template.item_wt;
|
this.inventoryWeight += i.template.getItemWt();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1041,7 +1042,7 @@ public class CharacterItemManager {
|
|||||||
if (npc.getContractID() >= 1900 && npc.getContractID() <= 1906)
|
if (npc.getContractID() >= 1900 && npc.getContractID() <= 1906)
|
||||||
eatItem = true;
|
eatItem = true;
|
||||||
|
|
||||||
if (itemToSell.template.item_type.equals(ItemType.POTION))
|
if (itemToSell.template.getItemType().equals(ItemType.POTION))
|
||||||
eatItem = true;
|
eatItem = true;
|
||||||
|
|
||||||
if (eatItem) {
|
if (eatItem) {
|
||||||
@@ -1085,14 +1086,14 @@ public class CharacterItemManager {
|
|||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
synchronized (itemMan) {
|
synchronized (itemMan) {
|
||||||
ItemTemplate template = purchasedItem.template;
|
CObjectTemplate template = purchasedItem.template;
|
||||||
|
|
||||||
if (template == null)
|
if (template == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//test inventory is not full
|
//test inventory is not full
|
||||||
|
|
||||||
if (!hasRoomInventory(template.item_wt))
|
if (!hasRoomInventory(template.getItemWt()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!itemMan.inventory.contains(purchasedItem))
|
if (!itemMan.inventory.contains(purchasedItem))
|
||||||
@@ -1105,8 +1106,8 @@ public class CharacterItemManager {
|
|||||||
|
|
||||||
// Reset value
|
// Reset value
|
||||||
|
|
||||||
purchasedItem.value = (int) (purchasedItem.template.item_value * (purchasedItem.combat_health_current / purchasedItem.template.combat_health_full));
|
purchasedItem.value = (int) (purchasedItem.template.getItemValue() * (purchasedItem.combat_health_current / purchasedItem.template.getCombatHealthFull()));
|
||||||
purchasedItem.magicValue = purchasedItem.template.item_value + purchasedItem.calcMagicValue();
|
purchasedItem.magicValue = purchasedItem.template.getItemValue() + purchasedItem.calcMagicValue();
|
||||||
|
|
||||||
// db transfer successfully, remove from this character
|
// db transfer successfully, remove from this character
|
||||||
// skip this check if this is a mobLoot item (which is not in any inventory)
|
// skip this check if this is a mobLoot item (which is not in any inventory)
|
||||||
@@ -1184,9 +1185,9 @@ public class CharacterItemManager {
|
|||||||
synchronized (lockFirst) {
|
synchronized (lockFirst) {
|
||||||
synchronized (lockSecond) {
|
synchronized (lockSecond) {
|
||||||
// make sure current player has item in inventory
|
// make sure current player has item in inventory
|
||||||
if (lootItem.template.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;
|
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;
|
return null;
|
||||||
|
|
||||||
// get weight of item
|
// get weight of item
|
||||||
@@ -1194,13 +1195,13 @@ public class CharacterItemManager {
|
|||||||
if (lootItem.template == null)
|
if (lootItem.template == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
int weight = lootItem.template.item_wt;
|
int weight = lootItem.template.getItemWt();
|
||||||
|
|
||||||
// make sure lootingPlayer has room for item
|
// 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;
|
return null;
|
||||||
|
|
||||||
if (lootItem.template.item_type.equals(ItemType.GOLD))
|
if (lootItem.template.getItemType().equals(ItemType.GOLD))
|
||||||
if (amount != -1) { //from steal
|
if (amount != -1) { //from steal
|
||||||
int total = lootItem.getNumOfItems();
|
int total = lootItem.getNumOfItems();
|
||||||
amount = (amount > total) ? total : amount;
|
amount = (amount > total) ? total : amount;
|
||||||
@@ -1263,19 +1264,19 @@ public class CharacterItemManager {
|
|||||||
* Delegates
|
* Delegates
|
||||||
*/
|
*/
|
||||||
public synchronized boolean bankContains(Item item) {
|
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 (this.getGoldBank() != null && this.goldBank.getObjectUUID() == item.getObjectUUID());
|
||||||
return bank.contains(item);
|
return bank.contains(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean inventoryContains(Item item) {
|
public synchronized boolean inventoryContains(Item item) {
|
||||||
if (item.template.item_type.equals(ItemType.GOLD))
|
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||||
return (this.getGoldInventory() != null && this.goldInventory.getObjectUUID() == item.getObjectUUID());
|
return (this.getGoldInventory() != null && this.goldInventory.getObjectUUID() == item.getObjectUUID());
|
||||||
return inventory.contains(item);
|
return inventory.contains(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean vaultContains(Item item) {
|
public synchronized boolean vaultContains(Item item) {
|
||||||
if (item.template.item_type.equals(ItemType.GOLD))
|
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||||
return (this.getGoldVault() != null && this.goldVault.getObjectUUID() == item.getObjectUUID());
|
return (this.getGoldVault() != null && this.goldVault.getObjectUUID() == item.getObjectUUID());
|
||||||
return this.account.getVault().contains(item);
|
return this.account.getVault().contains(item);
|
||||||
}
|
}
|
||||||
@@ -1518,13 +1519,13 @@ public class CharacterItemManager {
|
|||||||
item.zeroItem();
|
item.zeroItem();
|
||||||
item.containerType = mbEnums.ItemContainerType.INVENTORY;
|
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
|
//only add gold item once
|
||||||
if (!corpse.hasGold())
|
if (!corpse.hasGold())
|
||||||
corpse.setHasGold(true);
|
corpse.setHasGold(true);
|
||||||
newInventory.add(item);
|
newInventory.add(item);
|
||||||
} else //item
|
} else //item
|
||||||
if (item.template.item_type.equals(ItemType.GOLD)) {
|
if (item.template.getItemType().equals(ItemType.GOLD)) {
|
||||||
int amt = item.getNumOfItems();
|
int amt = item.getNumOfItems();
|
||||||
item.setNumOfItems(0);
|
item.setNumOfItems(0);
|
||||||
MobLoot ml = new MobLoot(this.absCharacter, amt);
|
MobLoot ml = new MobLoot(this.absCharacter, amt);
|
||||||
@@ -1676,7 +1677,7 @@ public class CharacterItemManager {
|
|||||||
if (item == null)
|
if (item == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
weight += item.template.item_wt;
|
weight += item.template.getItemWt();
|
||||||
}
|
}
|
||||||
return weight;
|
return weight;
|
||||||
}
|
}
|
||||||
@@ -1696,7 +1697,7 @@ public class CharacterItemManager {
|
|||||||
this.bankWeight = 0;
|
this.bankWeight = 0;
|
||||||
for (Item item : this.bank) {
|
for (Item item : this.bank) {
|
||||||
if (item.template != null)
|
if (item.template != null)
|
||||||
this.bankWeight += item.template.item_wt;
|
this.bankWeight += item.template.getItemWt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1707,7 +1708,7 @@ public class CharacterItemManager {
|
|||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Item item = it.next();
|
Item item = it.next();
|
||||||
if (item.template != null)
|
if (item.template != null)
|
||||||
this.equipWeight += item.template.item_wt;
|
this.equipWeight += item.template.getItemWt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1715,7 +1716,7 @@ public class CharacterItemManager {
|
|||||||
this.inventoryWeight = 0;
|
this.inventoryWeight = 0;
|
||||||
for (Item item : this.inventory) {
|
for (Item item : this.inventory) {
|
||||||
if (item.template != null)
|
if (item.template != null)
|
||||||
this.inventoryWeight += item.template.item_wt;
|
this.inventoryWeight += item.template.getItemWt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1723,7 +1724,7 @@ public class CharacterItemManager {
|
|||||||
this.vaultWeight = 0;
|
this.vaultWeight = 0;
|
||||||
for (Item item : this.vault) {
|
for (Item item : this.vault) {
|
||||||
if (item.template != null)
|
if (item.template != null)
|
||||||
this.vaultWeight += item.template.item_wt;
|
this.vaultWeight += item.template.getItemWt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1755,7 +1756,7 @@ public class CharacterItemManager {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!item.moveItemToInventory(player))
|
if (!item.moveItemToInventory(player))
|
||||||
Logger.error("templateL " + item.template.template_id);
|
Logger.error("templateL " + item.template.getTemplateId());
|
||||||
|
|
||||||
// remove it from other lists:
|
// remove it from other lists:
|
||||||
this.remItemFromLists(item);
|
this.remItemFromLists(item);
|
||||||
@@ -1932,7 +1933,7 @@ public class CharacterItemManager {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//don't damage noob gear, hair or beards.
|
//don't damage noob gear, hair or beards.
|
||||||
if (item.template.combat_health_full == 0)
|
if (item.template.getCombatHealthFull() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!item.isCanDestroy())
|
if (!item.isCanDestroy())
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ public class CharacterPower extends AbstractGameObject {
|
|||||||
// return pc.getBonuses().getByte("gt." + this.power.getToken());
|
// return pc.getBonuses().getByte("gt." + this.power.getToken());
|
||||||
// } else
|
// } else
|
||||||
// return pc.getBonuses().getByte("gt." + this.power.getToken());
|
// return pc.getBonuses().getByte("gt." + this.power.getToken());
|
||||||
return PowerGrant.getGrantedTrains(this.power.getToken(), pc);
|
return PowerGrantedTrains.getGrantedTrains(this.power.getToken(), pc);
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ public class CharacterRune extends AbstractGameObject {
|
|||||||
private final int player;
|
private final int player;
|
||||||
private final ArrayList<SkillReq> skillsGranted;
|
private final ArrayList<SkillReq> skillsGranted;
|
||||||
private final ArrayList<PowerReq> powersGranted;
|
private final ArrayList<PowerReq> powersGranted;
|
||||||
private final ArrayList<RuneBaseEffect> effectsGranted;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No Table ID Constructor
|
* No Table ID Constructor
|
||||||
@@ -37,16 +36,12 @@ public class CharacterRune extends AbstractGameObject {
|
|||||||
this.runeBase = runeBase;
|
this.runeBase = runeBase;
|
||||||
this.player = characterID;
|
this.player = characterID;
|
||||||
if (this.runeBase != null) {
|
if (this.runeBase != null) {
|
||||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
||||||
} else {
|
} else {
|
||||||
this.skillsGranted = new ArrayList<>();
|
this.skillsGranted = new ArrayList<>();
|
||||||
this.powersGranted = new ArrayList<>();
|
this.powersGranted = new ArrayList<>();
|
||||||
}
|
}
|
||||||
if (this.runeBase != null)
|
|
||||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
|
||||||
else
|
|
||||||
this.effectsGranted = new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,16 +52,12 @@ public class CharacterRune extends AbstractGameObject {
|
|||||||
this.runeBase = runeBase;
|
this.runeBase = runeBase;
|
||||||
this.player = characterID;
|
this.player = characterID;
|
||||||
if (this.runeBase != null) {
|
if (this.runeBase != null) {
|
||||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
||||||
} else {
|
} else {
|
||||||
this.skillsGranted = new ArrayList<>();
|
this.skillsGranted = new ArrayList<>();
|
||||||
this.powersGranted = new ArrayList<>();
|
this.powersGranted = new ArrayList<>();
|
||||||
}
|
}
|
||||||
if (this.runeBase != null)
|
|
||||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
|
||||||
else
|
|
||||||
this.effectsGranted = new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,14 +69,12 @@ public class CharacterRune extends AbstractGameObject {
|
|||||||
this.runeBase = RuneBase.getRuneBase(rs.getInt("RuneBaseID"));
|
this.runeBase = RuneBase.getRuneBase(rs.getInt("RuneBaseID"));
|
||||||
this.player = rs.getInt("CharacterID");
|
this.player = rs.getInt("CharacterID");
|
||||||
if (this.runeBase != null) {
|
if (this.runeBase != null) {
|
||||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
||||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
|
||||||
} else {
|
} else {
|
||||||
Logger.error("Failed to find RuneBase for CharacterRune " + this.getObjectUUID());
|
Logger.error("Failed to find RuneBase for CharacterRune " + this.getObjectUUID());
|
||||||
this.skillsGranted = new ArrayList<>();
|
this.skillsGranted = new ArrayList<>();
|
||||||
this.powersGranted = new ArrayList<>();
|
this.powersGranted = new ArrayList<>();
|
||||||
this.effectsGranted = new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,10 +189,6 @@ public class CharacterRune extends AbstractGameObject {
|
|||||||
return this.powersGranted;
|
return this.powersGranted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
|
||||||
return this.effectsGranted;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateDatabase() {
|
public void updateDatabase() {
|
||||||
DbManager.CharacterRuneQueries.updateDatabase(this);
|
DbManager.CharacterRuneQueries.updateDatabase(this);
|
||||||
|
|||||||
@@ -296,14 +296,14 @@ public class Corpse extends AbstractWorldObject {
|
|||||||
|
|
||||||
//get weight of item
|
//get weight of item
|
||||||
|
|
||||||
int weight = item.template.item_wt;
|
int weight = item.template.getItemWt();
|
||||||
|
|
||||||
//make sure looter has room for item
|
//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;
|
return null;
|
||||||
|
|
||||||
//attempt to transfer item in db
|
//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()))
|
if (!looterItems.moveGoldToInventory(item, item.getNumOfItems()))
|
||||||
return null;
|
return null;
|
||||||
} else if (!item.moveItemToInventory(looter))
|
} else if (!item.moveItemToInventory(looter))
|
||||||
|
|||||||
@@ -12,114 +12,17 @@ package engine.objects;
|
|||||||
import engine.gameManager.ZoneManager;
|
import engine.gameManager.ZoneManager;
|
||||||
import engine.math.Vector3fImmutable;
|
import engine.math.Vector3fImmutable;
|
||||||
import engine.mbEnums.TargetColor;
|
import engine.mbEnums.TargetColor;
|
||||||
|
import engine.parsers.objects.RuneTemplate;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import static engine.gameManager.LootManager.LOOTMANAGER;
|
import static engine.gameManager.LootManager.LOOTMANAGER;
|
||||||
|
|
||||||
public class Experience {
|
public class Experience {
|
||||||
|
|
||||||
private static final TreeMap<Integer, Integer> ExpToLevel;
|
// Client ArcCharacter_ExpForLevelUp (0x4715D0) float constant at 0x154195C
|
||||||
private static final int[] LevelToExp = {Integer.MIN_VALUE, // Pad
|
private static final float EXP_LEVEL_SLOPE = 0.0512f;
|
||||||
// everything
|
|
||||||
// over 1
|
|
||||||
|
|
||||||
// R0
|
|
||||||
0, // Level 1
|
|
||||||
150, // Level 2
|
|
||||||
1200, // Level 3
|
|
||||||
4050, // Level 4
|
|
||||||
9600, // Level 5
|
|
||||||
18750, // Level 6
|
|
||||||
32400, // Level 7
|
|
||||||
51450, // Level 8
|
|
||||||
76800, // Level 9
|
|
||||||
|
|
||||||
// R1
|
|
||||||
109350, // Level 10
|
|
||||||
150000, // Level 11
|
|
||||||
199650, // Level 12
|
|
||||||
259200, // Level 13
|
|
||||||
329550, // Level 14
|
|
||||||
411600, // Level 15
|
|
||||||
506250, // Level 16
|
|
||||||
614400, // Level 17
|
|
||||||
736950, // Level 18
|
|
||||||
874800, // Level 19
|
|
||||||
|
|
||||||
// R2
|
|
||||||
1028850, // Level 20
|
|
||||||
1200000, // Level 21
|
|
||||||
1389150, // Level 22
|
|
||||||
1597200, // Level 23
|
|
||||||
1825050, // Level 24
|
|
||||||
2073600, // Level 25
|
|
||||||
2343750, // Level 26
|
|
||||||
2636400, // Level 27
|
|
||||||
2952450, // Level 28
|
|
||||||
3292800, // Level 29
|
|
||||||
|
|
||||||
// R3
|
|
||||||
3658350, // Level 30
|
|
||||||
4050000, // Level 31
|
|
||||||
4468650, // Level 32
|
|
||||||
4915200, // Level 33
|
|
||||||
5390550, // Level 34
|
|
||||||
5895600, // Level 35
|
|
||||||
6431250, // Level 36
|
|
||||||
6998400, // Level 37
|
|
||||||
7597950, // Level 38
|
|
||||||
8230800, // Level 39
|
|
||||||
|
|
||||||
// R4
|
|
||||||
8897850, // Level 40
|
|
||||||
10091520, // Level 41
|
|
||||||
11396777, // Level 42
|
|
||||||
12820187, // Level 43
|
|
||||||
14368505, // Level 44
|
|
||||||
16048666, // Level 45
|
|
||||||
17867790, // Level 46
|
|
||||||
19833183, // Level 47
|
|
||||||
21952335, // Level 48
|
|
||||||
24232919, // Level 49
|
|
||||||
|
|
||||||
// R5
|
|
||||||
26682793, // Level 50
|
|
||||||
29310000, // Level 51
|
|
||||||
32122766, // Level 52
|
|
||||||
35129502, // Level 53
|
|
||||||
38338805, // Level 54
|
|
||||||
41759452, // Level 55
|
|
||||||
45400409, // Level 56
|
|
||||||
49270824, // Level 57
|
|
||||||
53380030, // Level 58
|
|
||||||
57737542, // Level 59
|
|
||||||
|
|
||||||
// R6
|
|
||||||
62353064, // Level 60
|
|
||||||
67236479, // Level 61
|
|
||||||
72397859, // Level 62
|
|
||||||
77847457, // Level 63
|
|
||||||
83595712, // Level 64
|
|
||||||
89653247, // Level 65
|
|
||||||
96030869, // Level 66
|
|
||||||
102739569, // Level 67
|
|
||||||
109790524, // Level 68
|
|
||||||
117195093, // Level 69
|
|
||||||
|
|
||||||
// R7
|
|
||||||
124964822, // Level 70
|
|
||||||
133111438, // Level 71
|
|
||||||
141646855, // Level 72
|
|
||||||
150583171, // Level 73
|
|
||||||
159932666, // Level 74
|
|
||||||
169707808, // Level 75
|
|
||||||
179921247, // Level 76
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final float[] MaxExpPerLevel = {Float.MIN_VALUE, // Pad
|
private static final float[] MaxExpPerLevel = {Float.MIN_VALUE, // Pad
|
||||||
// everything
|
// everything
|
||||||
// over
|
// over
|
||||||
@@ -227,39 +130,56 @@ public class Experience {
|
|||||||
// (expGranted / group.size()) * (groupBonus * (group.size()-1) +1)
|
// (expGranted / group.size()) * (groupBonus * (group.size()-1) +1)
|
||||||
private static final float GROUP_BONUS = 0.5f; // 0.2 grants (20%) addtional
|
private static final float GROUP_BONUS = 0.5f; // 0.2 grants (20%) addtional
|
||||||
|
|
||||||
static {
|
|
||||||
ExpToLevel = new TreeMap<>();
|
|
||||||
|
|
||||||
// flip keys and values for other Map
|
|
||||||
for (int i = 1; i < LevelToExp.length; i++) {
|
|
||||||
ExpToLevel.put(LevelToExp[i], i);
|
|
||||||
}
|
|
||||||
} // end Static block
|
|
||||||
// exp per group member
|
// exp per group member
|
||||||
|
|
||||||
// called to determine current level based on xp
|
// called to determine current level based on xp
|
||||||
public static int getLevel(int experience) {
|
public static int getLevel(PlayerCharacter player, int experience) {
|
||||||
|
|
||||||
int expKey = ExpToLevel.floorKey(experience);
|
int level = 1;
|
||||||
int level = ExpToLevel.get(expKey);
|
|
||||||
|
|
||||||
if (level > MBServerStatics.LEVELCAP)
|
while (level < MBServerStatics.LEVELCAP && experience >= getBaseExperience(player, level + 1))
|
||||||
level = MBServerStatics.LEVELCAP;
|
level++;
|
||||||
|
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the base xp for a level
|
// The client function returns the XP to reach level + 1, so it is called with level - 1.
|
||||||
public static int getBaseExperience(int level) {
|
// 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)
|
int clientLevel = level - 1;
|
||||||
return LevelToExp[level];
|
double levelScale;
|
||||||
|
|
||||||
int fLevel = level - 1;
|
levelScale = Math.max(1.0, (clientLevel - 39) * (double) EXP_LEVEL_SLOPE + 1.0);
|
||||||
int baseXP = fLevel * fLevel * fLevel;
|
|
||||||
|
|
||||||
return (int) ((fLevel < 40) ? (baseXP * 150)
|
return (int) (long) ((double) clientLevel * clientLevel * clientLevel * levelScale
|
||||||
: (baseXP * (150 + (7.6799998 * (level - 40)))));
|
* 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
|
// 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.Dispatch;
|
||||||
import engine.net.client.ClientConnection;
|
import engine.net.client.ClientConnection;
|
||||||
import engine.net.client.msg.DeleteItemMsg;
|
import engine.net.client.msg.DeleteItemMsg;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
|
import engine.parsers.objects.UserPowerAction;
|
||||||
import engine.powers.EffectsBase;
|
import engine.powers.EffectsBase;
|
||||||
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
import engine.powers.effectmodifiers.AbstractEffectModifier;
|
||||||
import engine.powers.poweractions.AbstractPowerAction;
|
import engine.powers.poweractions.AbstractPowerAction;
|
||||||
@@ -31,6 +33,7 @@ import java.sql.SQLException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
@@ -55,7 +58,7 @@ public class Item extends AbstractWorldObject {
|
|||||||
public int templateID;
|
public int templateID;
|
||||||
private long dateToUpgrade;
|
private long dateToUpgrade;
|
||||||
public int magicValue;
|
public int magicValue;
|
||||||
public ItemTemplate template;
|
public CObjectTemplate template;
|
||||||
public String name = "";
|
public String name = "";
|
||||||
public int prefixToken; // Forge support
|
public int prefixToken; // Forge support
|
||||||
public int suffixToken; // Forge support
|
public int suffixToken; // Forge support
|
||||||
@@ -68,14 +71,14 @@ public class Item extends AbstractWorldObject {
|
|||||||
public Item(int templateID) {
|
public Item(int templateID) {
|
||||||
super();
|
super();
|
||||||
this.templateID = templateID;
|
this.templateID = templateID;
|
||||||
this.template = ItemTemplate.templates.get(templateID);
|
this.template = CObjectTemplate.lookup(templateID);
|
||||||
this.chargesRemaining = this.template.item_initial_charges;
|
this.chargesRemaining = this.template.getItemInitialCharges();
|
||||||
this.combat_health_current = this.template.combat_health_full;
|
this.combat_health_current = this.template.getCombatHealthFull();
|
||||||
this.equipSlot = EquipSlotType.NONE;
|
this.equipSlot = EquipSlotType.NONE;
|
||||||
this.containerType = ItemContainerType.NONE;
|
this.containerType = ItemContainerType.NONE;
|
||||||
this.numberOfItems = 1;
|
this.numberOfItems = 1;
|
||||||
this.flags.addAll(this.template.item_flags);
|
this.flags.addAll(this.template.getItemFlags());
|
||||||
this.value = this.template.item_value;
|
this.value = this.template.getItemValue();
|
||||||
this.magicValue = this.value + calcMagicValue();
|
this.magicValue = this.value + calcMagicValue();
|
||||||
loadTemplateEnchantments();
|
loadTemplateEnchantments();
|
||||||
}
|
}
|
||||||
@@ -87,7 +90,7 @@ public class Item extends AbstractWorldObject {
|
|||||||
super(rs);
|
super(rs);
|
||||||
|
|
||||||
this.templateID = rs.getInt("templateID");
|
this.templateID = rs.getInt("templateID");
|
||||||
this.template = ItemTemplate.templates.get(this.templateID);
|
this.template = CObjectTemplate.lookup(this.templateID);
|
||||||
|
|
||||||
if (this.template == null)
|
if (this.template == null)
|
||||||
Logger.error("Null template of " + this.templateID);
|
Logger.error("Null template of " + this.templateID);
|
||||||
@@ -166,7 +169,7 @@ public class Item extends AbstractWorldObject {
|
|||||||
this.value = rs.getInt("value");
|
this.value = rs.getInt("value");
|
||||||
|
|
||||||
if (this.value == 0) {
|
if (this.value == 0) {
|
||||||
this.value = this.template.item_value;
|
this.value = this.template.getItemValue();
|
||||||
this.magicValue = this.value + calcMagicValue();
|
this.magicValue = this.value + calcMagicValue();
|
||||||
} else
|
} else
|
||||||
this.magicValue = this.value; // Value was overridden in vendor inventory
|
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.putString(item.name); // Unknown. pad?
|
||||||
writer.put((byte) 1); // End Datablock byte
|
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.putFloat((float) item.combat_health_current);
|
||||||
|
|
||||||
writer.put((byte) 1); // End Datablock byte
|
writer.put((byte) 1); // End Datablock byte
|
||||||
@@ -255,7 +258,7 @@ public class Item extends AbstractWorldObject {
|
|||||||
} else
|
} else
|
||||||
writer.putInt(item.numberOfItems); // Amount of gold
|
writer.putInt(item.numberOfItems); // Amount of gold
|
||||||
} else
|
} else
|
||||||
writer.putInt(item.template.item_value);
|
writer.putInt(item.template.getItemValue());
|
||||||
|
|
||||||
writer.putInt(item.getValue());
|
writer.putInt(item.getValue());
|
||||||
|
|
||||||
@@ -288,7 +291,7 @@ public class Item extends AbstractWorldObject {
|
|||||||
writer.putInt(36); //Magical, blue name
|
writer.putInt(36); //Magical, blue name
|
||||||
else
|
else
|
||||||
writer.putInt(40); //Magical, unidentified
|
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
|
writer.putInt(36); //Magical, blue name
|
||||||
else
|
else
|
||||||
writer.putInt(4); //Non-Magical, grey name
|
writer.putInt(4); //Non-Magical, grey name
|
||||||
@@ -298,7 +301,7 @@ public class Item extends AbstractWorldObject {
|
|||||||
writer.put((byte) 0);
|
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);
|
writer.putShort((short) 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -463,7 +466,7 @@ public class Item extends AbstractWorldObject {
|
|||||||
int serialized = 0;
|
int serialized = 0;
|
||||||
for (Item item : list) {
|
for (Item item : list) {
|
||||||
|
|
||||||
if (item.template.item_type.equals(ItemType.GOLD))
|
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||||
if (item.numberOfItems == 0)
|
if (item.numberOfItems == 0)
|
||||||
continue;
|
continue;
|
||||||
try {
|
try {
|
||||||
@@ -497,7 +500,7 @@ public class Item extends AbstractWorldObject {
|
|||||||
int serialized = 0;
|
int serialized = 0;
|
||||||
for (Item item : list) {
|
for (Item item : list) {
|
||||||
|
|
||||||
if (item.template.item_type.equals(ItemType.GOLD))
|
if (item.template.getItemType().equals(ItemType.GOLD))
|
||||||
if (item.numberOfItems == 0)
|
if (item.numberOfItems == 0)
|
||||||
continue;
|
continue;
|
||||||
try {
|
try {
|
||||||
@@ -931,12 +934,16 @@ public class Item extends AbstractWorldObject {
|
|||||||
private void loadTemplateEnchantments() {
|
private void loadTemplateEnchantments() {
|
||||||
|
|
||||||
EffectsBase effect;
|
EffectsBase effect;
|
||||||
|
LinkedHashMap<String, int[]> templateEnchantments = new LinkedHashMap<>();
|
||||||
|
|
||||||
if (ConfigManager.serverType.equals(mbEnums.ServerType.LOGINSERVER))
|
if (ConfigManager.serverType.equals(mbEnums.ServerType.LOGINSERVER))
|
||||||
return;
|
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);
|
effect = PowersManager.getEffectByIDString(effectID);
|
||||||
|
|
||||||
@@ -946,7 +953,7 @@ public class Item extends AbstractWorldObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AbstractPowerAction apa = PowersManager.getPowerActionByIDString(effect.getIDString());
|
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.
|
// No enchantments for negative id items in the db. Early exit.
|
||||||
|
|
||||||
if (this.objectUUID < 0) {
|
if (this.objectUUID < 0) {
|
||||||
this.magicValue = this.template.item_value + calcMagicValue();
|
this.magicValue = this.template.getItemValue() + calcMagicValue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -971,8 +978,8 @@ public class Item extends AbstractWorldObject {
|
|||||||
|
|
||||||
// Value is overridden the db
|
// Value is overridden the db
|
||||||
|
|
||||||
if (this.value == this.template.item_value)
|
if (this.value == this.template.getItemValue())
|
||||||
this.magicValue = this.template.item_value + calcMagicValue();
|
this.magicValue = this.template.getItemValue() + calcMagicValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPermanentEnchantment(String enchantID, int rank) {
|
public void addPermanentEnchantment(String enchantID, int rank) {
|
||||||
@@ -1116,11 +1123,11 @@ public class Item extends AbstractWorldObject {
|
|||||||
else
|
else
|
||||||
modifiedValue = this.value;
|
modifiedValue = this.value;
|
||||||
|
|
||||||
if (this.template.item_initial_charges > 0)
|
if (this.template.getItemInitialCharges() > 0)
|
||||||
modifiedValue = modifiedValue * (this.chargesRemaining / this.template.item_initial_charges);
|
modifiedValue = modifiedValue * (this.chargesRemaining / this.template.getItemInitialCharges());
|
||||||
|
|
||||||
if (this.template.combat_health_full > 0)
|
if (this.template.getCombatHealthFull() > 0)
|
||||||
modifiedValue = (int) (modifiedValue * (this.combat_health_current / this.template.combat_health_full));
|
modifiedValue = (int) (modifiedValue * (this.combat_health_current / this.template.getCombatHealthFull()));
|
||||||
|
|
||||||
return modifiedValue;
|
return modifiedValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,649 +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;
|
|
||||||
// Lossy: some runes list the same power several times with different
|
|
||||||
// arguments (a step table, e.g. PET_DISC). Only the last entry is kept.
|
|
||||||
// engine.parsers.objects.RuneTemplate keeps the full list.
|
|
||||||
public final HashMap<String, int[]> item_user_power_action = new HashMap<>();
|
|
||||||
public final HashMap<String, Integer> item_power_grant = new HashMap<>();
|
|
||||||
// Lossy: some runes carry up to 35 power_actions entries per power
|
|
||||||
// (a step table, e.g. HNT-031). Only the first entry is kept.
|
|
||||||
// engine.parsers.objects.RuneTemplate keeps the full list.
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -9,10 +9,14 @@
|
|||||||
|
|
||||||
package engine.objects;
|
package engine.objects;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import engine.mbEnums;
|
||||||
import java.sql.SQLException;
|
import engine.parsers.objects.RuneTemplate;
|
||||||
|
import engine.util.Hasher;
|
||||||
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class MaxSkills {
|
public class MaxSkills {
|
||||||
|
|
||||||
@@ -23,17 +27,6 @@ public class MaxSkills {
|
|||||||
private int maxSkillPercent;
|
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) {
|
public MaxSkills(int runeID, int skillToken, int skillLevel, int maxSkillPercent) {
|
||||||
super();
|
super();
|
||||||
this.runeID = runeID;
|
this.runeID = runeID;
|
||||||
@@ -42,6 +35,29 @@ public class MaxSkills {
|
|||||||
this.maxSkillPercent = maxSkillPercent;
|
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() {
|
public int getRuneID() {
|
||||||
return runeID;
|
return runeID;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,9 +127,13 @@ public class MobBase extends AbstractGameObject {
|
|||||||
for (BootySetEntry equipmentSetEntry : equipList) {
|
for (BootySetEntry equipmentSetEntry : equipList) {
|
||||||
|
|
||||||
Item item = new Item(equipmentSetEntry.templateID);
|
Item item = new Item(equipmentSetEntry.templateID);
|
||||||
|
|
||||||
|
if (item.template.getItemEqSlotsOr().isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
item.objectUUID = ItemManager.lastNegativeID.decrementAndGet();
|
item.objectUUID = ItemManager.lastNegativeID.decrementAndGet();
|
||||||
item.drop_chance = equipmentSetEntry.dropChance;
|
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);
|
equip.put(item.equipSlot, item);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,23 @@
|
|||||||
|
|
||||||
package engine.objects;
|
package engine.objects;
|
||||||
|
|
||||||
|
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.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
|
||||||
public class MobBaseEffects {
|
public class MobBaseEffects {
|
||||||
|
|
||||||
|
private static final ConcurrentHashMap<Integer, ArrayList<MobBaseEffects>> effectsByRune = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||||
|
|
||||||
private int mobBaseID;
|
private int mobBaseID;
|
||||||
private int token;
|
private int token;
|
||||||
private int rank;
|
private int rank;
|
||||||
@@ -30,6 +41,52 @@ public class MobBaseEffects {
|
|||||||
this.reqLvl = rs.getInt("reqLvl");
|
this.reqLvl = rs.getInt("reqLvl");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MobBaseEffects(int token, int rank, int reqLvl) {
|
||||||
|
this.token = token;
|
||||||
|
this.rank = rank;
|
||||||
|
this.reqLvl = reqLvl;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the mobBaseID
|
* @return the mobBaseID
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import engine.gameManager.PowersManager;
|
|||||||
import engine.mbEnums;
|
import engine.mbEnums;
|
||||||
import engine.mbEnums.ItemType;
|
import engine.mbEnums.ItemType;
|
||||||
import engine.mbEnums.OwnerType;
|
import engine.mbEnums.OwnerType;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.powers.poweractions.AbstractPowerAction;
|
import engine.powers.poweractions.AbstractPowerAction;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
@@ -30,22 +31,22 @@ public final class MobLoot extends Item {
|
|||||||
private String prefix = "";
|
private String prefix = "";
|
||||||
private String suffix = "";
|
private String suffix = "";
|
||||||
|
|
||||||
public MobLoot(AbstractCharacter mob, ItemTemplate template, boolean noSteal) {
|
public MobLoot(AbstractCharacter mob, CObjectTemplate template, boolean noSteal) {
|
||||||
this(mob, template, 0, noSteal);
|
this(mob, template, 0, noSteal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MobLoot(AbstractCharacter mob, int qtyOfGold) {
|
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.ownerType = OwnerType.Mob;
|
||||||
this.ownerID = mob.getObjectUUID();
|
this.ownerID = mob.getObjectUUID();
|
||||||
this.objectUUID = generateId();
|
this.objectUUID = generateId();
|
||||||
|
|
||||||
if (quantity == 0 && template.item_type == ItemType.RESOURCE)
|
if (quantity == 0 && template.getItemType() == ItemType.RESOURCE)
|
||||||
quantity = 1;
|
quantity = 1;
|
||||||
|
|
||||||
if (quantity > 0)
|
if (quantity > 0)
|
||||||
@@ -105,7 +106,7 @@ public final class MobLoot extends Item {
|
|||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (this.template.item_type.equals(ItemType.GOLD))
|
if (this.template.getItemType().equals(ItemType.GOLD))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Item item = this;
|
Item item = this;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import engine.net.ByteBufferWriter;
|
|||||||
import engine.net.Dispatch;
|
import engine.net.Dispatch;
|
||||||
import engine.net.client.msg.PetMsg;
|
import engine.net.client.msg.PetMsg;
|
||||||
import engine.net.client.msg.PlaceAssetMsg;
|
import engine.net.client.msg.PlaceAssetMsg;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
@@ -961,15 +962,15 @@ public class NPC extends AbstractCharacter {
|
|||||||
maxSkill = 110;
|
maxSkill = 110;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ItemTemplate itemTemplate;
|
CObjectTemplate itemTemplate;
|
||||||
int skillRequired = 0;
|
int skillRequired = 0;
|
||||||
for (Integer itemID : fullItemList) {
|
for (Integer itemID : fullItemList) {
|
||||||
itemTemplate = ItemTemplate.templates.get(itemID);
|
itemTemplate = CObjectTemplate.lookup(itemID);
|
||||||
|
|
||||||
if (itemTemplate.item_skill_required.values().iterator().hasNext())
|
if (itemTemplate.getItemSkillReq().values().iterator().hasNext())
|
||||||
skillRequired = itemTemplate.item_skill_required.values().iterator().next();
|
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)
|
if (skillRequired <= maxSkill && !exclude)
|
||||||
filteredItemList.add(itemID);
|
filteredItemList.add(itemID);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,6 @@
|
|||||||
|
|
||||||
package engine.objects;
|
package engine.objects;
|
||||||
|
|
||||||
import engine.gameManager.DbManager;
|
|
||||||
import engine.net.ByteBufferWriter;
|
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@@ -23,7 +21,6 @@ public class NPCRune extends AbstractGameObject {
|
|||||||
private final RuneBase runeBase;
|
private final RuneBase runeBase;
|
||||||
private final int player;
|
private final int player;
|
||||||
private final ArrayList<SkillReq> skillsGranted;
|
private final ArrayList<SkillReq> skillsGranted;
|
||||||
private final ArrayList<RuneBaseEffect> effectsGranted;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No Table ID Constructor
|
* No Table ID Constructor
|
||||||
@@ -33,10 +30,9 @@ public class NPCRune extends AbstractGameObject {
|
|||||||
this.runeBase = runeBase;
|
this.runeBase = runeBase;
|
||||||
this.player = characterID;
|
this.player = characterID;
|
||||||
if (this.runeBase != null)
|
if (this.runeBase != null)
|
||||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||||
else
|
else
|
||||||
this.skillsGranted = new ArrayList<>();
|
this.skillsGranted = new ArrayList<>();
|
||||||
this.effectsGranted = new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,10 +43,9 @@ public class NPCRune extends AbstractGameObject {
|
|||||||
this.runeBase = runeBase;
|
this.runeBase = runeBase;
|
||||||
this.player = characterID;
|
this.player = characterID;
|
||||||
if (this.runeBase == null)
|
if (this.runeBase == null)
|
||||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||||
else
|
else
|
||||||
this.skillsGranted = new ArrayList<>();
|
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.runeBase = RuneBase.getRuneBase(rs.getInt("RuneBaseID"));
|
||||||
this.player = rs.getInt("NpcID");
|
this.player = rs.getInt("NpcID");
|
||||||
if (this.runeBase != null) {
|
if (this.runeBase != null) {
|
||||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
|
||||||
} else {
|
} else {
|
||||||
Logger.error("Failed to find RuneBase for NPCRune " + this.getObjectUUID());
|
Logger.error("Failed to find RuneBase for NPCRune " + this.getObjectUUID());
|
||||||
this.skillsGranted = new ArrayList<>();
|
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
|
* Serializing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
|
||||||
return this.effectsGranted;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateDatabase() {
|
public void updateDatabase() {
|
||||||
|
|
||||||
|
|||||||
@@ -236,10 +236,6 @@ public class PlayerBonuses {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void grantEffect(RuneBaseEffect rbe) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setFloat(AbstractEffectModifier mod, float val) {
|
public void setFloat(AbstractEffectModifier mod, float val) {
|
||||||
if (val != 0)
|
if (val != 0)
|
||||||
this.bonusFloats.put(mod, val);
|
this.bonusFloats.put(mod, val);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import engine.net.Dispatch;
|
|||||||
import engine.net.client.ClientConnection;
|
import engine.net.client.ClientConnection;
|
||||||
import engine.net.client.msg.*;
|
import engine.net.client.msg.*;
|
||||||
import engine.net.client.msg.login.CommitNewCharacterMsg;
|
import engine.net.client.msg.login.CommitNewCharacterMsg;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.powers.EffectsBase;
|
import engine.powers.EffectsBase;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
import engine.server.login.LoginServer;
|
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) {
|
public static PlayerCharacter generatePCFromCommitNewCharacterMsg(Account a, CommitNewCharacterMsg msg, ClientConnection clientConnection) {
|
||||||
|
|
||||||
String firstName = msg.getFirstName().trim();
|
String firstName = msg.getFirstName().trim();
|
||||||
@@ -767,8 +776,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
Race race = Race.getRace(raceID);
|
Race race = Race.getRace(raceID);
|
||||||
|
|
||||||
if (race == null) {
|
if (race == null) {
|
||||||
Logger.info("Invalid RaceID: " + raceID);
|
return refuseCreation(a, clientConnection, "Invalid RaceID: " + raceID);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify BaseClass Object.
|
// Verify BaseClass Object.
|
||||||
@@ -776,8 +784,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
BaseClass baseClass = DbManager.BaseClassQueries.GET_BASE_CLASS(baseClassID);
|
BaseClass baseClass = DbManager.BaseClassQueries.GET_BASE_CLASS(baseClassID);
|
||||||
|
|
||||||
if (baseClass == null) {
|
if (baseClass == null) {
|
||||||
Logger.info("Invalid BaseClasID: " + baseClassID);
|
return refuseCreation(a, clientConnection, "Invalid BaseClasID: " + baseClassID);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify Race/baseClass combo.
|
// Verify Race/baseClass combo.
|
||||||
@@ -792,8 +799,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
Logger.info("Invalid BaseClass/Race Combo");
|
return refuseCreation(a, clientConnection, "Invalid BaseClass/Race Combo");
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify HairStyle/BeardStyle/SkinColor/HairColor/BeardColor
|
// Verify HairStyle/BeardStyle/SkinColor/HairColor/BeardColor
|
||||||
@@ -804,23 +810,19 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
int beardColorID = msg.getBeardColor();
|
int beardColorID = msg.getBeardColor();
|
||||||
|
|
||||||
if (!race.isValidHairStyle(hairStyleID)) {
|
if (!race.isValidHairStyle(hairStyleID)) {
|
||||||
Logger.info("Invalid HairStyleID: " + hairStyleID + " for race: " + race.getName());
|
return refuseCreation(a, clientConnection, "Invalid HairStyleID: " + hairStyleID + " for race: " + race.getName());
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!race.isValidSkinColor(skinColorID)) {
|
if (!race.isValidSkinColor(skinColorID)) {
|
||||||
Logger.info("Invalid skinColorID: " + skinColorID + " for race: " + race.getName());
|
return refuseCreation(a, clientConnection, "Invalid skinColorID: " + skinColorID + " for race: " + race.getName());
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!race.isValidHairColor(hairColorID)) {
|
if (!race.isValidHairColor(hairColorID)) {
|
||||||
Logger.info("Invalid hairColorID: " + hairColorID + " for race: " + race.getName());
|
return refuseCreation(a, clientConnection, "Invalid hairColorID: " + hairColorID + " for race: " + race.getName());
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!race.isValidBeardColor(beardColorID)) {
|
if (!race.isValidBeardColor(beardColorID)) {
|
||||||
Logger.info("Invalid beardColorID: " + beardColorID + " for race: " + race.getName());
|
return refuseCreation(a, clientConnection, "Invalid beardColorID: " + beardColorID + " for race: " + race.getName());
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get stat modifiers
|
// Get stat modifiers
|
||||||
@@ -832,8 +834,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
|
|
||||||
|
|
||||||
if (intMod < -5 || dexMod < -5 || conMod < -5 || strMod < -5 || spiMod < -5) {
|
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 refuseCreation(a, clientConnection, "Negative stat mod");
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate current stats:
|
// calculate current stats:
|
||||||
@@ -850,12 +851,11 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
short intMax = race.getIntMax();
|
short intMax = race.getIntMax();
|
||||||
short spiMax = race.getSpiMax();
|
short spiMax = race.getSpiMax();
|
||||||
|
|
||||||
// Verify not too many runes applied
|
// 10 rune slots including race and class (client 0xBA8C80)
|
||||||
int numRunes = msg.getNumRunes();
|
int numRunes = msg.getNumRunes();
|
||||||
|
|
||||||
if (numRunes > 16) {
|
if (numRunes > 10) {
|
||||||
Logger.info("Too many Runes applied");
|
return refuseCreation(a, clientConnection, "Too many Runes applied");
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Runes
|
// Get Runes
|
||||||
@@ -865,7 +865,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
|
|
||||||
int[] characterRunes = msg.getRunes();
|
int[] characterRunes = msg.getRunes();
|
||||||
|
|
||||||
HashSet<Byte> usedRunesSubType = new HashSet<>();
|
HashSet<Integer> usedRuneIDs = new HashSet<>();
|
||||||
|
HashSet<Integer> usedSubTypeTokens = new HashSet<>();
|
||||||
HashSet<RuneBase> usedRunes = new HashSet<>();
|
HashSet<RuneBase> usedRunes = new HashSet<>();
|
||||||
|
|
||||||
// So that all the penalties can be added at the end.
|
// So that all the penalties can be added at the end.
|
||||||
@@ -905,38 +906,33 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
|
|
||||||
// Null check
|
// Null check
|
||||||
if (runeBase == null) {
|
if (runeBase == null) {
|
||||||
Logger.info("GOM returned NULL RuneBase");
|
return refuseCreation(a, clientConnection, "GOM returned NULL RuneBase");
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate Rune against Race
|
// Validate Rune against Race
|
||||||
if (!race.isAllowedRune(runeBase)) {
|
if (!race.isAllowedRune(runeBase)) {
|
||||||
Logger.info("Trait Not valid for Race");
|
return refuseCreation(a, clientConnection, "Trait Not valid for Race");
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate BaseClass against Race
|
// Validate BaseClass against Race
|
||||||
if (!baseClass.isAllowedRune(runeBase)) {
|
if (!baseClass.isAllowedRune(runeBase)) {
|
||||||
Logger.info("Trait Not valid for BaseClass");
|
return refuseCreation(a, clientConnection, "Trait Not valid for BaseClass");
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int previous_size = usedRunes.size();
|
if (!usedRuneIDs.add(runeBase.getObjectUUID())) {
|
||||||
int previous_subtype = usedRunesSubType.size();
|
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);
|
usedRunes.add(runeBase);
|
||||||
usedRunesSubType.add(runeBase.getSubtype());
|
|
||||||
|
|
||||||
// Duplicate Rune check
|
// Talent cap of 8 (client 0x4695D0)
|
||||||
if (usedRunes.size() <= previous_size) {
|
if (usedRunes.size() > 8) {
|
||||||
Logger.info("Duplicate RuneBase");
|
return refuseCreation(a, clientConnection, "Too many talents applied");
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Duplicate Subtype check
|
|
||||||
if (runeBase.getSubtype() != 0 && usedRunesSubType.size() <= previous_subtype) {
|
|
||||||
Logger.info("Duplicate RuneBase Subtype");
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxValue = 0;
|
int maxValue = 0;
|
||||||
@@ -981,43 +977,37 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
remainingPoints -= value;
|
remainingPoints -= value;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Logger.info("Not enough points left");
|
return refuseCreation(a, clientConnection, "Not enough points left");
|
||||||
return null;
|
|
||||||
case MBServerStatics.RUNE_STR_MIN_NEEDED_ATTRIBUTE_ID:
|
case MBServerStatics.RUNE_STR_MIN_NEEDED_ATTRIBUTE_ID:
|
||||||
|
|
||||||
if (strCur >= value)
|
if (strCur >= value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Logger.info("STR fails to meet Rune Minimum --> " + rb.getName());
|
return refuseCreation(a, clientConnection, "STR fails to meet Rune Minimum --> " + rb.getName());
|
||||||
return null;
|
|
||||||
case MBServerStatics.RUNE_DEX_MIN_NEEDED_ATTRIBUTE_ID:
|
case MBServerStatics.RUNE_DEX_MIN_NEEDED_ATTRIBUTE_ID:
|
||||||
|
|
||||||
if (dexCur >= value)
|
if (dexCur >= value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Logger.info("DEX fails to meet Rune Minimum --> " + rb.getName());
|
return refuseCreation(a, clientConnection, "DEX fails to meet Rune Minimum --> " + rb.getName());
|
||||||
return null;
|
|
||||||
case MBServerStatics.RUNE_CON_MIN_NEEDED_ATTRIBUTE_ID:
|
case MBServerStatics.RUNE_CON_MIN_NEEDED_ATTRIBUTE_ID:
|
||||||
|
|
||||||
if (conCur >= value)
|
if (conCur >= value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Logger.info("CON fails to meet Rune Minimum --> " + rb.getName());
|
return refuseCreation(a, clientConnection, "CON fails to meet Rune Minimum --> " + rb.getName());
|
||||||
return null;
|
|
||||||
case MBServerStatics.RUNE_INT_MIN_NEEDED_ATTRIBUTE_ID:
|
case MBServerStatics.RUNE_INT_MIN_NEEDED_ATTRIBUTE_ID:
|
||||||
|
|
||||||
if (intCur >= value)
|
if (intCur >= value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Logger.info("INT fails to meet Rune Minimum --> " + rb.getName());
|
return refuseCreation(a, clientConnection, "INT fails to meet Rune Minimum --> " + rb.getName());
|
||||||
return null;
|
|
||||||
case MBServerStatics.RUNE_SPI_MIN_NEEDED_ATTRIBUTE_ID:
|
case MBServerStatics.RUNE_SPI_MIN_NEEDED_ATTRIBUTE_ID:
|
||||||
|
|
||||||
if (spiCur >= value)
|
if (spiCur >= value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Logger.info("SPI fails to meet Rune Minimum --> " + rb.getName());
|
return refuseCreation(a, clientConnection, "SPI fails to meet Rune Minimum --> " + rb.getName());
|
||||||
return null;
|
|
||||||
case MBServerStatics.RUNE_STR_ATTRIBUTE_ID:
|
case MBServerStatics.RUNE_STR_ATTRIBUTE_ID:
|
||||||
|
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
@@ -1082,12 +1072,20 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Logger.info("Unknown ATTRIBUTE_ID while checking RuneBaseAttributes: " + attrID);
|
return refuseCreation(a, clientConnection, "Unknown ATTRIBUTE_ID while checking RuneBaseAttributes: " + attrID);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
// Add in all of the penalties.
|
||||||
strCur += penalties.get("StrCur");
|
strCur += penalties.get("StrCur");
|
||||||
strMax += penalties.get("StrMax");
|
strMax += penalties.get("StrMax");
|
||||||
@@ -1116,8 +1114,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kit == null) {
|
if (kit == null) {
|
||||||
Logger.info("Unable to find matching kitID: " + kitID);
|
return refuseCreation(a, clientConnection, "Unable to find matching kitID: " + kitID);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byte runningTrains = 0;
|
byte runningTrains = 0;
|
||||||
@@ -1270,7 +1267,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
player.endLoc = Vector3fImmutable.ZERO;
|
player.endLoc = Vector3fImmutable.ZERO;
|
||||||
|
|
||||||
//get level based on experience
|
//get level based on experience
|
||||||
player.level = (short) Experience.getLevel(player.exp);
|
player.level = (short) Experience.getLevel(player, player.exp);
|
||||||
|
|
||||||
player.setHealth(999999f);
|
player.setHealth(999999f);
|
||||||
player.mana.set(999999f);
|
player.mana.set(999999f);
|
||||||
@@ -1353,10 +1350,10 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
public static float getDexPenalty(Item armor) {
|
public static float getDexPenalty(Item armor) {
|
||||||
if (armor == null)
|
if (armor == null)
|
||||||
return 0f;
|
return 0f;
|
||||||
ItemTemplate ab = armor.template;
|
CObjectTemplate ab = armor.template;
|
||||||
if (ab == null)
|
if (ab == null)
|
||||||
return 0f;
|
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) {
|
public static void InitializeSkillsOnLoad(PlayerCharacter pc) {
|
||||||
@@ -2816,22 +2813,22 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
if (item == null)
|
if (item == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ItemTemplate ib = item.template;
|
CObjectTemplate ib = item.template;
|
||||||
if (ib != null) {
|
if (ib != null) {
|
||||||
|
|
||||||
if ((item.template.item_type.equals(ItemType.WEAPON))
|
if ((item.template.getItemType().equals(ItemType.WEAPON))
|
||||||
&& (item.template.item_skill_used.equals(type) || ib.item_skill_mastery_used.equals(type)))
|
&& (item.template.getItemSkillUsed().equals(type) || ib.getItemSkillMasteryUsed().equals(type)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return (item.template.item_type.equals(ItemType.ARMOR))
|
return (item.template.getItemType().equals(ItemType.ARMOR))
|
||||||
&& (item.template.item_skill_used.equals(type));
|
&& (item.template.getItemSkillUsed().equals(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getPCLevel() {
|
public short getPCLevel() {
|
||||||
short level = (short) Experience.getLevel(this.exp);
|
short level = (short) Experience.getLevel(this, this.exp);
|
||||||
if (this.promotionClass == null && level >= 10)
|
if (this.promotionClass == null && level >= 10)
|
||||||
return (short) 10;
|
return (short) 10;
|
||||||
|
|
||||||
@@ -2876,8 +2873,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
|
|
||||||
public synchronized void grantXP(int xp) {
|
public synchronized void grantXP(int xp) {
|
||||||
// Stop players from getting experience past the cap
|
// Stop players from getting experience past the cap
|
||||||
if (this.exp + xp >= Experience.getBaseExperience(MBServerStatics.LEVELCAP))
|
if (this.exp + xp >= Experience.getBaseExperience(this, MBServerStatics.LEVELCAP))
|
||||||
xp = Experience.getBaseExperience(MBServerStatics.LEVELCAP) - this.exp + 1;
|
xp = Experience.getBaseExperience(this, MBServerStatics.LEVELCAP) - this.exp + 1;
|
||||||
|
|
||||||
if (xp == 0)
|
if (xp == 0)
|
||||||
xp = 1;
|
xp = 1;
|
||||||
@@ -2893,7 +2890,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
//not promoted at level 10, start checking for negative EXP
|
//not promoted at level 10, start checking for negative EXP
|
||||||
if (this.promotionClass == null && this.getLevel() == 10) {
|
if (this.promotionClass == null && this.getLevel() == 10) {
|
||||||
|
|
||||||
if (this.getExp() == Experience.getBaseExperience(11)) {
|
if (this.getExp() == Experience.getBaseExperience(this, 11)) {
|
||||||
if (this.overFlowEXP == 110000)
|
if (this.overFlowEXP == 110000)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -2916,10 +2913,10 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
//Player exp begins negative exp, add remaing exp after level 11 to overflow
|
//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.overFlowEXP = remainingXP - (Experience.getBaseExperience(this, 11) - this.getExp());
|
||||||
this.exp = Experience.getBaseExperience(11);
|
this.exp = Experience.getBaseExperience(this, 11);
|
||||||
|
|
||||||
GrantExperienceMsg grantExperienceMsg = new GrantExperienceMsg(this, remainingXP);
|
GrantExperienceMsg grantExperienceMsg = new GrantExperienceMsg(this, remainingXP);
|
||||||
Dispatch dispatch = Dispatch.borrow(this, grantExperienceMsg);
|
Dispatch dispatch = Dispatch.borrow(this, grantExperienceMsg);
|
||||||
@@ -2951,7 +2948,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
else
|
else
|
||||||
nextLevel = level + 2;
|
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.
|
// 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.
|
//Use level + 2 experience for next level.
|
||||||
@@ -2974,8 +2971,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
checkGuildStatus();
|
checkGuildStatus();
|
||||||
this.addDatabaseJob("EXP", MBServerStatics.FIVE_MINUTES);
|
this.addDatabaseJob("EXP", MBServerStatics.FIVE_MINUTES);
|
||||||
// double overflow exp used up, remaining overflow will just add to level + 1.
|
// double overflow exp used up, remaining overflow will just add to level + 1.
|
||||||
} else if (this.getExp() + this.overFlowEXP >= Experience.getBaseExperience(level + 1)) {
|
} else if (this.getExp() + this.overFlowEXP >= Experience.getBaseExperience(this, level + 1)) {
|
||||||
int nextExperience = Experience.getBaseExperience(level + 1) + this.overFlowEXP;
|
int nextExperience = Experience.getBaseExperience(this, level + 1) + this.overFlowEXP;
|
||||||
this.exp = nextExperience;
|
this.exp = nextExperience;
|
||||||
this.level++;
|
this.level++;
|
||||||
charReloadRequired = true;
|
charReloadRequired = true;
|
||||||
@@ -2991,10 +2988,10 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Hand out each Level one at a time.
|
// 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) {
|
if (isNewLevel) {
|
||||||
neededXP = Experience.getBaseExperience(this.getLevel() + 1) - this.exp;
|
neededXP = Experience.getBaseExperience(this, this.getLevel() + 1) - this.exp;
|
||||||
|
|
||||||
charReloadRequired = true;
|
charReloadRequired = true;
|
||||||
this.exp += neededXP;
|
this.exp += neededXP;
|
||||||
@@ -3768,8 +3765,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
ConcurrentHashMap<EquipSlotType, Item> equipped = this.charItemManager.getEquipped();
|
ConcurrentHashMap<EquipSlotType, Item> equipped = this.charItemManager.getEquipped();
|
||||||
Item off = equipped.get(EquipSlotType.LHELD);
|
Item off = equipped.get(EquipSlotType.LHELD);
|
||||||
Item main = equipped.get(EquipSlotType.RHELD);
|
Item main = equipped.get(EquipSlotType.RHELD);
|
||||||
ItemTemplate wbMain = null;
|
CObjectTemplate wbMain = null;
|
||||||
ItemTemplate wbOff = null;
|
CObjectTemplate wbOff = null;
|
||||||
if (main != null)
|
if (main != null)
|
||||||
wbMain = main.template;
|
wbMain = main.template;
|
||||||
if (off != null)
|
if (off != null)
|
||||||
@@ -3791,8 +3788,8 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
this.bonuses.setBool(ModType.Parry, SourceType.None, false);
|
this.bonuses.setBool(ModType.Parry, SourceType.None, false);
|
||||||
if ((this.baseClass != null && this.baseClass.getObjectUUID() == 2500)
|
if ((this.baseClass != null && this.baseClass.getObjectUUID() == 2500)
|
||||||
|| (this.promotionClass != null && this.promotionClass.getObjectUUID() == 2520))
|
|| (this.promotionClass != null && this.promotionClass.getObjectUUID() == 2520))
|
||||||
if (wbMain == null || wbMain.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 || wbOff.item_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);
|
this.bonuses.setBool(ModType.Parry, SourceType.None, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4091,7 +4088,7 @@ public class PlayerCharacter extends AbstractCharacter {
|
|||||||
tmpLevel = (short) Math.min(tmpLevel, 75);
|
tmpLevel = (short) Math.min(tmpLevel, 75);
|
||||||
|
|
||||||
while (this.level < tmpLevel) {
|
while (this.level < tmpLevel) {
|
||||||
grantXP(Experience.getBaseExperience(tmpLevel) - this.exp);
|
grantXP(Experience.getBaseExperience(this, tmpLevel) - this.exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,31 +9,25 @@
|
|||||||
|
|
||||||
package engine.objects;
|
package engine.objects;
|
||||||
|
|
||||||
import engine.gameManager.DbManager;
|
import engine.mbEnums;
|
||||||
|
import engine.parsers.objects.RuneTemplate;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
|
import engine.util.Hasher;
|
||||||
import org.pmw.tinylog.Logger;
|
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.ArrayList;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
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 int token;
|
||||||
private ConcurrentHashMap<Integer, Short> runeGrants = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
private ConcurrentHashMap<Integer, Short> runeGrants = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||||
|
|
||||||
/**
|
public PowerGrantedTrains(int token) {
|
||||||
* ResultSet Constructor
|
this.token = token;
|
||||||
*/
|
|
||||||
public PowerGrant(ResultSet rs) throws SQLException {
|
|
||||||
super();
|
|
||||||
this.token = rs.getInt("powerToken");
|
|
||||||
runeGrants.put(rs.getInt("runeID"), rs.getShort("grantAmount"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -44,11 +38,11 @@ public class PowerGrant extends AbstractGameObject {
|
|||||||
if (pc == null)
|
if (pc == null)
|
||||||
return (short) 0;
|
return (short) 0;
|
||||||
|
|
||||||
if (PowerGrant.grantedPowers == null)
|
if (PowerGrantedTrains.grantedPowers == null)
|
||||||
fillGrantedPowers();
|
loadGrantedPowers();
|
||||||
|
|
||||||
if (PowerGrant.grantedPowers.containsKey(token)) {
|
if (PowerGrantedTrains.grantedPowers.containsKey(token)) {
|
||||||
PowerGrant pg = PowerGrant.grantedPowers.get(token);
|
PowerGrantedTrains pg = PowerGrantedTrains.grantedPowers.get(token);
|
||||||
ConcurrentHashMap<Integer, Short> runeGrants = pg.runeGrants;
|
ConcurrentHashMap<Integer, Short> runeGrants = pg.runeGrants;
|
||||||
ArrayList<Integer> toks = new ArrayList<>();
|
ArrayList<Integer> toks = new ArrayList<>();
|
||||||
|
|
||||||
@@ -88,39 +82,33 @@ public class PowerGrant extends AbstractGameObject {
|
|||||||
return (short) 0;
|
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();
|
for (RuneTemplate rune : RuneTemplate._runes.values()) {
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_power_powergrant")) {
|
|
||||||
|
|
||||||
|
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) {
|
if (powerAction.getValue().isEmpty())
|
||||||
rs.close();
|
continue;
|
||||||
return;
|
|
||||||
|
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) {
|
private void addRuneGrant(int runeID, short amount) {
|
||||||
this.runeGrants.put(runeID, amount);
|
this.runeGrants.put(runeID, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateDatabase() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -10,8 +10,13 @@
|
|||||||
package engine.objects;
|
package engine.objects;
|
||||||
|
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
|
import engine.mbEnums;
|
||||||
import engine.mbEnums.GameObjectType;
|
import engine.mbEnums.GameObjectType;
|
||||||
import engine.net.ByteBufferWriter;
|
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.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@@ -28,11 +33,6 @@ public class PromotionClass extends AbstractGameObject {
|
|||||||
private final ArrayList<Integer> allowedRunes;
|
private final ArrayList<Integer> allowedRunes;
|
||||||
private final ArrayList<SkillReq> skillsGranted;
|
private final ArrayList<SkillReq> skillsGranted;
|
||||||
private final ArrayList<PowerReq> powersGranted;
|
private final ArrayList<PowerReq> powersGranted;
|
||||||
private final ArrayList<RuneBaseEffect> effectsGranted;
|
|
||||||
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 int token = 0;
|
||||||
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
||||||
|
|
||||||
@@ -50,11 +50,6 @@ public class PromotionClass extends AbstractGameObject {
|
|||||||
this.healthMod = 0f;
|
this.healthMod = 0f;
|
||||||
this.manaMod = 0f;
|
this.manaMod = 0f;
|
||||||
this.staminaMod = 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.healthMod = 0f;
|
||||||
this.manaMod = 0f;
|
this.manaMod = 0f;
|
||||||
this.staminaMod = 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
|
* 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 {
|
public PromotionClass(ResultSet rs) throws SQLException {
|
||||||
super(rs);
|
super(rs);
|
||||||
@@ -90,19 +81,82 @@ public class PromotionClass extends AbstractGameObject {
|
|||||||
this.healthMod = rs.getFloat("healthMod");
|
this.healthMod = rs.getFloat("healthMod");
|
||||||
this.manaMod = rs.getFloat("manaMod");
|
this.manaMod = rs.getFloat("manaMod");
|
||||||
this.staminaMod = rs.getFloat("staminaMod");
|
this.staminaMod = rs.getFloat("staminaMod");
|
||||||
this.allowedRunes = DbManager.PromotionQueries.GET_ALLOWED_RUNES(this);
|
this.allowedRunes = new ArrayList<>();
|
||||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.getObjectUUID());
|
this.skillsGranted = SkillReq.getSkillReqsForRune(this.getObjectUUID());
|
||||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
||||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.getObjectUUID());
|
this.effectsList = MobBaseEffects.getEffectsForRune(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());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
public static void serializeForClientMsg(PromotionClass promotionClass, ByteBufferWriter writer) {
|
||||||
writer.putInt(3); // For BaseClass
|
writer.putInt(3); // For BaseClass
|
||||||
writer.putInt(0); // Pad
|
writer.putInt(0); // Pad
|
||||||
@@ -169,23 +223,6 @@ public class PromotionClass extends AbstractGameObject {
|
|||||||
* Serializing
|
* 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
|
@Override
|
||||||
public void updateDatabase() {
|
public void updateDatabase() {
|
||||||
// TODO Create update logic.
|
// TODO Create update logic.
|
||||||
|
|||||||
+101
-45
@@ -11,14 +11,18 @@ package engine.objects;
|
|||||||
|
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
import engine.mbEnums;
|
import engine.mbEnums;
|
||||||
import engine.mbEnums.RaceType;
|
|
||||||
import engine.net.ByteBufferWriter;
|
import engine.net.ByteBufferWriter;
|
||||||
|
import engine.parsers.cache.CacheParserUtil;
|
||||||
|
import engine.parsers.objects.RuneTemplate;
|
||||||
import engine.server.MBServerStatics;
|
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.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class Race {
|
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);
|
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 name;
|
||||||
private final String description;
|
private final String description;
|
||||||
private final int raceRuneID;
|
private final int raceRuneID;
|
||||||
@@ -64,57 +71,114 @@ public class Race {
|
|||||||
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
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.raceType = mbEnums.RaceType.getRaceTypebyRuneID(raceRuneID);
|
||||||
this.name = rs.getString("name");
|
this.name = rune.obj_name;
|
||||||
this.description = rs.getString("description");
|
this.description = rune.rune_dsc;
|
||||||
this.strStart = rs.getShort("strStart");
|
this.strStart = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Strength, 0).shortValue();
|
||||||
this.strMin = rs.getShort("strMin");
|
this.strMin = 0;
|
||||||
this.strMax = rs.getShort("strMax");
|
this.strMax = rune.rune_max_attr_adj.getOrDefault(mbEnums.AttributeType.Strength, 0).shortValue();
|
||||||
this.dexStart = rs.getShort("dexStart");
|
this.dexStart = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Dexterity, 0).shortValue();
|
||||||
this.dexMin = rs.getShort("dexMin");
|
this.dexMin = 0;
|
||||||
this.dexMax = rs.getShort("dexMax");
|
this.dexMax = rune.rune_max_attr_adj.getOrDefault(mbEnums.AttributeType.Dexterity, 0).shortValue();
|
||||||
this.conStart = rs.getShort("conStart");
|
this.conStart = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Constitution, 0).shortValue();
|
||||||
this.conMin = rs.getShort("conMin");
|
this.conMin = 0;
|
||||||
this.conMax = rs.getShort("conMax");
|
this.conMax = rune.rune_max_attr_adj.getOrDefault(mbEnums.AttributeType.Constitution, 0).shortValue();
|
||||||
this.intStart = rs.getShort("intStart");
|
this.intStart = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Intelligence, 0).shortValue();
|
||||||
this.intMin = rs.getShort("intMin");
|
this.intMin = 0;
|
||||||
this.intMax = rs.getShort("intMax");
|
this.intMax = rune.rune_max_attr_adj.getOrDefault(mbEnums.AttributeType.Intelligence, 0).shortValue();
|
||||||
this.spiStart = rs.getShort("spiStart");
|
this.spiStart = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Spirit, 0).shortValue();
|
||||||
this.spiMin = rs.getShort("spiMin");
|
this.spiMin = 0;
|
||||||
this.spiMax = rs.getShort("spiMax");
|
this.spiMax = rune.rune_max_attr_adj.getOrDefault(mbEnums.AttributeType.Spirit, 0).shortValue();
|
||||||
this.token = rs.getInt("token");
|
this.token = Hasher.SBStringHash(rune.rune_sub_type);
|
||||||
this.healthBonus = rs.getShort("healthBonus");
|
this.healthBonus = (short) rune.rune_health;
|
||||||
this.manaBonus = rs.getShort("manaBonus");
|
this.manaBonus = (short) rune.rune_mana;
|
||||||
this.staminaBonus = rs.getShort("staminaBonus");
|
this.staminaBonus = (short) rune.rune_stamina;
|
||||||
this.startingPoints = rs.getByte("startingPoints");
|
this.startingPoints = (byte) (STARTING_POINT_POOL - rune.rune_creation_cost);
|
||||||
this.raceType = RaceType.getRaceTypebyRuneID(this.raceRuneID);
|
this.minHeight = heights[0];
|
||||||
this.minHeight = rs.getFloat("minHeight");
|
this.strHeightMod = heights[1];
|
||||||
this.strHeightMod = rs.getFloat("strHeightMod");
|
this.hairStyles = new HashSet<>(rune.rune_hair);
|
||||||
this.hairStyles = DbManager.RaceQueries.HAIR_STYLES_FOR_RACE(raceRuneID);
|
this.beardStyles = new HashSet<>(rune.rune_beard);
|
||||||
this.beardStyles = DbManager.RaceQueries.BEARD_STYLES_FOR_RACE(raceRuneID);
|
|
||||||
this.skinColors = DbManager.RaceQueries.SKIN_COLOR_FOR_RACE(raceRuneID);
|
this.skinColors = DbManager.RaceQueries.SKIN_COLOR_FOR_RACE(raceRuneID);
|
||||||
this.beardColors = DbManager.RaceQueries.BEARD_COLORS_FOR_RACE(raceRuneID);
|
this.beardColors = DbManager.RaceQueries.BEARD_COLORS_FOR_RACE(raceRuneID);
|
||||||
this.hairColors = DbManager.RaceQueries.HAIR_COLORS_FOR_RACE(raceRuneID);
|
this.hairColors = DbManager.RaceQueries.HAIR_COLORS_FOR_RACE(raceRuneID);
|
||||||
this.baseClasses = DbManager.BaseClassQueries.GET_BASECLASS_FOR_RACE(raceRuneID);
|
this.baseClasses = getBaseClassesForRace(rune);
|
||||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(raceRuneID);
|
this.skillsGranted = SkillReq.getSkillReqsForRune(raceRuneID);
|
||||||
this.powersGranted = PowerReq.getPowerReqsForRune(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() {
|
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) {
|
public static Race getRace(int id) {
|
||||||
return _raceByID.get(id);
|
return _raceByID.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Collection<Race> getAllRaces() {
|
||||||
|
return _raceByID.values();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object object) {
|
public boolean equals(Object object) {
|
||||||
|
|
||||||
@@ -258,10 +322,6 @@ public class Race {
|
|||||||
return this.powersGranted;
|
return this.powersGranted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<RuneBaseEffect> getEffectsGranted() {
|
|
||||||
return RuneBaseEffect.RuneIDBaseEffectMap.get(this.raceRuneID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validators
|
* Validators
|
||||||
*/
|
*/
|
||||||
@@ -290,10 +350,6 @@ public class Race {
|
|||||||
if (this.getAllowedRunes() != null)
|
if (this.getAllowedRunes() != null)
|
||||||
if (this.getAllowedRunes().contains(rb.getObjectUUID()))
|
if (this.getAllowedRunes().contains(rb.getObjectUUID()))
|
||||||
return true;
|
return true;
|
||||||
if (RuneBase.AllowedBaseClassRunesMap.containsKey(111111)) {
|
|
||||||
if (RuneBase.AllowedRaceRunesMap.get(111111).contains(rb.getObjectUUID()))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.pmw.tinylog.Logger;
|
|||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.EnumMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@@ -159,13 +160,16 @@ public class Resists {
|
|||||||
|
|
||||||
private static float[] getArmorResists(Item armor, float[] phys) {
|
private static float[] getArmorResists(Item armor, float[] phys) {
|
||||||
|
|
||||||
|
EnumMap<mbEnums.DamageType, Float> armorResists;
|
||||||
|
|
||||||
if (armor == null)
|
if (armor == null)
|
||||||
return phys;
|
return phys;
|
||||||
|
|
||||||
if (armor.template.item_type.equals(mbEnums.ItemType.ARMOR)) {
|
if (armor.template.getItemType().equals(mbEnums.ItemType.ARMOR)) {
|
||||||
phys[0] += armor.template.combat_attack_resist.get("SLASHING");
|
armorResists = armor.template.getCombatAttackResist();
|
||||||
phys[1] += armor.template.combat_attack_resist.get("CRUSHING");
|
phys[0] += armorResists.getOrDefault(mbEnums.DamageType.SLASHING, 0f);
|
||||||
phys[2] += armor.template.combat_attack_resist.get("PIERCING");
|
phys[1] += armorResists.getOrDefault(mbEnums.DamageType.CRUSHING, 0f);
|
||||||
|
phys[2] += armorResists.getOrDefault(mbEnums.DamageType.PIERCING, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return phys;
|
return phys;
|
||||||
|
|||||||
@@ -11,13 +11,17 @@ package engine.objects;
|
|||||||
|
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
import engine.mbEnums;
|
import engine.mbEnums;
|
||||||
import engine.net.ByteBufferWriter;
|
import engine.parsers.cache.CObjectIndex;
|
||||||
|
import engine.parsers.objects.RuneTemplate;
|
||||||
import engine.server.MBServerStatics;
|
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.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
|
||||||
@@ -25,57 +29,88 @@ public class RuneBase extends AbstractGameObject {
|
|||||||
|
|
||||||
public static HashMap<Integer, ArrayList<Integer>> AllowedBaseClassRunesMap = new HashMap<>();
|
public static HashMap<Integer, ArrayList<Integer>> AllowedBaseClassRunesMap = new HashMap<>();
|
||||||
public static HashMap<Integer, ArrayList<Integer>> AllowedRaceRunesMap = new HashMap<>();
|
public static HashMap<Integer, ArrayList<Integer>> AllowedRaceRunesMap = new HashMap<>();
|
||||||
|
// Flagged rune_is_standard_character_creation but missing from CharCreateRuneList.cfg ATTRRUNES:
|
||||||
|
// admin runes 2910/2911, unused duplicates, and Proficient with Bows (commented out in the cfg).
|
||||||
|
private static final Set<Integer> NON_CREATION_TALENTS = new HashSet<>(Arrays.asList(2910, 2911, 250081, 250116, 250117, 250123, 250124, 250125));
|
||||||
private final String name;
|
private final String name;
|
||||||
private final String description;
|
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> 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> 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> 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 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 int levelRequired = 1;
|
||||||
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
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) {
|
public RuneBase(RuneTemplate rune) {
|
||||||
super();
|
super(rune.template_id);
|
||||||
|
|
||||||
this.name = name;
|
Integer classRuneID;
|
||||||
this.description = description;
|
Integer discRuneID;
|
||||||
this.type = type;
|
ArrayList<Integer> raceRuneIDs;
|
||||||
this.subtype = subtype;
|
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;
|
||||||
|
|
||||||
/**
|
for (mbEnums.MonsterType raceType : rune.item_race_req) {
|
||||||
* Normal Constructor
|
raceRuneIDs = CObjectIndex.getRaceRuneIds(raceType);
|
||||||
*/
|
|
||||||
public RuneBase(String name, String description, int type, byte subtype, ArrayList<RuneBaseAttribute> attrs, int newUUID) {
|
|
||||||
super(newUUID);
|
|
||||||
|
|
||||||
this.name = name;
|
if (raceRuneIDs.isEmpty())
|
||||||
this.description = description;
|
Logger.warn("RuneBase " + rune.template_id + ": race " + raceType + " has no race rune");
|
||||||
this.type = type;
|
|
||||||
this.subtype = subtype;
|
|
||||||
|
|
||||||
}
|
for (int raceRuneID : raceRuneIDs)
|
||||||
|
this.race.put(raceRuneID, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
for (mbEnums.ClassType classType : rune.item_class_req) {
|
||||||
* ResultSet Constructor
|
classRuneID = CObjectIndex.getClassRuneId(classType);
|
||||||
*/
|
|
||||||
public RuneBase(ResultSet rs) throws SQLException {
|
|
||||||
super(rs);
|
|
||||||
|
|
||||||
this.name = rs.getString("name");
|
if (classRuneID == null) {
|
||||||
this.description = rs.getString("description");
|
Logger.warn("RuneBase " + rune.template_id + ": class " + classType + " has no class rune");
|
||||||
this.type = rs.getInt("type");
|
continue;
|
||||||
this.subtype = rs.getByte("subtype");
|
}
|
||||||
|
|
||||||
DbManager.RuneBaseQueries.GET_RUNE_REQS(this);
|
classRune = RuneTemplate._runes.get(classRuneID);
|
||||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID());
|
|
||||||
|
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) {
|
public static RuneBase getRuneBase(int tableId) {
|
||||||
@@ -83,28 +118,113 @@ public class RuneBase extends AbstractGameObject {
|
|||||||
if (tableId == 0)
|
if (tableId == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
RuneBase rb = (RuneBase) DbManager.getFromCache(mbEnums.GameObjectType.RuneBase, tableId);
|
return (RuneBase) DbManager.getFromCache(mbEnums.GameObjectType.RuneBase, tableId);
|
||||||
|
|
||||||
if (rb != null)
|
|
||||||
return rb;
|
|
||||||
|
|
||||||
return DbManager.RuneBaseQueries.GET_RUNEBASE(tableId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void serializeForClientMsg(RuneBase runeBase, ByteBufferWriter writer) {
|
// Rune bases are every non-RACE rune: the classes, disciplines and talents (the 315 former static_rune_runebase rows).
|
||||||
writer.putInt(runeBase.type);
|
|
||||||
writer.putInt(0); // Pad
|
|
||||||
writer.putInt(runeBase.getObjectUUID());
|
|
||||||
writer.putInt(runeBase.getObjectType().ordinal());
|
|
||||||
writer.putInt(runeBase.getObjectUUID());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void LoadAllRuneBases() {
|
public static void LoadAllRuneBases() {
|
||||||
|
|
||||||
DbManager.RuneBaseQueries.LOAD_ALL_RUNEBASES();
|
ArrayList<RuneBaseAttribute> attributes;
|
||||||
RuneBase.AllowedBaseClassRunesMap = DbManager.RuneBaseQueries.LOAD_ALLOWED_STARTING_RUNES_FOR_BASECLASS();
|
int loadedCount = 0;
|
||||||
RuneBase.AllowedRaceRunesMap = DbManager.RuneBaseQueries.LOAD_ALLOWED_STARTING_RUNES_FOR_RACE();
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (NON_CREATION_TALENTS.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
|
@Override
|
||||||
@@ -124,15 +244,6 @@ public class RuneBase extends AbstractGameObject {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.type != rbObj.type) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.subtype != rbObj.subtype) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,17 +261,6 @@ public class RuneBase extends AbstractGameObject {
|
|||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the subtype
|
|
||||||
*/
|
|
||||||
public byte getSubtype() {
|
|
||||||
return subtype;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the attrs
|
* @return the attrs
|
||||||
*/
|
*/
|
||||||
@@ -184,8 +284,30 @@ public class RuneBase extends AbstractGameObject {
|
|||||||
return this.discipline;
|
return this.discipline;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Integer> getOverwrite() {
|
public mbEnums.RuneType getRuneType() {
|
||||||
return this.overwrite;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
|
|
||||||
package engine.objects;
|
package engine.objects;
|
||||||
|
|
||||||
import engine.gameManager.DbManager;
|
import engine.mbEnums;
|
||||||
import engine.mbEnums.GameObjectType;
|
import engine.parsers.objects.RuneTemplate;
|
||||||
|
import engine.server.MBServerStatics;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumMap;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
|
||||||
@@ -23,7 +23,6 @@ public class RuneBaseAttribute extends AbstractGameObject {
|
|||||||
public static HashMap<Integer, ArrayList<RuneBaseAttribute>> runeBaseAttributeMap = new HashMap<>();
|
public static HashMap<Integer, ArrayList<RuneBaseAttribute>> runeBaseAttributeMap = new HashMap<>();
|
||||||
private short attributeID;
|
private short attributeID;
|
||||||
private short modValue;
|
private short modValue;
|
||||||
private int runeBaseID;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,39 +45,31 @@ public class RuneBaseAttribute extends AbstractGameObject {
|
|||||||
this.modValue = modValue;
|
this.modValue = modValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Attribute ids: 0 = rune_creation_cost, 1-5 = rune_attr_adj, 6-10 = rune_max_attr_adj,
|
||||||
* ResultSet Constructor
|
// 11-15 = item_attr_req; the AttributeType ordinals Strength..Spirit are 1-5.
|
||||||
*/
|
|
||||||
public RuneBaseAttribute(ResultSet rs) throws SQLException {
|
|
||||||
super(rs);
|
|
||||||
|
|
||||||
this.attributeID = rs.getShort("attributeID");
|
public static ArrayList<RuneBaseAttribute> getAttributesForRune(RuneTemplate rune) {
|
||||||
this.modValue = rs.getShort("modValue");
|
|
||||||
this.runeBaseID = rs.getInt("RuneBaseID");
|
ArrayList<RuneBaseAttribute> attributes = new ArrayList<>();
|
||||||
|
|
||||||
|
if (rune.rune_creation_cost != 0)
|
||||||
|
attributes.add(new RuneBaseAttribute((short) MBServerStatics.RUNE_COST_ATTRIBUTE_ID, (short) rune.rune_creation_cost));
|
||||||
|
|
||||||
|
addAttributes(attributes, rune.rune_attr_adj, 0);
|
||||||
|
addAttributes(attributes, rune.rune_max_attr_adj, 5);
|
||||||
|
addAttributes(attributes, rune.item_attr_req, 10);
|
||||||
|
|
||||||
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LoadAllAttributes() {
|
private static void addAttributes(ArrayList<RuneBaseAttribute> attributes, EnumMap<mbEnums.AttributeType, Integer> values, int idOffset) {
|
||||||
DbManager.RuneBaseAttributeQueries.GET_ATTRIBUTES_FOR_RUNEBASE();
|
|
||||||
|
|
||||||
|
for (mbEnums.AttributeType attributeType : values.keySet()) {
|
||||||
|
if (values.get(attributeType) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
//cache attributeLists for rune.
|
attributes.add(new RuneBaseAttribute((short) (attributeType.ordinal() + idOffset), values.get(attributeType).shortValue()));
|
||||||
for (AbstractGameObject ago : DbManager.getList(GameObjectType.RuneBaseAttribute)) {
|
|
||||||
|
|
||||||
RuneBaseAttribute runeBaseAttribute = (RuneBaseAttribute) ago;
|
|
||||||
|
|
||||||
int runeBaseID = ((RuneBaseAttribute) runeBaseAttribute).runeBaseID;
|
|
||||||
if (runeBaseAttributeMap.get(runeBaseID) == null) {
|
|
||||||
ArrayList<RuneBaseAttribute> attributeList = new ArrayList<>();
|
|
||||||
attributeList.add(runeBaseAttribute);
|
|
||||||
runeBaseAttributeMap.put(runeBaseID, attributeList);
|
|
||||||
} else {
|
|
||||||
ArrayList<RuneBaseAttribute> attributeList = runeBaseAttributeMap.get(runeBaseID);
|
|
||||||
attributeList.add(runeBaseAttribute);
|
|
||||||
runeBaseAttributeMap.put(runeBaseID, attributeList);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
|
||||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
|
||||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
|
||||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
|
||||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
|
||||||
// Magicbane Emulator Project © 2013 - 2026
|
|
||||||
// https://www.magicbane.com
|
|
||||||
|
|
||||||
|
|
||||||
package engine.objects;
|
|
||||||
|
|
||||||
import engine.gameManager.DbManager;
|
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
|
|
||||||
public class RuneBaseEffect extends AbstractGameObject {
|
|
||||||
|
|
||||||
public static HashMap<Integer, ArrayList<RuneBaseEffect>> RuneIDBaseEffectMap = new HashMap<>();
|
|
||||||
private byte type;
|
|
||||||
private String name;
|
|
||||||
private short amount;
|
|
||||||
private int runeBaseID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ResultSet Constructor
|
|
||||||
*/
|
|
||||||
public RuneBaseEffect(ResultSet rs) throws SQLException {
|
|
||||||
super(rs);
|
|
||||||
this.type = rs.getByte("type");
|
|
||||||
this.name = rs.getString("name");
|
|
||||||
this.amount = rs.getShort("amount");
|
|
||||||
this.runeBaseID = rs.getInt("runeID");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Getters
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static void LoadRuneBaseEffects() {
|
|
||||||
//cache runebase effects.
|
|
||||||
DbManager.RuneBaseEffectQueries.GET_ALL_RUNEBASE_EFFECTS();
|
|
||||||
//store runebase effects in new hashmap.
|
|
||||||
RuneBaseEffect.RuneIDBaseEffectMap = DbManager.RuneBaseEffectQueries.LOAD_BASEEFFECTS_FOR_RUNEBASE();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getType() {
|
|
||||||
return this.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getAmount() {
|
|
||||||
return this.amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateDatabase() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRuneBaseID() {
|
|
||||||
return runeBaseID;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -256,13 +256,13 @@ public class Shrine extends AbstractWorldObject implements Comparable<Shrine> {
|
|||||||
if (!boonOwner.charItemManager.doesCharOwnThisItem(boonItem.getObjectUUID()))
|
if (!boonOwner.charItemManager.doesCharOwnThisItem(boonItem.getObjectUUID()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (ShrineType boonShrineType : boonItem.template.item_offering_info.keySet()) {
|
for (ShrineType boonShrineType : boonItem.template.getItemOfferingInfo().keySet()) {
|
||||||
|
|
||||||
if (boonShrineType != shrineType)
|
if (boonShrineType != shrineType)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//Same Shrine Type, add favors and stop loop.
|
//Same Shrine Type, add favors and stop loop.
|
||||||
int amount = boonItem.template.item_offering_info.get(boonShrineType) * boonItem.getNumOfItems();
|
int amount = boonItem.template.getItemOfferingInfo().get(boonShrineType) * boonItem.getNumOfItems();
|
||||||
int oldAmount = this.favors;
|
int oldAmount = this.favors;
|
||||||
|
|
||||||
if (!DbManager.ShrineQueries.updateFavors(this, this.favors + amount, oldAmount)) {
|
if (!DbManager.ShrineQueries.updateFavors(this, this.favors + amount, oldAmount)) {
|
||||||
|
|||||||
@@ -10,18 +10,25 @@
|
|||||||
package engine.objects;
|
package engine.objects;
|
||||||
|
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
|
import engine.parsers.objects.RuneTemplate;
|
||||||
|
import engine.server.MBServerStatics;
|
||||||
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
|
||||||
public class SkillReq extends AbstractGameObject {
|
public class SkillReq extends AbstractGameObject {
|
||||||
|
|
||||||
|
private static final int DEFAULT_SKILL_REQ_AMOUNT = 80;
|
||||||
|
private static final ConcurrentHashMap<Integer, ArrayList<SkillReq>> skillReqsByRune = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||||
|
|
||||||
private int skillID;
|
private int skillID;
|
||||||
private short level;
|
private short level;
|
||||||
private ArrayList<Byte> skillReqs;
|
private ArrayList<Byte> skillReqs;
|
||||||
|
private HashMap<Byte, Integer> skillReqAmounts;
|
||||||
|
|
||||||
/* This shouldn't be used
|
/* This shouldn't be used
|
||||||
public SkillReq(SkillsBase skillsBase, short level, ArrayList<Byte>skillReqs) {
|
public SkillReq(SkillsBase skillsBase, short level, ArrayList<Byte>skillReqs) {
|
||||||
@@ -52,25 +59,62 @@ public class SkillReq extends AbstractGameObject {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
// skill_value is the level the skill is granted at; skill_granted_skills are prereq skills with amounts
|
||||||
* ResultSet Constructor
|
public SkillReq(RuneTemplate.SkillGrant skillGrant, SkillsBase skillsBase, int runeID) {
|
||||||
*/
|
super();
|
||||||
public SkillReq(ResultSet rs) throws SQLException {
|
|
||||||
super(rs, 0);
|
|
||||||
this.skillID = rs.getInt("skillID");
|
|
||||||
this.level = rs.getShort("level");
|
|
||||||
skillReqs = new ArrayList<>(0);
|
|
||||||
|
|
||||||
int skillReq;
|
SkillsBase reqSkillsBase;
|
||||||
skillReq = rs.getInt("skillreq1");
|
|
||||||
if (skillReq > 0)
|
this.skillID = skillsBase.getObjectUUID();
|
||||||
skillReqs.add((byte) skillReq);
|
this.level = (short) skillGrant.skill_value;
|
||||||
skillReq = rs.getInt("skillreq2");
|
this.skillReqs = new ArrayList<>(0);
|
||||||
if (skillReq > 0)
|
this.skillReqAmounts = new HashMap<>();
|
||||||
skillReqs.add((byte) skillReq);
|
|
||||||
skillReq = rs.getInt("skillreq3");
|
for (Map.Entry<String, Integer> reqSkill : skillGrant.skill_granted_skills.entrySet()) {
|
||||||
if (skillReq > 0)
|
|
||||||
skillReqs.add((byte) skillReq);
|
reqSkillsBase = DbManager.SkillsBaseQueries.GET_BASE_BY_NAME(reqSkill.getKey());
|
||||||
|
|
||||||
|
if (reqSkillsBase == null) {
|
||||||
|
Logger.warn("Rune " + runeID + " skill grant " + skillGrant.skill_type + ": unknown prereq skill " + reqSkill.getKey());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.skillReqs.add((byte) reqSkillsBase.getObjectUUID());
|
||||||
|
this.skillReqAmounts.put((byte) reqSkillsBase.getObjectUUID(), reqSkill.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ArrayList<SkillReq> getSkillReqsForRune(int runeID) {
|
||||||
|
return skillReqsByRune.computeIfAbsent(runeID, SkillReq::loadSkillReqsForRune);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ArrayList<SkillReq> loadSkillReqsForRune(int runeID) {
|
||||||
|
|
||||||
|
ArrayList<SkillReq> runeSkillReqs = new ArrayList<>();
|
||||||
|
ArrayList<String> skippedGrants = new ArrayList<>();
|
||||||
|
RuneTemplate rune = RuneTemplate._runes.get(runeID);
|
||||||
|
SkillsBase skillsBase;
|
||||||
|
|
||||||
|
if (rune == null)
|
||||||
|
return runeSkillReqs;
|
||||||
|
|
||||||
|
for (RuneTemplate.SkillGrant skillGrant : rune.rune_skill_grant) {
|
||||||
|
|
||||||
|
skillsBase = DbManager.SkillsBaseQueries.GET_BASE_BY_NAME(skillGrant.skill_type);
|
||||||
|
|
||||||
|
if (skillsBase == null) {
|
||||||
|
skippedGrants.add(skillGrant.skill_type);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
runeSkillReqs.add(new SkillReq(skillGrant, skillsBase, runeID));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expected at every boot: Archon 2018 lists resistances as skill grants (Duelist 3010 lists Dueling); not a bug
|
||||||
|
if (!skippedGrants.isEmpty())
|
||||||
|
Logger.warn("Rune " + runeID + ": skipped non-skill grants " + skippedGrants);
|
||||||
|
|
||||||
|
return runeSkillReqs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -92,6 +136,10 @@ public class SkillReq extends AbstractGameObject {
|
|||||||
return this.skillReqs;
|
return this.skillReqs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getSkillReqAmount(byte reqSkillID) {
|
||||||
|
return this.skillReqAmounts.getOrDefault(reqSkillID, DEFAULT_SKILL_REQ_AMOUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateDatabase() {
|
public void updateDatabase() {
|
||||||
|
|||||||
@@ -11,11 +11,16 @@ package engine.objects;
|
|||||||
|
|
||||||
import engine.gameManager.DbManager;
|
import engine.gameManager.DbManager;
|
||||||
import engine.mbEnums.SourceType;
|
import engine.mbEnums.SourceType;
|
||||||
|
import engine.parsers.objects.RuneTemplate;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
|
import engine.util.Hasher;
|
||||||
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
|
||||||
@@ -102,6 +107,31 @@ public class SkillsBase extends AbstractGameObject {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Level 0 adjusts are the skills a rune grants outright; higher levels are trainer caps
|
||||||
|
public static void LoadAllRuneSkills() {
|
||||||
|
|
||||||
|
HashMap<Integer, Integer> grantedSkills;
|
||||||
|
int entryCount = 0;
|
||||||
|
|
||||||
|
for (RuneTemplate rune : RuneTemplate._runes.values()) {
|
||||||
|
|
||||||
|
grantedSkills = new HashMap<>();
|
||||||
|
|
||||||
|
for (Map.Entry<String, ArrayList<int[]>> skillAdjust : rune.rune_skill_adj.entrySet())
|
||||||
|
for (int[] adjust : skillAdjust.getValue())
|
||||||
|
if (adjust[1] == 0)
|
||||||
|
grantedSkills.put(Hasher.SBStringHash(skillAdjust.getKey()), adjust[0]);
|
||||||
|
|
||||||
|
if (grantedSkills.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
runeSkillsCache.put(rune.template_id, grantedSkills);
|
||||||
|
entryCount += grantedSkills.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info("Loaded " + entryCount + " granted skills for " + runeSkillsCache.size() + " runes");
|
||||||
|
}
|
||||||
|
|
||||||
public static void putInCache(SkillsBase sb) {
|
public static void putInCache(SkillsBase sb) {
|
||||||
|
|
||||||
if (sb == null)
|
if (sb == null)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import engine.mbEnums;
|
|||||||
import engine.net.Dispatch;
|
import engine.net.Dispatch;
|
||||||
import engine.net.client.ClientConnection;
|
import engine.net.client.ClientConnection;
|
||||||
import engine.net.client.msg.*;
|
import engine.net.client.msg.*;
|
||||||
|
import engine.parsers.objects.CObjectTemplate;
|
||||||
import engine.server.MBServerStatics;
|
import engine.server.MBServerStatics;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
@@ -304,10 +305,10 @@ public class Warehouse {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resource.template.item_type.equals(mbEnums.ItemType.GOLD))
|
if (resource.template.getItemType().equals(mbEnums.ItemType.GOLD))
|
||||||
resourceType = mbEnums.ResourceType.GOLD;
|
resourceType = mbEnums.ResourceType.GOLD;
|
||||||
else
|
else
|
||||||
resourceType = mbEnums.ResourceType.valueOf(ItemTemplate.templates.get(resource.templateID).item_base_name.toUpperCase());
|
resourceType = mbEnums.ResourceType.valueOf(CObjectTemplate.lookup(resource.templateID).getItemBaseName().toUpperCase());
|
||||||
|
|
||||||
if (transaction)
|
if (transaction)
|
||||||
AddTransactionToWarehouse(warehouse, playerCharacter.getObjectType(), playerCharacter.getObjectUUID(), mbEnums.TransactionType.DEPOSIT, resourceType, amount);
|
AddTransactionToWarehouse(warehouse, playerCharacter.getObjectType(), playerCharacter.getObjectUUID(), mbEnums.TransactionType.DEPOSIT, resourceType, amount);
|
||||||
@@ -418,7 +419,7 @@ public class Warehouse {
|
|||||||
if (playerCharacter == null)
|
if (playerCharacter == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ItemTemplate template = ItemTemplate.templates.get(resourceType.templateID);
|
CObjectTemplate template = CObjectTemplate.lookup(resourceType.templateID);
|
||||||
|
|
||||||
if (warehouse.resources.get(resourceType) == null)
|
if (warehouse.resources.get(resourceType) == null)
|
||||||
return false;
|
return false;
|
||||||
@@ -432,7 +433,7 @@ public class Warehouse {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (addToInventory)
|
if (addToInventory)
|
||||||
if (!itemMan.hasRoomInventory(template.item_wt)) {
|
if (!itemMan.hasRoomInventory(template.getItemWt())) {
|
||||||
ChatManager.chatSystemInfo(playerCharacter, "You can not carry any more of that item.");
|
ChatManager.chatSystemInfo(playerCharacter, "You can not carry any more of that item.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -501,7 +502,7 @@ public class Warehouse {
|
|||||||
if (playerCharacter == null)
|
if (playerCharacter == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ItemTemplate template = ItemTemplate.templates.get(resourceType.templateID);
|
CObjectTemplate template = CObjectTemplate.lookup(resourceType.templateID);
|
||||||
|
|
||||||
if (template == null)
|
if (template == null)
|
||||||
return false;
|
return false;
|
||||||
@@ -517,7 +518,7 @@ public class Warehouse {
|
|||||||
if (itemMan == null)
|
if (itemMan == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!itemMan.hasRoomInventory(template.item_wt)) {
|
if (!itemMan.hasRoomInventory(template.getItemWt())) {
|
||||||
ChatManager.chatSystemInfo(playerCharacter, "You can not carry any more of that item.");
|
ChatManager.chatSystemInfo(playerCharacter, "You can not carry any more of that item.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -97,8 +97,14 @@ public class DeedParser {
|
|||||||
deed.item_type = CacheParserUtil.readEnum(mbEnums.ItemType.class, deedJson.getString("item_type"), templateId, "item_type");
|
deed.item_type = CacheParserUtil.readEnum(mbEnums.ItemType.class, deedJson.getString("item_type"), templateId, "item_type");
|
||||||
deed.item_eq_slots_value = deedJson.getInt("item_eq_slots_value");
|
deed.item_eq_slots_value = deedJson.getInt("item_eq_slots_value");
|
||||||
deed.item_eq_slots_type = deedJson.getBoolean("item_eq_slots_type");
|
deed.item_eq_slots_type = deedJson.getBoolean("item_eq_slots_type");
|
||||||
|
|
||||||
|
// The exporter writes ["NONE"] for an empty slot mask
|
||||||
|
|
||||||
deed.item_eq_slots_or.addAll(CacheParserUtil.readEnumSet(mbEnums.EquipSlotType.class, deedJson.getJSONArray("item_eq_slots_or"), templateId, "item_eq_slots_or"));
|
deed.item_eq_slots_or.addAll(CacheParserUtil.readEnumSet(mbEnums.EquipSlotType.class, deedJson.getJSONArray("item_eq_slots_or"), templateId, "item_eq_slots_or"));
|
||||||
|
deed.item_eq_slots_or.remove(mbEnums.EquipSlotType.NONE);
|
||||||
deed.item_eq_slots_and.addAll(CacheParserUtil.readEnumSet(mbEnums.EquipSlotType.class, deedJson.getJSONArray("item_eq_slots_and"), templateId, "item_eq_slots_and"));
|
deed.item_eq_slots_and.addAll(CacheParserUtil.readEnumSet(mbEnums.EquipSlotType.class, deedJson.getJSONArray("item_eq_slots_and"), templateId, "item_eq_slots_and"));
|
||||||
|
deed.item_eq_slots_and.remove(mbEnums.EquipSlotType.NONE);
|
||||||
|
|
||||||
deed.item_takeable = deedJson.getBoolean("item_takeable");
|
deed.item_takeable = deedJson.getBoolean("item_takeable");
|
||||||
deed.item_value = deedJson.getInt("item_value");
|
deed.item_value = deedJson.getInt("item_value");
|
||||||
deed.item_wt = deedJson.getInt("item_wt");
|
deed.item_wt = deedJson.getInt("item_wt");
|
||||||
|
|||||||
-34
@@ -9,16 +9,10 @@
|
|||||||
package engine.parsers.cache;
|
package engine.parsers.cache;
|
||||||
|
|
||||||
import engine.gameManager.ConfigManager;
|
import engine.gameManager.ConfigManager;
|
||||||
import engine.gameManager.DbManager;
|
|
||||||
import engine.mbEnums;
|
|
||||||
import engine.objects.AbstractGameObject;
|
|
||||||
import engine.objects.BaseClass;
|
|
||||||
import engine.parsers.objects.RuneTemplate;
|
|
||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
// Dev-only check that compares DB-built objects with the cache JSON before a loader is switched.
|
// Dev-only check that compares DB-built objects with the cache JSON before a loader is switched.
|
||||||
@@ -34,10 +28,6 @@ public class ParityCheck {
|
|||||||
private int differenceCount = 0;
|
private int differenceCount = 0;
|
||||||
private int missingCount = 0;
|
private int missingCount = 0;
|
||||||
|
|
||||||
static {
|
|
||||||
register("static_rune_baseclass", ParityCheck::compareBaseClasses);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ParityCheck(String table) {
|
private ParityCheck(String table) {
|
||||||
this.table = table;
|
this.table = table;
|
||||||
}
|
}
|
||||||
@@ -91,28 +81,4 @@ public class ParityCheck {
|
|||||||
differenceCount++;
|
differenceCount++;
|
||||||
Logger.warn("Parity: " + table + "/" + id + "/" + field + ": db=" + dbValue + " json=" + jsonValue);
|
Logger.warn("Parity: " + table + "/" + id + "/" + field + ": db=" + dbValue + " json=" + jsonValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void compareBaseClasses(ParityCheck check) {
|
|
||||||
|
|
||||||
ConcurrentHashMap<Integer, AbstractGameObject> cache;
|
|
||||||
BaseClass baseClass;
|
|
||||||
RuneTemplate rune;
|
|
||||||
|
|
||||||
cache = DbManager.getMap(mbEnums.GameObjectType.BaseClass);
|
|
||||||
|
|
||||||
if (cache == null) {
|
|
||||||
Logger.warn("Parity: static_rune_baseclass: no BaseClass objects loaded");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (AbstractGameObject cached : cache.values()) {
|
|
||||||
baseClass = (BaseClass) cached;
|
|
||||||
rune = RuneTemplate._runes.get(baseClass.getObjectUUID());
|
|
||||||
|
|
||||||
if (!check.compareRow(baseClass.getObjectUUID(), rune))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
check.compareField(baseClass.getObjectUUID(), "name", baseClass.getName(), rune.obj_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+6
@@ -112,8 +112,14 @@ public class RuneParser {
|
|||||||
rune.item_type = CacheParserUtil.readEnum(mbEnums.ItemType.class, runeJson.getString("item_type"), templateId, "item_type");
|
rune.item_type = CacheParserUtil.readEnum(mbEnums.ItemType.class, runeJson.getString("item_type"), templateId, "item_type");
|
||||||
rune.item_eq_slots_value = runeJson.getInt("item_eq_slots_value");
|
rune.item_eq_slots_value = runeJson.getInt("item_eq_slots_value");
|
||||||
rune.item_eq_slots_type = runeJson.getBoolean("item_eq_slots_type");
|
rune.item_eq_slots_type = runeJson.getBoolean("item_eq_slots_type");
|
||||||
|
|
||||||
|
// The exporter writes ["NONE"] for an empty slot mask
|
||||||
|
|
||||||
rune.item_eq_slots_or.addAll(CacheParserUtil.readEnumSet(mbEnums.EquipSlotType.class, runeJson.getJSONArray("item_eq_slots_or"), templateId, "item_eq_slots_or"));
|
rune.item_eq_slots_or.addAll(CacheParserUtil.readEnumSet(mbEnums.EquipSlotType.class, runeJson.getJSONArray("item_eq_slots_or"), templateId, "item_eq_slots_or"));
|
||||||
|
rune.item_eq_slots_or.remove(mbEnums.EquipSlotType.NONE);
|
||||||
rune.item_eq_slots_and.addAll(CacheParserUtil.readEnumSet(mbEnums.EquipSlotType.class, runeJson.getJSONArray("item_eq_slots_and"), templateId, "item_eq_slots_and"));
|
rune.item_eq_slots_and.addAll(CacheParserUtil.readEnumSet(mbEnums.EquipSlotType.class, runeJson.getJSONArray("item_eq_slots_and"), templateId, "item_eq_slots_and"));
|
||||||
|
rune.item_eq_slots_and.remove(mbEnums.EquipSlotType.NONE);
|
||||||
|
|
||||||
rune.item_takeable = runeJson.getBoolean("item_takeable");
|
rune.item_takeable = runeJson.getBoolean("item_takeable");
|
||||||
rune.item_value = runeJson.getInt("item_value");
|
rune.item_value = runeJson.getInt("item_value");
|
||||||
rune.item_wt = runeJson.getInt("item_wt");
|
rune.item_wt = runeJson.getInt("item_wt");
|
||||||
|
|||||||
@@ -8,8 +8,92 @@
|
|||||||
|
|
||||||
package engine.parsers.objects;
|
package engine.parsers.objects;
|
||||||
|
|
||||||
|
import engine.math.Vector3fImmutable;
|
||||||
|
import engine.mbEnums;
|
||||||
|
import engine.parsers.cache.CObjectIndex;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
// Common type for ITEM, DEED and RUNE cache templates, which share one id space.
|
// Common type for ITEM, DEED and RUNE cache templates, which share one id space.
|
||||||
// Shared obj_/combat_/item_ getters arrive with JSON-Refactor-Plan Task 1.1.
|
// Getters cover only the obj_/combat_/item_ fields all three define (JSON-Refactor-Plan D1).
|
||||||
|
// Returned collections are the template's own; never modify them.
|
||||||
|
|
||||||
public interface CObjectTemplate {
|
public interface CObjectTemplate {
|
||||||
|
|
||||||
|
static CObjectTemplate lookup(int templateId) {
|
||||||
|
return CObjectIndex.lookup(templateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getTemplateId();
|
||||||
|
String getObjName();
|
||||||
|
boolean getObjPickable();
|
||||||
|
float getObjGravity();
|
||||||
|
float getObjCullDistance();
|
||||||
|
Vector3fImmutable getObjScale();
|
||||||
|
int getObjRenderObject();
|
||||||
|
boolean getObjDoubleFusion();
|
||||||
|
Vector3fImmutable getObjForwardVector();
|
||||||
|
String getObjTrackingName();
|
||||||
|
float getObjMaxTrackingDistance();
|
||||||
|
int getObjIcon();
|
||||||
|
float getObjGravityF();
|
||||||
|
LinkedHashMap<String, Integer> getObjSoundEvents();
|
||||||
|
JSONArray getObjArcHardpointList();
|
||||||
|
HashMap<String, String> getObjSparseData();
|
||||||
|
int getObjRenderObjectLowDetail();
|
||||||
|
Vector3fImmutable getObjDefaultAlignment();
|
||||||
|
String getObjSoundTable();
|
||||||
|
|
||||||
|
float getCombatHealthCurrent();
|
||||||
|
float getCombatHealthFull();
|
||||||
|
EnumMap<mbEnums.DamageType, Float> getCombatAttackResist();
|
||||||
|
JSONArray getCombatPowers();
|
||||||
|
|
||||||
|
mbEnums.ItemType getItemType();
|
||||||
|
int getItemEqSlotsValue();
|
||||||
|
boolean getItemEqSlotsType();
|
||||||
|
EnumSet<mbEnums.EquipSlotType> getItemEqSlotsOr();
|
||||||
|
EnumSet<mbEnums.EquipSlotType> getItemEqSlotsAnd();
|
||||||
|
boolean getItemTakeable();
|
||||||
|
int getItemValue();
|
||||||
|
int getItemWt();
|
||||||
|
float getItemPassiveDefenseMod();
|
||||||
|
String getItemBaseName();
|
||||||
|
String getItemDsc();
|
||||||
|
int getItemRenderObjectFemale();
|
||||||
|
float getItemHealthFull();
|
||||||
|
String getItemSkillUsed();
|
||||||
|
String getItemSkillMasteryUsed();
|
||||||
|
int getItemParryAnimId();
|
||||||
|
EnumMap<mbEnums.ShrineType, Integer> getItemOfferingInfo();
|
||||||
|
EnumSet<mbEnums.ItemFlags> getItemFlags();
|
||||||
|
EnumSet<mbEnums.ItemUseFlags> getItemUseFlags();
|
||||||
|
int getItemPostItemId();
|
||||||
|
int getItemInitialCharges();
|
||||||
|
int getItemBookArcana();
|
||||||
|
LinkedHashMap<String, Integer> getItemSkillReq();
|
||||||
|
boolean getItemRaceReqRestrict();
|
||||||
|
EnumSet<mbEnums.MonsterType> getItemRaceReq();
|
||||||
|
boolean getItemClassReqRestrict();
|
||||||
|
EnumSet<mbEnums.ClassType> getItemClassReq();
|
||||||
|
boolean getItemDiscReqRestrict();
|
||||||
|
EnumSet<mbEnums.DisciplineType> getItemDiscReq();
|
||||||
|
EnumMap<mbEnums.AttributeType, Integer> getItemAttrReq();
|
||||||
|
int getItemLevelReq();
|
||||||
|
int getItemRankReq();
|
||||||
|
mbEnums.SexType getItemSexReq();
|
||||||
|
ArrayList<UserPowerAction> getItemUserPowerAction();
|
||||||
|
ArrayList<PowerGrant> getItemPowerGrant();
|
||||||
|
LinkedHashMap<String, ArrayList<int[]>> getItemPowerAction();
|
||||||
|
boolean getItemSheathable();
|
||||||
|
boolean getItemHasStub();
|
||||||
|
EnumMap<mbEnums.ShrineType, Integer> getItemOfferingAdjustments();
|
||||||
|
EnumMap<mbEnums.ResourceType, Integer> getItemResourceCosts();
|
||||||
|
int getItemBaneRank();
|
||||||
|
boolean getItemIgnoreSavedActions();
|
||||||
}
|
}
|
||||||
@@ -119,4 +119,329 @@ public class DeedTemplate implements CObjectTemplate {
|
|||||||
public float deed_namelookup_val;
|
public float deed_namelookup_val;
|
||||||
public boolean deed_custom_city;
|
public boolean deed_custom_city;
|
||||||
public int deed_structure_id;
|
public int deed_structure_id;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTemplateId() {
|
||||||
|
return template_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjName() {
|
||||||
|
return obj_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getObjPickable() {
|
||||||
|
return obj_pickable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getObjGravity() {
|
||||||
|
return obj_gravity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getObjCullDistance() {
|
||||||
|
return obj_cull_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3fImmutable getObjScale() {
|
||||||
|
return obj_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getObjRenderObject() {
|
||||||
|
return obj_render_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getObjDoubleFusion() {
|
||||||
|
return obj_double_fusion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3fImmutable getObjForwardVector() {
|
||||||
|
return obj_forward_vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjTrackingName() {
|
||||||
|
return obj_tracking_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getObjMaxTrackingDistance() {
|
||||||
|
return obj_max_tracking_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getObjIcon() {
|
||||||
|
return obj_icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getObjGravityF() {
|
||||||
|
return obj_gravity_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedHashMap<String, Integer> getObjSoundEvents() {
|
||||||
|
return obj_sound_events;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONArray getObjArcHardpointList() {
|
||||||
|
return obj_arc_hardpoint_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HashMap<String, String> getObjSparseData() {
|
||||||
|
return obj_sparse_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getObjRenderObjectLowDetail() {
|
||||||
|
return obj_render_object_low_detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3fImmutable getObjDefaultAlignment() {
|
||||||
|
return obj_default_alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjSoundTable() {
|
||||||
|
return obj_sound_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCombatHealthCurrent() {
|
||||||
|
return combat_health_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCombatHealthFull() {
|
||||||
|
return combat_health_full;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.DamageType, Float> getCombatAttackResist() {
|
||||||
|
return combat_attack_resist;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONArray getCombatPowers() {
|
||||||
|
return combat_powers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public mbEnums.ItemType getItemType() {
|
||||||
|
return item_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemEqSlotsValue() {
|
||||||
|
return item_eq_slots_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemEqSlotsType() {
|
||||||
|
return item_eq_slots_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.EquipSlotType> getItemEqSlotsOr() {
|
||||||
|
return item_eq_slots_or;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.EquipSlotType> getItemEqSlotsAnd() {
|
||||||
|
return item_eq_slots_and;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemTakeable() {
|
||||||
|
return item_takeable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemValue() {
|
||||||
|
return item_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemWt() {
|
||||||
|
return item_wt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getItemPassiveDefenseMod() {
|
||||||
|
return item_passive_defense_mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemBaseName() {
|
||||||
|
return item_base_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemDsc() {
|
||||||
|
return item_dsc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemRenderObjectFemale() {
|
||||||
|
return item_render_object_female;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getItemHealthFull() {
|
||||||
|
return item_health_full;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemSkillUsed() {
|
||||||
|
return item_skill_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemSkillMasteryUsed() {
|
||||||
|
return item_skill_mastery_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemParryAnimId() {
|
||||||
|
return item_parry_anim_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.ShrineType, Integer> getItemOfferingInfo() {
|
||||||
|
return item_offering_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.ItemFlags> getItemFlags() {
|
||||||
|
return item_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.ItemUseFlags> getItemUseFlags() {
|
||||||
|
return item_use_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemPostItemId() {
|
||||||
|
return item_post_item_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemInitialCharges() {
|
||||||
|
return item_initial_charges;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemBookArcana() {
|
||||||
|
return item_book_arcana;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedHashMap<String, Integer> getItemSkillReq() {
|
||||||
|
return item_skill_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemRaceReqRestrict() {
|
||||||
|
return item_race_req_restrict;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.MonsterType> getItemRaceReq() {
|
||||||
|
return item_race_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemClassReqRestrict() {
|
||||||
|
return item_class_req_restrict;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.ClassType> getItemClassReq() {
|
||||||
|
return item_class_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemDiscReqRestrict() {
|
||||||
|
return item_disc_req_restrict;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.DisciplineType> getItemDiscReq() {
|
||||||
|
return item_disc_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.AttributeType, Integer> getItemAttrReq() {
|
||||||
|
return item_attr_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemLevelReq() {
|
||||||
|
return item_level_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemRankReq() {
|
||||||
|
return item_rank_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public mbEnums.SexType getItemSexReq() {
|
||||||
|
return item_sex_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayList<UserPowerAction> getItemUserPowerAction() {
|
||||||
|
return item_user_power_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayList<PowerGrant> getItemPowerGrant() {
|
||||||
|
return item_power_grant;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedHashMap<String, ArrayList<int[]>> getItemPowerAction() {
|
||||||
|
return item_power_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemSheathable() {
|
||||||
|
return item_sheathable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemHasStub() {
|
||||||
|
return item_has_stub;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.ShrineType, Integer> getItemOfferingAdjustments() {
|
||||||
|
return item_offering_adjustments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.ResourceType, Integer> getItemResourceCosts() {
|
||||||
|
return item_resource_costs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemBaneRank() {
|
||||||
|
return item_bane_rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemIgnoreSavedActions() {
|
||||||
|
return item_ignore_saved_actions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -25,14 +25,15 @@ import java.util.LinkedHashMap;
|
|||||||
// Values are kept as the client defines them: no req/res splitting,
|
// Values are kept as the client defines them: no req/res splitting,
|
||||||
// no defaults substituted. Strings with a matching enum in mbEnums
|
// no defaults substituted. Strings with a matching enum in mbEnums
|
||||||
// are stored as that enum; everything else stays a String.
|
// are stored as that enum; everything else stays a String.
|
||||||
//
|
// Read only once loaded.
|
||||||
// Not to be confused with engine.objects.ItemTemplate, which is loaded
|
|
||||||
// from the database. Read only once loaded.
|
|
||||||
|
|
||||||
public class ItemTemplate implements CObjectTemplate {
|
public class ItemTemplate implements CObjectTemplate {
|
||||||
|
|
||||||
public static HashMap<Integer, ItemTemplate> _items = new HashMap<>();
|
public static HashMap<Integer, ItemTemplate> _items = new HashMap<>();
|
||||||
|
|
||||||
|
// Legacy templates zero-filled the weapon block on non-weapons; held shields and the like rely on it.
|
||||||
|
private static final Weapon NO_WEAPON = new Weapon();
|
||||||
|
|
||||||
public int template_id;
|
public int template_id;
|
||||||
|
|
||||||
// obj_
|
// obj_
|
||||||
@@ -138,6 +139,341 @@ public class ItemTemplate implements CObjectTemplate {
|
|||||||
public int item_bane_rank;
|
public int item_bane_rank;
|
||||||
public boolean item_ignore_saved_actions;
|
public boolean item_ignore_saved_actions;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTemplateId() {
|
||||||
|
return template_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjName() {
|
||||||
|
return obj_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getObjPickable() {
|
||||||
|
return obj_pickable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getObjGravity() {
|
||||||
|
return obj_gravity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getObjCullDistance() {
|
||||||
|
return obj_cull_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3fImmutable getObjScale() {
|
||||||
|
return obj_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getObjRenderObject() {
|
||||||
|
return obj_render_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getObjDoubleFusion() {
|
||||||
|
return obj_double_fusion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3fImmutable getObjForwardVector() {
|
||||||
|
return obj_forward_vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjTrackingName() {
|
||||||
|
return obj_tracking_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getObjMaxTrackingDistance() {
|
||||||
|
return obj_max_tracking_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getObjIcon() {
|
||||||
|
return obj_icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getObjGravityF() {
|
||||||
|
return obj_gravity_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedHashMap<String, Integer> getObjSoundEvents() {
|
||||||
|
return obj_sound_events;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONArray getObjArcHardpointList() {
|
||||||
|
return obj_arc_hardpoint_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HashMap<String, String> getObjSparseData() {
|
||||||
|
return obj_sparse_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getObjRenderObjectLowDetail() {
|
||||||
|
return obj_render_object_low_detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3fImmutable getObjDefaultAlignment() {
|
||||||
|
return obj_default_alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjSoundTable() {
|
||||||
|
return obj_sound_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCombatHealthCurrent() {
|
||||||
|
return combat_health_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCombatHealthFull() {
|
||||||
|
return combat_health_full;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.DamageType, Float> getCombatAttackResist() {
|
||||||
|
return combat_attack_resist;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONArray getCombatPowers() {
|
||||||
|
return combat_powers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public mbEnums.ItemType getItemType() {
|
||||||
|
return item_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemEqSlotsValue() {
|
||||||
|
return item_eq_slots_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemEqSlotsType() {
|
||||||
|
return item_eq_slots_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.EquipSlotType> getItemEqSlotsOr() {
|
||||||
|
return item_eq_slots_or;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.EquipSlotType> getItemEqSlotsAnd() {
|
||||||
|
return item_eq_slots_and;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemTakeable() {
|
||||||
|
return item_takeable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemValue() {
|
||||||
|
return item_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemWt() {
|
||||||
|
return item_wt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getItemPassiveDefenseMod() {
|
||||||
|
return item_passive_defense_mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemBaseName() {
|
||||||
|
return item_base_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemDsc() {
|
||||||
|
return item_dsc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemRenderObjectFemale() {
|
||||||
|
return item_render_object_female;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getItemHealthFull() {
|
||||||
|
return item_health_full;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemSkillUsed() {
|
||||||
|
return item_skill_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemSkillMasteryUsed() {
|
||||||
|
return item_skill_mastery_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemParryAnimId() {
|
||||||
|
return item_parry_anim_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.ShrineType, Integer> getItemOfferingInfo() {
|
||||||
|
return item_offering_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.ItemFlags> getItemFlags() {
|
||||||
|
return item_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.ItemUseFlags> getItemUseFlags() {
|
||||||
|
return item_use_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemPostItemId() {
|
||||||
|
return item_post_item_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemInitialCharges() {
|
||||||
|
return item_initial_charges;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemBookArcana() {
|
||||||
|
return item_book_arcana;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedHashMap<String, Integer> getItemSkillReq() {
|
||||||
|
return item_skill_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemRaceReqRestrict() {
|
||||||
|
return item_race_req_restrict;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.MonsterType> getItemRaceReq() {
|
||||||
|
return item_race_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemClassReqRestrict() {
|
||||||
|
return item_class_req_restrict;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.ClassType> getItemClassReq() {
|
||||||
|
return item_class_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemDiscReqRestrict() {
|
||||||
|
return item_disc_req_restrict;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.DisciplineType> getItemDiscReq() {
|
||||||
|
return item_disc_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.AttributeType, Integer> getItemAttrReq() {
|
||||||
|
return item_attr_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemLevelReq() {
|
||||||
|
return item_level_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemRankReq() {
|
||||||
|
return item_rank_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public mbEnums.SexType getItemSexReq() {
|
||||||
|
return item_sex_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayList<UserPowerAction> getItemUserPowerAction() {
|
||||||
|
return item_user_power_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayList<PowerGrant> getItemPowerGrant() {
|
||||||
|
return item_power_grant;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedHashMap<String, ArrayList<int[]>> getItemPowerAction() {
|
||||||
|
return item_power_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemSheathable() {
|
||||||
|
return item_sheathable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemHasStub() {
|
||||||
|
return item_has_stub;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.ShrineType, Integer> getItemOfferingAdjustments() {
|
||||||
|
return item_offering_adjustments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.ResourceType, Integer> getItemResourceCosts() {
|
||||||
|
return item_resource_costs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemBaneRank() {
|
||||||
|
return item_bane_rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemIgnoreSavedActions() {
|
||||||
|
return item_ignore_saved_actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Weapon getWeapon(int templateID) {
|
||||||
|
|
||||||
|
ItemTemplate template = _items.get(templateID);
|
||||||
|
|
||||||
|
if (template == null || template.item_weapon == null)
|
||||||
|
return NO_WEAPON;
|
||||||
|
|
||||||
|
return template.item_weapon;
|
||||||
|
}
|
||||||
|
|
||||||
// item_weapon (ArcAttackInfo_LoadWeapon, sb.exe 0x61FA60).
|
// item_weapon (ArcAttackInfo_LoadWeapon, sb.exe 0x61FA60).
|
||||||
|
|
||||||
public static class Weapon {
|
public static class Weapon {
|
||||||
@@ -149,7 +485,7 @@ public class ItemTemplate implements CObjectTemplate {
|
|||||||
public int weapon_combat_idle_anim;
|
public int weapon_combat_idle_anim;
|
||||||
public final ArrayList<Damage> weapon_damage = new ArrayList<>();
|
public final ArrayList<Damage> weapon_damage = new ArrayList<>();
|
||||||
|
|
||||||
// [animation, duration] pairs in file order; names from engine.objects.ItemTemplate, not the client.
|
// [animation, duration] pairs in file order; names from the old static_item_templates export, not the client.
|
||||||
public final ArrayList<int[]> weapon_attack_anim_right = new ArrayList<>();
|
public final ArrayList<int[]> weapon_attack_anim_right = new ArrayList<>();
|
||||||
public final ArrayList<int[]> weapon_attack_anim_left = new ArrayList<>();
|
public final ArrayList<int[]> weapon_attack_anim_left = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ public class RuneTemplate implements CObjectTemplate {
|
|||||||
public String rune_dsc;
|
public String rune_dsc;
|
||||||
public String rune_fx_txt;
|
public String rune_fx_txt;
|
||||||
|
|
||||||
// Bit vectors. The existing ItemTemplate decodes these as MobBehaviourType.
|
// Bit vectors. The old static_item_templates export decoded these as MobBehaviourType.
|
||||||
|
|
||||||
public long rune_group_tactics;
|
public long rune_group_tactics;
|
||||||
public long rune_group_role_set;
|
public long rune_group_role_set;
|
||||||
@@ -191,6 +191,331 @@ public class RuneTemplate implements CObjectTemplate {
|
|||||||
public int rune_natural_power_attack;
|
public int rune_natural_power_attack;
|
||||||
public final HashMap<String, String> rune_sparse_data = new HashMap<>();
|
public final HashMap<String, String> rune_sparse_data = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTemplateId() {
|
||||||
|
return template_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjName() {
|
||||||
|
return obj_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getObjPickable() {
|
||||||
|
return obj_pickable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getObjGravity() {
|
||||||
|
return obj_gravity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getObjCullDistance() {
|
||||||
|
return obj_cull_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3fImmutable getObjScale() {
|
||||||
|
return obj_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getObjRenderObject() {
|
||||||
|
return obj_render_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getObjDoubleFusion() {
|
||||||
|
return obj_double_fusion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3fImmutable getObjForwardVector() {
|
||||||
|
return obj_forward_vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjTrackingName() {
|
||||||
|
return obj_tracking_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getObjMaxTrackingDistance() {
|
||||||
|
return obj_max_tracking_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getObjIcon() {
|
||||||
|
return obj_icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getObjGravityF() {
|
||||||
|
return obj_gravity_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedHashMap<String, Integer> getObjSoundEvents() {
|
||||||
|
return obj_sound_events;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONArray getObjArcHardpointList() {
|
||||||
|
return obj_arc_hardpoint_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HashMap<String, String> getObjSparseData() {
|
||||||
|
return obj_sparse_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getObjRenderObjectLowDetail() {
|
||||||
|
return obj_render_object_low_detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3fImmutable getObjDefaultAlignment() {
|
||||||
|
return obj_default_alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjSoundTable() {
|
||||||
|
return obj_sound_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCombatHealthCurrent() {
|
||||||
|
return combat_health_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCombatHealthFull() {
|
||||||
|
return combat_health_full;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.DamageType, Float> getCombatAttackResist() {
|
||||||
|
return combat_attack_resist;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONArray getCombatPowers() {
|
||||||
|
return combat_powers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public mbEnums.ItemType getItemType() {
|
||||||
|
return item_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemEqSlotsValue() {
|
||||||
|
return item_eq_slots_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemEqSlotsType() {
|
||||||
|
return item_eq_slots_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.EquipSlotType> getItemEqSlotsOr() {
|
||||||
|
return item_eq_slots_or;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.EquipSlotType> getItemEqSlotsAnd() {
|
||||||
|
return item_eq_slots_and;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemTakeable() {
|
||||||
|
return item_takeable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemValue() {
|
||||||
|
return item_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemWt() {
|
||||||
|
return item_wt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getItemPassiveDefenseMod() {
|
||||||
|
return item_passive_defense_mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemBaseName() {
|
||||||
|
return item_base_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemDsc() {
|
||||||
|
return item_dsc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemRenderObjectFemale() {
|
||||||
|
return item_render_object_female;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getItemHealthFull() {
|
||||||
|
return item_health_full;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemSkillUsed() {
|
||||||
|
return item_skill_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemSkillMasteryUsed() {
|
||||||
|
return item_skill_mastery_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemParryAnimId() {
|
||||||
|
return item_parry_anim_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.ShrineType, Integer> getItemOfferingInfo() {
|
||||||
|
return item_offering_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.ItemFlags> getItemFlags() {
|
||||||
|
return item_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.ItemUseFlags> getItemUseFlags() {
|
||||||
|
return item_use_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemPostItemId() {
|
||||||
|
return item_post_item_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemInitialCharges() {
|
||||||
|
return item_initial_charges;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemBookArcana() {
|
||||||
|
return item_book_arcana;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedHashMap<String, Integer> getItemSkillReq() {
|
||||||
|
return item_skill_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemRaceReqRestrict() {
|
||||||
|
return item_race_req_restrict;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.MonsterType> getItemRaceReq() {
|
||||||
|
return item_race_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemClassReqRestrict() {
|
||||||
|
return item_class_req_restrict;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.ClassType> getItemClassReq() {
|
||||||
|
return item_class_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemDiscReqRestrict() {
|
||||||
|
return item_disc_req_restrict;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<mbEnums.DisciplineType> getItemDiscReq() {
|
||||||
|
return item_disc_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.AttributeType, Integer> getItemAttrReq() {
|
||||||
|
return item_attr_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemLevelReq() {
|
||||||
|
return item_level_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemRankReq() {
|
||||||
|
return item_rank_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public mbEnums.SexType getItemSexReq() {
|
||||||
|
return item_sex_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayList<UserPowerAction> getItemUserPowerAction() {
|
||||||
|
return item_user_power_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayList<PowerGrant> getItemPowerGrant() {
|
||||||
|
return item_power_grant;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedHashMap<String, ArrayList<int[]>> getItemPowerAction() {
|
||||||
|
return item_power_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemSheathable() {
|
||||||
|
return item_sheathable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemHasStub() {
|
||||||
|
return item_has_stub;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.ShrineType, Integer> getItemOfferingAdjustments() {
|
||||||
|
return item_offering_adjustments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumMap<mbEnums.ResourceType, Integer> getItemResourceCosts() {
|
||||||
|
return item_resource_costs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemBaneRank() {
|
||||||
|
return item_bane_rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getItemIgnoreSavedActions() {
|
||||||
|
return item_ignore_saved_actions;
|
||||||
|
}
|
||||||
|
|
||||||
// One entry of rune_skill_grant; same layout as PowerGrant.
|
// One entry of rune_skill_grant; same layout as PowerGrant.
|
||||||
// skill_monster_types is empty in every RUNE file, so it is kept as raw JSON.
|
// skill_monster_types is empty in every RUNE file, so it is kept as raw JSON.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.objects.wpak;
|
||||||
|
|
||||||
|
import engine.mbEnums;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
// CharCreateRuneList.cfg: the rune ids the client offers at character creation,
|
||||||
|
// in file order. Race runes carry the sex they are offered to (NONE = both).
|
||||||
|
|
||||||
|
public class CharCreateRuneList {
|
||||||
|
|
||||||
|
public static CharCreateRuneList _runeList;
|
||||||
|
|
||||||
|
public final LinkedHashMap<Integer, mbEnums.SexType> race_runes = new LinkedHashMap<>();
|
||||||
|
public final ArrayList<Integer> class_runes = new ArrayList<>();
|
||||||
|
public final ArrayList<Integer> promotion_runes = new ArrayList<>();
|
||||||
|
public final ArrayList<Integer> attr_runes = new ArrayList<>();
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.objects.wpak;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
// One row of CompoundCurves.cfg: <name> then segments of <DownperRange> <SimpleCurveName> <params>.
|
||||||
|
// Most curves are one SlopedLine segment; DefaultCurveUp/Down have two, which the
|
||||||
|
// CompoundCurveType enum (one value per curve) can't hold.
|
||||||
|
|
||||||
|
public class CompoundCurveTemplate {
|
||||||
|
|
||||||
|
public static HashMap<String, CompoundCurveTemplate> _curves = new HashMap<>();
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
public final ArrayList<Segment> segments = new ArrayList<>();
|
||||||
|
|
||||||
|
public static class Segment {
|
||||||
|
|
||||||
|
public int down_per_range;
|
||||||
|
public String simple_curve;
|
||||||
|
public float[] params;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.objects.wpak;
|
||||||
|
|
||||||
|
import engine.mbEnums;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
// One EFFECTBEGIN block of Effects.cfg (client ArcEffect_ParseBlock 0x555540).
|
||||||
|
// Header: <effect_id> <effect_name> <icon>. Keys are flags; SOURCE, MODS and
|
||||||
|
// CONDITION are nested blocks, kept in file order.
|
||||||
|
//
|
||||||
|
// Read only once loaded.
|
||||||
|
|
||||||
|
public class EffectTemplate {
|
||||||
|
|
||||||
|
public static HashMap<String, EffectTemplate> _effects = new HashMap<>();
|
||||||
|
|
||||||
|
public String effect_id;
|
||||||
|
public String effect_name;
|
||||||
|
public int icon;
|
||||||
|
|
||||||
|
public boolean isitemeffect;
|
||||||
|
public boolean dontsave;
|
||||||
|
public boolean ignorenomod;
|
||||||
|
public boolean isspireeffect;
|
||||||
|
|
||||||
|
public final ArrayList<String> sources = new ArrayList<>();
|
||||||
|
public final ArrayList<ModEntry> mods = new ArrayList<>();
|
||||||
|
public final ArrayList<ConditionEntry> conditions = new ArrayList<>();
|
||||||
|
|
||||||
|
// One MODS line. Which fields are set depends on the mod type's behavior in ModTypes.cfg;
|
||||||
|
// the layouts are from the client's ArcMod*_Parse functions. args keeps the line as written.
|
||||||
|
|
||||||
|
public static class ModEntry {
|
||||||
|
|
||||||
|
public mbEnums.ModType mod_type;
|
||||||
|
public String behavior;
|
||||||
|
public final ArrayList<String> args = new ArrayList<>();
|
||||||
|
|
||||||
|
public float min_mod;
|
||||||
|
public float max_mod;
|
||||||
|
|
||||||
|
// Standard and FPSubType*: the client reads this with String::ToInt, so 16.8 acts as 16 (0x55A6C0)
|
||||||
|
public float percent_mod;
|
||||||
|
public String curve;
|
||||||
|
|
||||||
|
// The behavior's subtype: attribute, skill, damage type, source type, power type, mod type or monster type
|
||||||
|
public String type;
|
||||||
|
|
||||||
|
// SubTypeSourceType/SubTypePowerType display text, or the two ItemName strings
|
||||||
|
public String string1;
|
||||||
|
public String string2;
|
||||||
|
|
||||||
|
public String proc_power_id;
|
||||||
|
public int map_key;
|
||||||
|
public final ArrayList<Integer> map_values = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// One CONDITION line: <condition> <amount> [curve] [damage type ...] (0x588320)
|
||||||
|
|
||||||
|
public static class ConditionEntry {
|
||||||
|
|
||||||
|
public mbEnums.PowerFailCondition condition;
|
||||||
|
public float amount;
|
||||||
|
public String curve;
|
||||||
|
public final ArrayList<mbEnums.DamageType> damage_types = new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.objects.wpak;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
// One row of ModTypes.cfg: <Type> <Behavior> <DisplayCategory> <DisplayString>.
|
||||||
|
// Behavior names the client ArcMod class that parses the mod's arguments in Effects.cfg.
|
||||||
|
// Types are kept as strings: the cfg has types the ModType enum doesn't (AttrReq, BulkFactor, ...).
|
||||||
|
|
||||||
|
public class ModTypeTemplate {
|
||||||
|
|
||||||
|
public static HashMap<String, ModTypeTemplate> _modTypes = new HashMap<>();
|
||||||
|
|
||||||
|
public String type;
|
||||||
|
public String behavior;
|
||||||
|
public String display_category;
|
||||||
|
public String display_string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.objects.wpak;
|
||||||
|
|
||||||
|
import engine.mbEnums;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
// One line of PowActionCostInfo.cfg: <id> ("<resource>" <amount>)*.
|
||||||
|
// The resource cost of a prefix/suffix (client EffectCostMap 0x6E00C0); the source of
|
||||||
|
// the server's static_effect_costmaps.
|
||||||
|
|
||||||
|
public class PowActionCostTemplate {
|
||||||
|
|
||||||
|
public static HashMap<String, PowActionCostTemplate> _costs = new HashMap<>();
|
||||||
|
|
||||||
|
public String id;
|
||||||
|
public final LinkedHashMap<mbEnums.ResourceType, Integer> costs = new LinkedHashMap<>();
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.objects.wpak;
|
||||||
|
|
||||||
|
import engine.mbEnums;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
// One POWERACTIONBEGIN block of PowerActions.cfg.
|
||||||
|
//
|
||||||
|
// Header: <action_id> <action_type> <type-specific args>. The per-type layouts
|
||||||
|
// come from the client's ArcPowerAction*_ParseHeader functions. header_args keeps
|
||||||
|
// every arg as written, including ones the client reads but nothing names yet.
|
||||||
|
// KEY= lines map to the lower-case fields named after them.
|
||||||
|
//
|
||||||
|
// Read only once loaded.
|
||||||
|
|
||||||
|
public class PowerActionTemplate {
|
||||||
|
|
||||||
|
public static HashMap<String, PowerActionTemplate> _powerActions = new HashMap<>();
|
||||||
|
|
||||||
|
public String action_id;
|
||||||
|
public mbEnums.PowerActionType action_type;
|
||||||
|
public final ArrayList<String> header_args = new ArrayList<>();
|
||||||
|
|
||||||
|
// Header
|
||||||
|
|
||||||
|
// ApplyEffect, ApplyEffects, Block, Charm, DamageOverTime, DeferredPower,
|
||||||
|
// DirectDamage, Invis, SpireDisable, Track, Transform, TransferStatOT
|
||||||
|
public final ArrayList<String> effect_ids = new ArrayList<>();
|
||||||
|
|
||||||
|
public String deferred_power_id;
|
||||||
|
public int num_iterations;
|
||||||
|
public int mob_id;
|
||||||
|
public int mob_level;
|
||||||
|
public String effect_source_to_remove;
|
||||||
|
public mbEnums.ItemFlags item_flag;
|
||||||
|
public boolean item_flag_value;
|
||||||
|
public String track_filter;
|
||||||
|
public int max_track;
|
||||||
|
|
||||||
|
public mbEnums.CostType transfer_from_type;
|
||||||
|
public mbEnums.CostType transfer_to_type;
|
||||||
|
|
||||||
|
// The client reads both with String::ToInt, so 31.5 acts as 31 (0x56ADF0)
|
||||||
|
public float transfer_amount;
|
||||||
|
public String transfer_amount_curve;
|
||||||
|
public float transfer_efficiency;
|
||||||
|
public String transfer_efficiency_curve;
|
||||||
|
|
||||||
|
// Keys, plus the header's trailing aggressive flag (both set the same client field)
|
||||||
|
|
||||||
|
public boolean isaggressive;
|
||||||
|
public boolean bladetrails;
|
||||||
|
public boolean isresistable;
|
||||||
|
public String applyeffectself;
|
||||||
|
public String applyeffectother;
|
||||||
|
public String wearoffeffectself;
|
||||||
|
public String wearoffeffectother;
|
||||||
|
public boolean applyeffectblank;
|
||||||
|
public boolean wearoffeffectblank;
|
||||||
|
public boolean is_available_for_formulae;
|
||||||
|
public boolean removeall;
|
||||||
|
public final ArrayList<Integer> bodyparts = new ArrayList<>();
|
||||||
|
public final ArrayList<Integer> femalebodyparts = new ArrayList<>();
|
||||||
|
public boolean shouldshowweapons;
|
||||||
|
public boolean shouldshowarmor;
|
||||||
|
public final ArrayList<Integer> attackanims = new ArrayList<>();
|
||||||
|
public float[] scalefactor;
|
||||||
|
public String effectid;
|
||||||
|
public int levelcap;
|
||||||
|
public String levelcap_curve;
|
||||||
|
public boolean clearaggro;
|
||||||
|
public boolean targetbecomespet;
|
||||||
|
public boolean destroyoldpet;
|
||||||
|
public String rootfsmid;
|
||||||
|
public mbEnums.DamageType damagetype;
|
||||||
|
public final ArrayList<Integer> splashdamage = new ArrayList<>();
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.objects.wpak;
|
||||||
|
|
||||||
|
import engine.mbEnums;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
// One POWERBEGIN block of Powers.cfg (client loader 0x56E410).
|
||||||
|
// Header field names follow the client's "<field> Error with line" messages.
|
||||||
|
// KEY= lines map to the lower-case fields named after them.
|
||||||
|
//
|
||||||
|
// Read only once loaded.
|
||||||
|
|
||||||
|
public class PowerTemplate {
|
||||||
|
|
||||||
|
public static HashMap<String, PowerTemplate> _powers = new HashMap<>();
|
||||||
|
|
||||||
|
// Header: 22 tokens
|
||||||
|
|
||||||
|
public String power_id;
|
||||||
|
public String power_name;
|
||||||
|
public mbEnums.PowerType power_type;
|
||||||
|
public int icon_number;
|
||||||
|
public String focus;
|
||||||
|
public mbEnums.PowerTargetType target_type;
|
||||||
|
public float range;
|
||||||
|
public mbEnums.AreaType area_type;
|
||||||
|
public float area_range;
|
||||||
|
public mbEnums.ExcludeType exclude_type;
|
||||||
|
public mbEnums.CostType cost_type;
|
||||||
|
public float cost_amt;
|
||||||
|
public int difficulty;
|
||||||
|
public int precision;
|
||||||
|
public float init_time;
|
||||||
|
public float release_time;
|
||||||
|
public float recycle_time;
|
||||||
|
public boolean hit_roll_yn;
|
||||||
|
public mbEnums.CastingModeType casting_mode;
|
||||||
|
public int init_anim;
|
||||||
|
public int release_anim;
|
||||||
|
public mbEnums.TargetSelectType target_sel;
|
||||||
|
|
||||||
|
// Keys
|
||||||
|
|
||||||
|
public final ArrayList<ActionEntry> actions = new ArrayList<>();
|
||||||
|
public int maxlevel;
|
||||||
|
public float hatevalue;
|
||||||
|
public String hatevalue_curve;
|
||||||
|
public String grantoverridevar;
|
||||||
|
public mbEnums.PowerCategoryType category;
|
||||||
|
public final ArrayList<EquipPrereq> eqprereqs = new ArrayList<>();
|
||||||
|
public final ArrayList<mbEnums.MonsterType> monstertypeprereqs = new ArrayList<>();
|
||||||
|
public final ArrayList<mbEnums.MonsterType> monstertyperestricts = new ArrayList<>();
|
||||||
|
public final ArrayList<EffectPrereq> targeteffectprereqs_anded = new ArrayList<>();
|
||||||
|
public final ArrayList<EffectPrereq> targeteffectprereqs_ored = new ArrayList<>();
|
||||||
|
public final ArrayList<EffectPrereq> effectprereqs = new ArrayList<>();
|
||||||
|
|
||||||
|
// CURVE= <COSTAMT|INITTIME|RECYCLETIME> <curve>: the curve applied to that header value
|
||||||
|
public final LinkedHashMap<String, String> curves = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
public final ArrayList<String> descriptions = new ArrayList<>();
|
||||||
|
public int loopanimid;
|
||||||
|
public boolean bladetrails;
|
||||||
|
public boolean cancastwhilemoving;
|
||||||
|
public boolean cancastwhileflying;
|
||||||
|
public boolean shouldcheckpath;
|
||||||
|
public boolean isadminpower;
|
||||||
|
public boolean cantargetadmin;
|
||||||
|
public boolean isprojectile;
|
||||||
|
public boolean sticky;
|
||||||
|
public int maxnummobtargets;
|
||||||
|
public int maxnumplayertargets;
|
||||||
|
public float pulseinfo_duration;
|
||||||
|
public int pulseinfo_iterations;
|
||||||
|
public final ArrayList<Integer> sounds = new ArrayList<>();
|
||||||
|
public int casterspulseparticle;
|
||||||
|
public final ArrayList<EffectTemplate.ConditionEntry> conditions = new ArrayList<>();
|
||||||
|
|
||||||
|
public String initstring;
|
||||||
|
public String successself;
|
||||||
|
public String successother;
|
||||||
|
public String fizzleself;
|
||||||
|
public String fizzleother;
|
||||||
|
public String applyeffectself;
|
||||||
|
public String applyeffectother;
|
||||||
|
public String wearoffeffectself;
|
||||||
|
public String wearoffeffectother;
|
||||||
|
public String applydamagecaster;
|
||||||
|
public String applydamagetarget;
|
||||||
|
public String applydamageother;
|
||||||
|
|
||||||
|
// ACTION= <action_id> <min_trains> <max_trains> <duration> <duration_curve> <stack_type>
|
||||||
|
// <stack_order> <stack_priority>, then up to four optional pairs kept only in args
|
||||||
|
|
||||||
|
public static class ActionEntry {
|
||||||
|
|
||||||
|
public String action_id;
|
||||||
|
public int min_trains;
|
||||||
|
public int max_trains;
|
||||||
|
public float duration;
|
||||||
|
public String duration_curve;
|
||||||
|
public String stack_type;
|
||||||
|
public int stack_order;
|
||||||
|
public mbEnums.CategoryToPowerType stack_priority;
|
||||||
|
public final ArrayList<String> args = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// EQPREREQ= repeats <slot> <skill> <required>
|
||||||
|
|
||||||
|
public static class EquipPrereq {
|
||||||
|
|
||||||
|
public mbEnums.EquipSlotType slot;
|
||||||
|
public String skill;
|
||||||
|
public boolean required;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EffectPrereq {
|
||||||
|
|
||||||
|
public String effect_id;
|
||||||
|
public int value;
|
||||||
|
public String message;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.objects.wpak;
|
||||||
|
|
||||||
|
import engine.mbEnums;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
// One line of Skills.cfg: "<uid>" "<name>" <icon> (<attribute> <weight>)* = "<description>".
|
||||||
|
// The cfg has no numeric ids; the server's skill ids 1-63 stay in static_skill_skillsbase.
|
||||||
|
|
||||||
|
public class SkillTemplate {
|
||||||
|
|
||||||
|
public static HashMap<String, SkillTemplate> _skills = new HashMap<>();
|
||||||
|
|
||||||
|
public String skill_uid;
|
||||||
|
public String skill_name;
|
||||||
|
public int icon_number;
|
||||||
|
public final LinkedHashMap<mbEnums.AttributeType, Integer> attr_weights = new LinkedHashMap<>();
|
||||||
|
public String description;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.objects.wpak;
|
||||||
|
|
||||||
|
import engine.mbEnums;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
// One kit of StartingKitTable.cfg: a kit line under RACE= <race> <sex> "<class>".
|
||||||
|
// The client reads a kit as a plain list of up to 10 item template ids; the tab
|
||||||
|
// columns in the file (Legs, Torso, ...) are not used (0x620250).
|
||||||
|
// kit_number counts the kits of one race/sex/class from 0.
|
||||||
|
|
||||||
|
public class StartingKitTemplate {
|
||||||
|
|
||||||
|
public static ArrayList<StartingKitTemplate> _kits = new ArrayList<>();
|
||||||
|
|
||||||
|
public String race;
|
||||||
|
public mbEnums.SexType sex;
|
||||||
|
public String base_class;
|
||||||
|
public int kit_number;
|
||||||
|
public final ArrayList<Integer> item_ids = new ArrayList<>();
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.wpak;
|
||||||
|
|
||||||
|
import engine.mbEnums;
|
||||||
|
import engine.parsers.objects.wpak.CharCreateRuneList;
|
||||||
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
// Loads CharCreateRuneList.cfg (client loaders at 0xBA4C20 and three siblings, one per section).
|
||||||
|
|
||||||
|
public class CharCreateRuneParser {
|
||||||
|
|
||||||
|
private static final String fileName = "Config/CharCreateRuneList.cfg";
|
||||||
|
|
||||||
|
public static CharCreateRuneList parseCharCreateRuneFile() {
|
||||||
|
|
||||||
|
CharCreateRuneList runeList = new CharCreateRuneList();
|
||||||
|
WpakBlock root;
|
||||||
|
int failedCount = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
root = WpakFileReader.readBlocks(fileName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.error(fileName + ": " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WpakLine line : root.lines()) {
|
||||||
|
Logger.error(line.location() + ": line outside a XxxRUNESBEGIN/END section");
|
||||||
|
failedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WpakBlock block : root.blocks()) {
|
||||||
|
try {
|
||||||
|
switch (block.name) {
|
||||||
|
case "RACERUNES":
|
||||||
|
for (WpakLine line : block.lines())
|
||||||
|
runeList.race_runes.put(line.intToken(0), parseSex(line));
|
||||||
|
break;
|
||||||
|
case "CLASSRUNES":
|
||||||
|
readRuneIds(block, runeList.class_runes);
|
||||||
|
break;
|
||||||
|
case "PROMOTIONRUNES":
|
||||||
|
readRuneIds(block, runeList.promotion_runes);
|
||||||
|
break;
|
||||||
|
case "ATTRRUNES":
|
||||||
|
readRuneIds(block, runeList.attr_runes);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw block.beginLine.error("unexpected " + block.name + "BEGIN");
|
||||||
|
}
|
||||||
|
} catch (WpakFormatException e) {
|
||||||
|
Logger.error(e.getMessage());
|
||||||
|
failedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info("Loaded " + runeList.race_runes.size() + " race, " + runeList.class_runes.size() + " class, "
|
||||||
|
+ runeList.promotion_runes.size() + " promotion and " + runeList.attr_runes.size() + " attribute creation runes");
|
||||||
|
|
||||||
|
if (failedCount > 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return runeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The client keeps the previous line's sex when one is missing; every race line in the file has one
|
||||||
|
|
||||||
|
private static mbEnums.SexType parseSex(WpakLine line) {
|
||||||
|
|
||||||
|
if (!line.has(1))
|
||||||
|
return mbEnums.SexType.NONE;
|
||||||
|
|
||||||
|
return line.enumToken(mbEnums.SexType.class, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readRuneIds(WpakBlock block, ArrayList<Integer> runeIds) {
|
||||||
|
|
||||||
|
for (WpakLine line : block.lines())
|
||||||
|
runeIds.add(line.intToken(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.wpak;
|
||||||
|
|
||||||
|
import engine.parsers.objects.wpak.CompoundCurveTemplate;
|
||||||
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
// Loads CompoundCurves.cfg.
|
||||||
|
|
||||||
|
public class CompoundCurveParser {
|
||||||
|
|
||||||
|
private static final String fileName = "Config/CompoundCurves.cfg";
|
||||||
|
|
||||||
|
// Segments run back to back on one line, so the param count per simple curve
|
||||||
|
// is what tells where the next segment starts.
|
||||||
|
private static final HashMap<String, Integer> paramCounts = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
paramCounts.put("FlatLine", 0);
|
||||||
|
paramCounts.put("SlopedLine", 1);
|
||||||
|
paramCounts.put("SlopedInitValLine", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<String, CompoundCurveTemplate> parseCompoundCurvesFile() {
|
||||||
|
|
||||||
|
HashMap<String, CompoundCurveTemplate> curves = new HashMap<>();
|
||||||
|
ArrayList<WpakLine> lines;
|
||||||
|
CompoundCurveTemplate curve;
|
||||||
|
int failedCount = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
lines = WpakFileReader.readLines(fileName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.error(fileName + ": " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WpakLine line : lines) {
|
||||||
|
try {
|
||||||
|
curve = parseCurveLine(line);
|
||||||
|
|
||||||
|
if (curves.containsKey(curve.name))
|
||||||
|
throw line.error("duplicate curve " + curve.name);
|
||||||
|
|
||||||
|
curves.put(curve.name, curve);
|
||||||
|
} catch (WpakFormatException e) {
|
||||||
|
Logger.error(e.getMessage());
|
||||||
|
failedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info("Loaded " + curves.size() + " of " + lines.size() + " compound curves");
|
||||||
|
|
||||||
|
if (failedCount > 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return curves;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CompoundCurveTemplate parseCurveLine(WpakLine line) {
|
||||||
|
|
||||||
|
CompoundCurveTemplate curve = new CompoundCurveTemplate();
|
||||||
|
CompoundCurveTemplate.Segment segment;
|
||||||
|
Integer paramCount;
|
||||||
|
int index = 1;
|
||||||
|
|
||||||
|
curve.name = line.token(0);
|
||||||
|
|
||||||
|
while (line.has(index)) {
|
||||||
|
segment = new CompoundCurveTemplate.Segment();
|
||||||
|
segment.down_per_range = line.intToken(index);
|
||||||
|
segment.simple_curve = line.token(index + 1);
|
||||||
|
paramCount = paramCounts.get(segment.simple_curve);
|
||||||
|
|
||||||
|
if (paramCount == null)
|
||||||
|
throw line.error("unknown simple curve " + segment.simple_curve);
|
||||||
|
|
||||||
|
segment.params = new float[paramCount];
|
||||||
|
|
||||||
|
for (int i = 0; i < paramCount; i++)
|
||||||
|
segment.params[i] = line.floatToken(index + 2 + i);
|
||||||
|
|
||||||
|
curve.segments.add(segment);
|
||||||
|
index += 2 + paramCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curve.segments.isEmpty())
|
||||||
|
throw line.error("curve " + curve.name + " has no segments");
|
||||||
|
|
||||||
|
return curve;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.wpak;
|
||||||
|
|
||||||
|
import engine.mbEnums;
|
||||||
|
import engine.parsers.objects.wpak.EffectTemplate;
|
||||||
|
import engine.parsers.objects.wpak.ModTypeTemplate;
|
||||||
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
// Loads Effects.cfg. ModTypes.cfg and CompoundCurves.cfg must be loaded first:
|
||||||
|
// a mod's argument layout comes from its behavior, and curve names are checked.
|
||||||
|
|
||||||
|
public class EffectParser {
|
||||||
|
|
||||||
|
private static final String fileName = "Config/Effects.cfg";
|
||||||
|
|
||||||
|
public static HashMap<String, EffectTemplate> parseEffectsFile() {
|
||||||
|
|
||||||
|
HashMap<String, EffectTemplate> effects = new HashMap<>();
|
||||||
|
WpakBlock root;
|
||||||
|
EffectTemplate effect;
|
||||||
|
int blockCount = 0;
|
||||||
|
int failedCount = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
root = WpakFileReader.readBlocks(fileName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.error(fileName + ": " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WpakLine line : root.lines()) {
|
||||||
|
Logger.error(line.location() + ": line outside EFFECTBEGIN/END");
|
||||||
|
failedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WpakBlock block : root.blocks()) {
|
||||||
|
try {
|
||||||
|
if (!block.name.equals("EFFECT"))
|
||||||
|
throw block.beginLine.error("unexpected " + block.name + "BEGIN");
|
||||||
|
|
||||||
|
blockCount++;
|
||||||
|
effect = parseEffectBlock(block);
|
||||||
|
|
||||||
|
if (effects.containsKey(effect.effect_id))
|
||||||
|
Logger.warn(block.location() + ": duplicate effect " + effect.effect_id + "; the later entry wins");
|
||||||
|
|
||||||
|
effects.put(effect.effect_id, effect);
|
||||||
|
} catch (WpakFormatException e) {
|
||||||
|
Logger.error(e.getMessage());
|
||||||
|
failedCount++;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.error(block.location() + ": " + e);
|
||||||
|
failedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info("Loaded " + effects.size() + " of " + blockCount + " effects");
|
||||||
|
|
||||||
|
if (failedCount > 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return effects;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EffectTemplate parseEffectBlock(WpakBlock block) {
|
||||||
|
|
||||||
|
EffectTemplate effect = new EffectTemplate();
|
||||||
|
ArrayList<WpakLine> lines = block.lines();
|
||||||
|
WpakLine header;
|
||||||
|
|
||||||
|
if (lines.isEmpty())
|
||||||
|
throw block.beginLine.error("effect has no header line");
|
||||||
|
|
||||||
|
header = lines.get(0);
|
||||||
|
effect.effect_id = header.token(0);
|
||||||
|
effect.effect_name = header.token(1);
|
||||||
|
effect.icon = header.optionalIntToken(2);
|
||||||
|
|
||||||
|
for (int i = 1; i < lines.size(); i++)
|
||||||
|
parseKey(effect, lines.get(i));
|
||||||
|
|
||||||
|
for (WpakBlock child : block.blocks()) {
|
||||||
|
switch (child.name) {
|
||||||
|
case "SOURCE":
|
||||||
|
for (WpakLine line : child.lines())
|
||||||
|
effect.sources.add(line.token(0));
|
||||||
|
break;
|
||||||
|
case "MODS":
|
||||||
|
for (WpakLine line : child.lines())
|
||||||
|
effect.mods.add(parseMod(line));
|
||||||
|
break;
|
||||||
|
case "CONDITION":
|
||||||
|
for (WpakLine line : child.lines())
|
||||||
|
effect.conditions.add(parseCondition(line));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw child.beginLine.error("unexpected " + child.name + "BEGIN in an effect");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!child.blocks().isEmpty())
|
||||||
|
throw child.blocks().get(0).beginLine.error("nested block in " + child.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The client compares these case-insensitively (cfg has IsItemEffect, client ISITEMEFFECT)
|
||||||
|
|
||||||
|
private static void parseKey(EffectTemplate effect, WpakLine line) {
|
||||||
|
|
||||||
|
switch (line.token(0).toUpperCase()) {
|
||||||
|
case "ISITEMEFFECT":
|
||||||
|
effect.isitemeffect = true;
|
||||||
|
break;
|
||||||
|
case "DONTSAVE":
|
||||||
|
effect.dontsave = true;
|
||||||
|
break;
|
||||||
|
case "IGNORENOMOD":
|
||||||
|
effect.ignorenomod = true;
|
||||||
|
break;
|
||||||
|
case "ISSPIREEFFECT":
|
||||||
|
effect.isspireeffect = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw line.error("unknown effect key " + line.token(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EffectTemplate.ModEntry parseMod(WpakLine line) {
|
||||||
|
|
||||||
|
EffectTemplate.ModEntry mod = new EffectTemplate.ModEntry();
|
||||||
|
ModTypeTemplate modType = ModTypeTemplate._modTypes.get(line.token(0));
|
||||||
|
|
||||||
|
if (modType == null)
|
||||||
|
throw line.error("mod type " + line.token(0) + " is not in ModTypes.cfg");
|
||||||
|
|
||||||
|
mod.mod_type = line.enumToken(mbEnums.ModType.class, 0);
|
||||||
|
mod.behavior = modType.behavior;
|
||||||
|
mod.args.addAll(line.tokens.subList(1, line.size()));
|
||||||
|
|
||||||
|
switch (mod.behavior) {
|
||||||
|
case "Flag":
|
||||||
|
break;
|
||||||
|
case "Standard":
|
||||||
|
parseStandard(mod, line);
|
||||||
|
break;
|
||||||
|
case "FPSubTypeAttr":
|
||||||
|
case "FPSubTypeSkill":
|
||||||
|
case "FPSubTypeDmg":
|
||||||
|
case "FPSubTypeMonster":
|
||||||
|
parseStandard(mod, line);
|
||||||
|
mod.type = line.token(4);
|
||||||
|
break;
|
||||||
|
case "DD":
|
||||||
|
mod.min_mod = line.floatToken(1);
|
||||||
|
mod.max_mod = line.floatToken(2);
|
||||||
|
mod.percent_mod = line.floatToken(3);
|
||||||
|
mod.curve = WpakParserUtil.curveToken(line, 5);
|
||||||
|
mod.type = line.token(6);
|
||||||
|
break;
|
||||||
|
case "ProcInfo":
|
||||||
|
mod.min_mod = line.floatToken(1);
|
||||||
|
mod.proc_power_id = line.token(2);
|
||||||
|
mod.percent_mod = line.floatToken(3);
|
||||||
|
break;
|
||||||
|
case "SubTypeSourceType":
|
||||||
|
case "SubTypePowerType":
|
||||||
|
mod.type = line.token(1);
|
||||||
|
mod.string1 = line.has(2) ? String.join(" ", line.tokens.subList(2, line.size())) : null;
|
||||||
|
break;
|
||||||
|
case "SubTypeSkill":
|
||||||
|
case "SubTypeDmg":
|
||||||
|
case "SubTypeMod":
|
||||||
|
case "SubTypePower":
|
||||||
|
mod.type = line.token(1);
|
||||||
|
break;
|
||||||
|
case "MapIntToInts":
|
||||||
|
mod.map_key = line.intToken(1);
|
||||||
|
mod.map_values.addAll(line.intTokensFrom(2));
|
||||||
|
break;
|
||||||
|
case "String":
|
||||||
|
mod.string1 = line.token(1);
|
||||||
|
mod.string2 = line.token(2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw line.error("unknown mod behavior " + mod.behavior + " for " + line.token(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tokens after the curve are ignored by the client (some lines end in "Unknown")
|
||||||
|
|
||||||
|
private static void parseStandard(EffectTemplate.ModEntry mod, WpakLine line) {
|
||||||
|
|
||||||
|
mod.min_mod = line.floatToken(1);
|
||||||
|
mod.percent_mod = line.floatToken(2);
|
||||||
|
mod.curve = WpakParserUtil.curveToken(line, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static EffectTemplate.ConditionEntry parseCondition(WpakLine line) {
|
||||||
|
|
||||||
|
EffectTemplate.ConditionEntry condition = new EffectTemplate.ConditionEntry();
|
||||||
|
|
||||||
|
condition.condition = line.enumToken(mbEnums.PowerFailCondition.class, 0);
|
||||||
|
condition.amount = line.floatToken(1);
|
||||||
|
condition.curve = line.has(2) ? WpakParserUtil.curveToken(line, 2) : null;
|
||||||
|
|
||||||
|
for (int i = 3; i < line.size(); i++)
|
||||||
|
condition.damage_types.add(line.enumToken(mbEnums.DamageType.class, i));
|
||||||
|
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.wpak;
|
||||||
|
|
||||||
|
import engine.parsers.objects.wpak.ModTypeTemplate;
|
||||||
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
// Loads ModTypes.cfg. Must load before Effects.cfg, whose mod arguments depend on the behavior.
|
||||||
|
|
||||||
|
public class ModTypeParser {
|
||||||
|
|
||||||
|
private static final String fileName = "Config/ModTypes.cfg";
|
||||||
|
|
||||||
|
public static HashMap<String, ModTypeTemplate> parseModTypesFile() {
|
||||||
|
|
||||||
|
HashMap<String, ModTypeTemplate> modTypes = new HashMap<>();
|
||||||
|
ArrayList<WpakLine> lines;
|
||||||
|
ModTypeTemplate modType;
|
||||||
|
int failedCount = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
lines = WpakFileReader.readLines(fileName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.error(fileName + ": " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WpakLine line : lines) {
|
||||||
|
try {
|
||||||
|
if (line.size() != 4)
|
||||||
|
throw line.error("expected 4 tokens, found " + line.size());
|
||||||
|
|
||||||
|
modType = new ModTypeTemplate();
|
||||||
|
modType.type = line.token(0);
|
||||||
|
modType.behavior = line.token(1);
|
||||||
|
modType.display_category = line.token(2);
|
||||||
|
modType.display_string = line.token(3);
|
||||||
|
|
||||||
|
if (modTypes.containsKey(modType.type))
|
||||||
|
throw line.error("duplicate mod type " + modType.type);
|
||||||
|
|
||||||
|
modTypes.put(modType.type, modType);
|
||||||
|
} catch (WpakFormatException e) {
|
||||||
|
Logger.error(e.getMessage());
|
||||||
|
failedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info("Loaded " + modTypes.size() + " of " + lines.size() + " mod types");
|
||||||
|
|
||||||
|
if (failedCount > 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return modTypes;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.wpak;
|
||||||
|
|
||||||
|
import engine.mbEnums;
|
||||||
|
import engine.parsers.objects.wpak.PowActionCostTemplate;
|
||||||
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
// Loads PowActionCostInfo.cfg (client loader EffectCostMap_LoadPowActionCostInfo 0x6E00C0).
|
||||||
|
|
||||||
|
public class PowActionCostParser {
|
||||||
|
|
||||||
|
private static final String fileName = "Config/PowActionCostInfo.cfg";
|
||||||
|
|
||||||
|
public static HashMap<String, PowActionCostTemplate> parsePowActionCostFile() {
|
||||||
|
|
||||||
|
HashMap<String, PowActionCostTemplate> costs = new HashMap<>();
|
||||||
|
ArrayList<WpakLine> lines;
|
||||||
|
PowActionCostTemplate cost;
|
||||||
|
int failedCount = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
lines = WpakFileReader.readLines(fileName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.error(fileName + ": " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WpakLine line : lines) {
|
||||||
|
try {
|
||||||
|
// A repeated id adds its pairs to the existing entry, as the client does
|
||||||
|
cost = costs.computeIfAbsent(line.token(0), id -> new PowActionCostTemplate());
|
||||||
|
cost.id = line.token(0);
|
||||||
|
|
||||||
|
for (int i = 1; i < line.size(); i += 2)
|
||||||
|
cost.costs.put(line.enumToken(mbEnums.ResourceType.class, i), line.intToken(i + 1));
|
||||||
|
} catch (WpakFormatException e) {
|
||||||
|
Logger.error(e.getMessage());
|
||||||
|
failedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info("Loaded " + costs.size() + " power action resource costs from " + lines.size() + " lines");
|
||||||
|
|
||||||
|
if (failedCount > 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return costs;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,258 @@
|
|||||||
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||||
|
// Magicbane Emulator Project © 2013 - 2026
|
||||||
|
// https://www.magicbane.com
|
||||||
|
|
||||||
|
package engine.parsers.wpak;
|
||||||
|
|
||||||
|
import engine.mbEnums;
|
||||||
|
import engine.parsers.objects.wpak.PowerActionTemplate;
|
||||||
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
// Loads PowerActions.cfg (client loader PowerActions_LoadCfg 0x578EC0).
|
||||||
|
// CompoundCurves.cfg must be loaded first.
|
||||||
|
|
||||||
|
public class PowerActionParser {
|
||||||
|
|
||||||
|
private static final String fileName = "Config/PowerActions.cfg";
|
||||||
|
|
||||||
|
public static HashMap<String, PowerActionTemplate> parsePowerActionsFile() {
|
||||||
|
|
||||||
|
HashMap<String, PowerActionTemplate> powerActions = new HashMap<>();
|
||||||
|
WpakBlock root;
|
||||||
|
PowerActionTemplate powerAction;
|
||||||
|
int blockCount = 0;
|
||||||
|
int failedCount = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
root = WpakFileReader.readBlocks(fileName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.error(fileName + ": " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WpakLine line : root.lines()) {
|
||||||
|
Logger.error(line.location() + ": line outside POWERACTIONBEGIN/END");
|
||||||
|
failedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WpakBlock block : root.blocks()) {
|
||||||
|
try {
|
||||||
|
if (!block.name.equals("POWERACTION"))
|
||||||
|
throw block.beginLine.error("unexpected " + block.name + "BEGIN");
|
||||||
|
|
||||||
|
blockCount++;
|
||||||
|
powerAction = parsePowerActionBlock(block);
|
||||||
|
|
||||||
|
// The client's map assigns on insert, so a repeated id keeps the later entry
|
||||||
|
if (powerActions.containsKey(powerAction.action_id))
|
||||||
|
Logger.warn(block.location() + ": duplicate power action " + powerAction.action_id + "; the later entry wins");
|
||||||
|
|
||||||
|
powerActions.put(powerAction.action_id, powerAction);
|
||||||
|
} catch (WpakFormatException e) {
|
||||||
|
Logger.error(e.getMessage());
|
||||||
|
failedCount++;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.error(block.location() + ": " + e);
|
||||||
|
failedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info("Loaded " + powerActions.size() + " of " + blockCount + " power actions");
|
||||||
|
|
||||||
|
if (failedCount > 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return powerActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PowerActionTemplate parsePowerActionBlock(WpakBlock block) {
|
||||||
|
|
||||||
|
PowerActionTemplate powerAction = new PowerActionTemplate();
|
||||||
|
ArrayList<WpakLine> lines = block.lines();
|
||||||
|
WpakLine header;
|
||||||
|
|
||||||
|
if (!block.blocks().isEmpty())
|
||||||
|
throw block.blocks().get(0).beginLine.error("nested block in a power action");
|
||||||
|
|
||||||
|
if (lines.isEmpty())
|
||||||
|
throw block.beginLine.error("empty power action");
|
||||||
|
|
||||||
|
header = lines.get(0);
|
||||||
|
powerAction.action_id = header.token(0);
|
||||||
|
powerAction.action_type = header.enumToken(mbEnums.PowerActionType.class, 1);
|
||||||
|
powerAction.header_args.addAll(header.tokens.subList(2, header.size()));
|
||||||
|
|
||||||
|
parseHeader(powerAction, header);
|
||||||
|
|
||||||
|
for (int i = 1; i < lines.size(); i++)
|
||||||
|
parseKey(powerAction, lines.get(i));
|
||||||
|
|
||||||
|
return powerAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layouts from the ArcPowerAction*_ParseHeader functions; args start at token 2
|
||||||
|
|
||||||
|
private static void parseHeader(PowerActionTemplate powerAction, WpakLine header) {
|
||||||
|
|
||||||
|
switch (powerAction.action_type) {
|
||||||
|
case ApplyEffect:
|
||||||
|
case Block:
|
||||||
|
case Charm:
|
||||||
|
case DirectDamage:
|
||||||
|
case Invis:
|
||||||
|
case SpireDisable:
|
||||||
|
powerAction.effect_ids.add(header.token(2));
|
||||||
|
powerAction.isaggressive = header.optionalIntToken(3) != 0;
|
||||||
|
break;
|
||||||
|
case ApplyEffects:
|
||||||
|
powerAction.isaggressive = header.intToken(2) != 0;
|
||||||
|
for (int i = 3; i < header.size(); i++)
|
||||||
|
powerAction.effect_ids.add(header.token(i));
|
||||||
|
break;
|
||||||
|
case DeferredPower:
|
||||||
|
powerAction.effect_ids.add(header.token(2));
|
||||||
|
powerAction.isaggressive = header.intToken(3) != 0;
|
||||||
|
powerAction.deferred_power_id = header.token(4);
|
||||||
|
break;
|
||||||
|
case DamageOverTime:
|
||||||
|
powerAction.effect_ids.add(header.token(2));
|
||||||
|
powerAction.num_iterations = header.intToken(3);
|
||||||
|
powerAction.isaggressive = header.optionalIntToken(4) != 0;
|
||||||
|
break;
|
||||||
|
case CreateMob:
|
||||||
|
powerAction.mob_id = header.intToken(2);
|
||||||
|
powerAction.mob_level = header.intToken(3);
|
||||||
|
break;
|
||||||
|
case RemoveEffect:
|
||||||
|
powerAction.effect_source_to_remove = header.token(2);
|
||||||
|
break;
|
||||||
|
case SetItemFlag:
|
||||||
|
powerAction.item_flag = header.enumToken(mbEnums.ItemFlags.class, 2);
|
||||||
|
powerAction.item_flag_value = header.optionalBoolToken(3);
|
||||||
|
break;
|
||||||
|
case Track:
|
||||||
|
powerAction.effect_ids.add(header.token(2));
|
||||||
|
powerAction.track_filter = header.token(5);
|
||||||
|
powerAction.max_track = header.intToken(7);
|
||||||
|
break;
|
||||||
|
case Transform:
|
||||||
|
powerAction.effect_ids.add(header.token(2));
|
||||||
|
break;
|
||||||
|
case TransferStat:
|
||||||
|
parseTransferStat(powerAction, header);
|
||||||
|
break;
|
||||||
|
case TransferStatOT:
|
||||||
|
parseTransferStat(powerAction, header);
|
||||||
|
powerAction.effect_ids.add(header.token(10));
|
||||||
|
powerAction.num_iterations = header.intToken(11);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void parseTransferStat(PowerActionTemplate powerAction, WpakLine header) {
|
||||||
|
|
||||||
|
powerAction.transfer_from_type = header.enumToken(mbEnums.CostType.class, 2);
|
||||||
|
powerAction.transfer_to_type = header.enumToken(mbEnums.CostType.class, 3);
|
||||||
|
powerAction.transfer_amount = header.floatToken(4);
|
||||||
|
powerAction.transfer_amount_curve = WpakParserUtil.curveToken(header, 5);
|
||||||
|
powerAction.transfer_efficiency = header.floatToken(6);
|
||||||
|
powerAction.transfer_efficiency_curve = WpakParserUtil.curveToken(header, 7);
|
||||||
|
powerAction.isaggressive = header.optionalIntToken(9) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shared keys from ArcPowerAction_ParseKey 0x579820; the rest are per action type.
|
||||||
|
// The client logs an unknown key and goes on; here it fails the load so no data is dropped silently.
|
||||||
|
|
||||||
|
private static void parseKey(PowerActionTemplate powerAction, WpakLine line) {
|
||||||
|
|
||||||
|
switch (line.token(0)) {
|
||||||
|
case "ISAGGRESSIVE=":
|
||||||
|
powerAction.isaggressive = line.optionalBoolToken(1);
|
||||||
|
break;
|
||||||
|
case "BLADETRAILS=":
|
||||||
|
powerAction.bladetrails = line.optionalBoolToken(1);
|
||||||
|
break;
|
||||||
|
case "ISRESISTABLE=":
|
||||||
|
powerAction.isresistable = line.optionalBoolToken(1);
|
||||||
|
break;
|
||||||
|
case "APPLYEFFECTSELF=":
|
||||||
|
powerAction.applyeffectself = line.token(1);
|
||||||
|
break;
|
||||||
|
case "APPLYEFFECTOTHER=":
|
||||||
|
powerAction.applyeffectother = line.token(1);
|
||||||
|
break;
|
||||||
|
case "WEAROFFEFFECTSELF=":
|
||||||
|
powerAction.wearoffeffectself = line.token(1);
|
||||||
|
break;
|
||||||
|
case "WEAROFFEFFECTOTHER=":
|
||||||
|
powerAction.wearoffeffectother = line.token(1);
|
||||||
|
break;
|
||||||
|
case "APPLYEFFECTBLANK=":
|
||||||
|
powerAction.applyeffectblank = line.optionalBoolToken(1);
|
||||||
|
break;
|
||||||
|
case "WEAROFFEFFECTBLANK=":
|
||||||
|
powerAction.wearoffeffectblank = line.optionalBoolToken(1);
|
||||||
|
break;
|
||||||
|
case "IS_AVAILABLE_FOR_FORMULAE=":
|
||||||
|
powerAction.is_available_for_formulae = line.optionalBoolToken(1);
|
||||||
|
break;
|
||||||
|
case "REMOVEALL=":
|
||||||
|
powerAction.removeall = line.optionalBoolToken(1);
|
||||||
|
break;
|
||||||
|
case "BODYPARTS=":
|
||||||
|
powerAction.bodyparts.addAll(line.intTokensFrom(1));
|
||||||
|
break;
|
||||||
|
case "FEMALEBODYPARTS=":
|
||||||
|
powerAction.femalebodyparts.addAll(line.intTokensFrom(1));
|
||||||
|
break;
|
||||||
|
case "SHOULDSHOWWEAPONS=":
|
||||||
|
powerAction.shouldshowweapons = line.optionalBoolToken(1);
|
||||||
|
break;
|
||||||
|
case "SHOULDSHOWARMOR=":
|
||||||
|
powerAction.shouldshowarmor = line.optionalBoolToken(1);
|
||||||
|
break;
|
||||||
|
case "ATTACKANIMS=":
|
||||||
|
powerAction.attackanims.addAll(line.intTokensFrom(1));
|
||||||
|
break;
|
||||||
|
case "SCALEFACTOR=":
|
||||||
|
powerAction.scalefactor = new float[]{line.floatToken(1), line.floatToken(2), line.floatToken(3)};
|
||||||
|
break;
|
||||||
|
case "EFFECTID=":
|
||||||
|
powerAction.effectid = line.token(1);
|
||||||
|
break;
|
||||||
|
case "LEVELCAP=":
|
||||||
|
powerAction.levelcap = line.intToken(1);
|
||||||
|
powerAction.levelcap_curve = line.has(2) ? WpakParserUtil.curveToken(line, 2) : null;
|
||||||
|
break;
|
||||||
|
case "CLEARAGGRO=":
|
||||||
|
powerAction.clearaggro = line.optionalBoolToken(1);
|
||||||
|
break;
|
||||||
|
case "TARGETBECOMESPET=":
|
||||||
|
powerAction.targetbecomespet = line.optionalBoolToken(1);
|
||||||
|
break;
|
||||||
|
case "DESTROYOLDPET=":
|
||||||
|
powerAction.destroyoldpet = line.optionalBoolToken(1);
|
||||||
|
break;
|
||||||
|
case "ROOTFSMID=":
|
||||||
|
powerAction.rootfsmid = line.token(1);
|
||||||
|
break;
|
||||||
|
case "DAMAGETYPE=":
|
||||||
|
powerAction.damagetype = line.enumToken(mbEnums.DamageType.class, 1);
|
||||||
|
break;
|
||||||
|
case "SPLASHDAMAGE=":
|
||||||
|
powerAction.splashdamage.addAll(line.intTokensFrom(1));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw line.error("unknown power action key " + line.token(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loaded 100 of 125 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user