forked from MagicBane/Server
Adds RuneBase(RuneTemplate, RuneBase): name from item_base_name, description from rune_dsc. type and subtype stay the static_rune_runebase values: they are server enums that don't map cleanly from rune_type/rune_sub_type (CLASS runes carry 0/2/3/5/256/289; the creation exclusive-group subtypes 1-10 leave out Blood Gift, the MaxIncrease chains and the hashed sub types). The requirement maps and effects are copied from the DB row until 2.5b/2.10. RuneBaseAttribute.getAttributesForRune builds attribute 0 from rune_creation_cost, 1-5 from rune_attr_adj, 6-10 from rune_max_attr_adj and 11-15 from item_attr_req. A static_rune_runebase comparator checks name and attributes against the JSON. Offline parity (scripts/p24.py, 315 runebase rows + 365 attribute rows vs the RUNE JSON): every row has a rune; all 365 DB attribute rows match. Differences: - name: 9 DB typos (Confesser, Theif, LagMaster, WP Dev, Exception Strength/ Dexterity/Constitution/Intelligence/Spirit) - attributes: 17 runes with no DB rows gain JSON values: base classes 2500-2503, Pet 2522, admin 2905/2907/2909/2911, guards 252621-252623, and creation cost on 250116, 250117, 250123-250125 - description: '' (or CSR text on 2901-2911) -> rune_dsc; nothing reads it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
238 lines
7.3 KiB
Java
238 lines
7.3 KiB
Java
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
|
// Magicbane Emulator Project © 2013 - 2026
|
|
// https://www.magicbane.com
|
|
|
|
|
|
package engine.objects;
|
|
|
|
import engine.gameManager.DbManager;
|
|
import engine.mbEnums;
|
|
import engine.net.ByteBufferWriter;
|
|
import engine.parsers.objects.RuneTemplate;
|
|
import engine.server.MBServerStatics;
|
|
|
|
import java.sql.ResultSet;
|
|
import java.sql.SQLException;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
|
public class RuneBase extends AbstractGameObject {
|
|
|
|
public static HashMap<Integer, ArrayList<Integer>> AllowedBaseClassRunesMap = new HashMap<>();
|
|
public static HashMap<Integer, ArrayList<Integer>> AllowedRaceRunesMap = new HashMap<>();
|
|
private final String name;
|
|
private final String description;
|
|
private final int type;
|
|
private final byte subtype;
|
|
private final ConcurrentHashMap<Integer, Boolean> race = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
|
private final ConcurrentHashMap<Integer, Boolean> baseClass = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
|
private final ConcurrentHashMap<Integer, Boolean> promotionClass = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
|
private final ConcurrentHashMap<Integer, Boolean> discipline = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
|
private final ArrayList<Integer> overwrite = new ArrayList<>();
|
|
private int levelRequired = 1;
|
|
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
|
|
|
/**
|
|
* No Table ID Constructor
|
|
*/
|
|
public RuneBase(String name, String description, int type, byte subtype, ArrayList<RuneBaseAttribute> attrs) {
|
|
super();
|
|
|
|
this.name = name;
|
|
this.description = description;
|
|
this.type = type;
|
|
this.subtype = subtype;
|
|
|
|
}
|
|
|
|
/**
|
|
* Normal Constructor
|
|
*/
|
|
public RuneBase(String name, String description, int type, byte subtype, ArrayList<RuneBaseAttribute> attrs, int newUUID) {
|
|
super(newUUID);
|
|
|
|
this.name = name;
|
|
this.description = description;
|
|
this.type = type;
|
|
this.subtype = subtype;
|
|
|
|
}
|
|
|
|
/**
|
|
* ResultSet Constructor
|
|
*/
|
|
public RuneBase(ResultSet rs) throws SQLException {
|
|
super(rs);
|
|
|
|
this.name = rs.getString("name");
|
|
this.description = rs.getString("description");
|
|
this.type = rs.getInt("type");
|
|
this.subtype = rs.getByte("subtype");
|
|
|
|
DbManager.RuneBaseQueries.GET_RUNE_REQS(this);
|
|
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID());
|
|
}
|
|
|
|
/**
|
|
* Rune Template Constructor
|
|
* type and subtype are server enums that don't map cleanly from rune_type/rune_sub_type, so they
|
|
* come from the static_rune_runebase row, as do the requirement maps and effects until 2.5b/2.10.
|
|
*/
|
|
public RuneBase(RuneTemplate rune, RuneBase dbRuneBase) {
|
|
super(rune.template_id);
|
|
|
|
this.name = rune.item_base_name;
|
|
this.description = rune.rune_dsc;
|
|
this.type = dbRuneBase.type;
|
|
this.subtype = dbRuneBase.subtype;
|
|
this.race.putAll(dbRuneBase.race);
|
|
this.baseClass.putAll(dbRuneBase.baseClass);
|
|
this.promotionClass.putAll(dbRuneBase.promotionClass);
|
|
this.discipline.putAll(dbRuneBase.discipline);
|
|
this.overwrite.addAll(dbRuneBase.overwrite);
|
|
this.levelRequired = dbRuneBase.levelRequired;
|
|
this.effectsList = dbRuneBase.effectsList;
|
|
}
|
|
|
|
public static RuneBase getRuneBase(int tableId) {
|
|
|
|
if (tableId == 0)
|
|
return null;
|
|
|
|
RuneBase rb = (RuneBase) DbManager.getFromCache(mbEnums.GameObjectType.RuneBase, tableId);
|
|
|
|
if (rb != null)
|
|
return rb;
|
|
|
|
return DbManager.RuneBaseQueries.GET_RUNEBASE(tableId);
|
|
}
|
|
|
|
public static void serializeForClientMsg(RuneBase runeBase, ByteBufferWriter writer) {
|
|
writer.putInt(runeBase.type);
|
|
writer.putInt(0); // Pad
|
|
writer.putInt(runeBase.getObjectUUID());
|
|
writer.putInt(runeBase.getObjectType().ordinal());
|
|
writer.putInt(runeBase.getObjectUUID());
|
|
|
|
}
|
|
|
|
public static void LoadAllRuneBases() {
|
|
|
|
DbManager.RuneBaseQueries.LOAD_ALL_RUNEBASES();
|
|
RuneBase.AllowedBaseClassRunesMap = DbManager.RuneBaseQueries.LOAD_ALLOWED_STARTING_RUNES_FOR_BASECLASS();
|
|
RuneBase.AllowedRaceRunesMap = DbManager.RuneBaseQueries.LOAD_ALLOWED_STARTING_RUNES_FOR_RACE();
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
|
|
if (!super.equals(obj)) {
|
|
return false;
|
|
}
|
|
|
|
if (obj instanceof RuneBase) {
|
|
RuneBase rbObj = (RuneBase) obj;
|
|
if (!this.name.equals(rbObj.name)) {
|
|
return false;
|
|
}
|
|
|
|
if (!this.description.equals(rbObj.description)) {
|
|
return false;
|
|
}
|
|
|
|
if (this.type != rbObj.type) {
|
|
return false;
|
|
}
|
|
|
|
if (this.subtype != rbObj.subtype) {
|
|
return false;
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Getters
|
|
*/
|
|
public String getName() {
|
|
return name;
|
|
}
|
|
|
|
public String getDescription() {
|
|
return description;
|
|
}
|
|
|
|
public int getType() {
|
|
return type;
|
|
}
|
|
|
|
/**
|
|
* @return the subtype
|
|
*/
|
|
public byte getSubtype() {
|
|
return subtype;
|
|
}
|
|
|
|
/**
|
|
* @return the attrs
|
|
*/
|
|
public ArrayList<RuneBaseAttribute> getAttrs() {
|
|
return RuneBaseAttribute.runeBaseAttributeMap.get(this.getObjectUUID());
|
|
}
|
|
|
|
public ConcurrentHashMap<Integer, Boolean> getRace() {
|
|
return this.race;
|
|
}
|
|
|
|
public ConcurrentHashMap<Integer, Boolean> getBaseClass() {
|
|
return this.baseClass;
|
|
}
|
|
|
|
public ConcurrentHashMap<Integer, Boolean> getPromotionClass() {
|
|
return this.promotionClass;
|
|
}
|
|
|
|
public ConcurrentHashMap<Integer, Boolean> getDiscipline() {
|
|
return this.discipline;
|
|
}
|
|
|
|
public ArrayList<Integer> getOverwrite() {
|
|
return this.overwrite;
|
|
}
|
|
|
|
/*
|
|
* Serializing
|
|
*/
|
|
|
|
public int getLevelRequired() {
|
|
return this.levelRequired;
|
|
}
|
|
|
|
public void setLevelRequired(int levelRequired) {
|
|
this.levelRequired = levelRequired;
|
|
}
|
|
|
|
@Override
|
|
public void updateDatabase() {
|
|
// TODO Auto-generated method stub
|
|
}
|
|
|
|
/**
|
|
* @return the effectsList
|
|
*/
|
|
public ArrayList<MobBaseEffects> getEffectsList() {
|
|
return effectsList;
|
|
}
|
|
|
|
}
|