Files
Server/src/engine/objects/SkillsBase.java
T
MagicBotandClaude Opus 5.5 865949fd1c Load rune granted skills from level-0 rune_skill_adj instead of static_skill_skillsgranted
Load moved after the rune templates are parsed.
Parity (scripts/p27.py): 76 of 107 DB runes match. Value changes (JSON
wins, Task 2.7 decisions):
- Blade Master 3005: Sword +10 removed (no rune_skill_adj in the JSON;
  Blade Weaver 3006 keeps Sword +10). Reaches players via PlayerBonuses.
- Pet 2522: Dodge and Unarmed Combat 1 -> 22. Not reachable; players
  never hold the Pet rune.
- 29 Master X / trainer runes lose their rows (no level-0 pairs in the
  JSON). Not reachable; players never hold trainer runes. Their caps
  still load into MaxSkills.
- 2243 mob/guard race runes gain rows. Not reachable; PlayerBonuses
  only reads player race/class/promotion/held runes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 07:46:48 -04:00

189 lines
6.0 KiB
Java

// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.objects;
import engine.gameManager.DbManager;
import engine.mbEnums.SourceType;
import engine.parsers.objects.RuneTemplate;
import engine.server.MBServerStatics;
import engine.util.Hasher;
import org.pmw.tinylog.Logger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class SkillsBase extends AbstractGameObject {
public static ConcurrentHashMap<String, SkillsBase> skillsCache = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
public static ConcurrentHashMap<Integer, SkillsBase> tokenCache = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
public static HashMap<Integer, HashMap<Integer, Integer>> runeSkillsCache = new HashMap<>();
private final String name;
private final String nameNoSpace;
private final String description;
private final int token;
private final short strMod;
private final short dexMod;
private final short conMod;
private final short intMod;
private final short spiMod;
public SourceType sourceType;
/**
* No Table ID Constructor
*/
public SkillsBase(String name, String description, int token, short strMod,
short dexMod, short conMod, short intMod, short spiMod) {
super();
this.name = name;
this.nameNoSpace = name.replace(" ", "");
this.sourceType = SourceType.GetSourceType(this.nameNoSpace.replace(",", ""));
this.description = description;
this.token = token;
this.strMod = strMod;
this.dexMod = dexMod;
this.conMod = conMod;
this.intMod = intMod;
this.spiMod = spiMod;
}
/**
* Normal Constructor
*/
public SkillsBase(String name, String description, int token, short strMod,
short dexMod, short conMod, short intMod, short spiMod, int newUUID) {
super(newUUID);
this.name = name;
this.nameNoSpace = name.replace(" ", "");
this.description = description;
this.token = token;
this.strMod = strMod;
this.dexMod = dexMod;
this.conMod = conMod;
this.intMod = intMod;
this.spiMod = spiMod;
}
/**
* ResultSet Constructor
*/
public SkillsBase(ResultSet rs) throws SQLException {
super(rs);
this.name = rs.getString("name");
this.nameNoSpace = name.replace(" ", "");
this.description = rs.getString("description");
this.sourceType = SourceType.GetSourceType(this.nameNoSpace.replace("-", "").replace("\"", "").replace(",", ""));
this.token = rs.getInt("token");
this.strMod = rs.getShort("strMod");
this.dexMod = rs.getShort("dexMod");
this.conMod = rs.getShort("conMod");
this.intMod = rs.getShort("intMod");
this.spiMod = rs.getShort("spiMod");
}
public static SkillsBase getFromCache(String name) {
if (skillsCache.containsKey(name))
return skillsCache.get(name);
else
return null;
}
public static SkillsBase getFromCache(int token) {
if (tokenCache.containsKey(token))
return tokenCache.get(token);
else
return null;
}
// 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) {
if (sb == null)
return;
DbManager.addToCache(sb);
skillsCache.putIfAbsent(sb.name, sb);
tokenCache.putIfAbsent(sb.token, sb);
}
/*
* Getters
*/
public String getName() {
return name;
}
public String getNameNoSpace() {
return nameNoSpace;
}
public String getDescription() {
return description;
}
public int getToken() {
return this.token;
}
public short getStrMod() {
return this.strMod;
}
public short getDexMod() {
return this.dexMod;
}
public short getConMod() {
return this.conMod;
}
public short getIntMod() {
return this.intMod;
}
public short getSpiMod() {
return this.spiMod;
}
@Override
public void updateDatabase() {
// TODO Auto-generated method stub
}
}