// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2026 // https://www.magicbane.com package engine.objects; import engine.gameManager.DbManager; import engine.mbEnums.AttributeType; import engine.mbEnums.SourceType; import engine.parsers.objects.RuneTemplate; import engine.parsers.objects.wpak.SkillTemplate; import engine.server.MBServerStatics; import engine.util.Hasher; import org.pmw.tinylog.Logger; 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 skillsCache = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); public static ConcurrentHashMap tokenCache = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); public static HashMap> 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; } public SkillsBase(int skillsBaseID, SkillTemplate template) { super(skillsBaseID); this.name = template.skill_name; this.nameNoSpace = name.replace(" ", ""); this.description = template.description; this.sourceType = SourceType.GetSourceType(this.nameNoSpace.replace("-", "").replace("\"", "").replace(",", "")); this.token = Hasher.SBStringHash(this.name); this.strMod = template.attr_weights.getOrDefault(AttributeType.Strength, 0).shortValue(); this.dexMod = template.attr_weights.getOrDefault(AttributeType.Dexterity, 0).shortValue(); this.conMod = template.attr_weights.getOrDefault(AttributeType.Constitution, 0).shortValue(); this.intMod = template.attr_weights.getOrDefault(AttributeType.Intelligence, 0).shortValue(); this.spiMod = template.attr_weights.getOrDefault(AttributeType.Spirit, 0).shortValue(); } 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; } // Skill ids stay in static_skill_skillsbase (dyn_character_skill and SkillReq use them); everything else is Skills.cfg public static void LoadAllSkillsBase() { HashMap skillsByName = new HashMap<>(); HashMap skillNames = DbManager.SkillsBaseQueries.GET_ALL_SKILL_NAMES(); SkillTemplate template; for (SkillTemplate skill : SkillTemplate._skills.values()) skillsByName.put(skill.skill_name, skill); for (Map.Entry skillName : skillNames.entrySet()) { template = skillsByName.get(skillName.getValue()); if (template == null) { Logger.error("static_skill_skillsbase " + skillName.getKey() + " '" + skillName.getValue() + "' has no Skills.cfg entry"); continue; } putInCache(new SkillsBase(skillName.getKey(), template)); } Logger.info("Loaded " + skillsCache.size() + " skills of " + SkillTemplate._skills.size() + " in Skills.cfg"); } // Level 0 adjusts are the skills a rune grants outright; higher levels are trainer caps public static void LoadAllRuneSkills() { HashMap grantedSkills; int entryCount = 0; for (RuneTemplate rune : RuneTemplate._runes.values()) { grantedSkills = new HashMap<>(); for (Map.Entry> 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 } }