// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2026 // https://www.magicbane.com package engine.objects; import engine.gameManager.DbManager; import engine.parsers.objects.RuneTemplate; import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class SkillReq extends AbstractGameObject { private static final int DEFAULT_SKILL_REQ_AMOUNT = 80; private static final ConcurrentHashMap> skillReqsByRune = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); private int skillID; private short level; private ArrayList skillReqs; private HashMap skillReqAmounts; /* This shouldn't be used public SkillReq(SkillsBase skillsBase, short level, ArrayListskillReqs) { super(); this.skillsBase = skillsBase; this.level = level; this.skillReqs = skillReqs; } */ /* This shouldn't be used public SkillReq(SkillsBase skillsBase, short level, ArrayListskillReqs, int newUUID) { super(newUUID); this.skillsBase = skillsBase; this.level = level; this.skillReqs = skillReqs; } */ /* This shouldn't be used public SkillReq(SkillReq a, int newUUID) { super(a, newUUID); this.skillsBase = a.skillsBase; this.level = a.level; this.skillReqs = a.skillReqs; } */ // skill_value is the level the skill is granted at; skill_granted_skills are prereq skills with amounts public SkillReq(RuneTemplate.SkillGrant skillGrant, SkillsBase skillsBase, int runeID) { super(); SkillsBase reqSkillsBase; this.skillID = skillsBase.getObjectUUID(); this.level = (short) skillGrant.skill_value; this.skillReqs = new ArrayList<>(0); this.skillReqAmounts = new HashMap<>(); for (Map.Entry reqSkill : skillGrant.skill_granted_skills.entrySet()) { 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 getSkillReqsForRune(int runeID) { return skillReqsByRune.computeIfAbsent(runeID, SkillReq::loadSkillReqsForRune); } private static ArrayList loadSkillReqsForRune(int runeID) { ArrayList runeSkillReqs = new ArrayList<>(); ArrayList 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; } /* * Getters */ public SkillsBase getSkillsBase() { return DbManager.SkillsBaseQueries.GET_BASE(this.skillID); } public int getSkillID() { return this.skillID; } public short getLevel() { return this.level; } public ArrayList getSkillReqs() { return this.skillReqs; } public int getSkillReqAmount(byte reqSkillID) { return this.skillReqAmounts.getOrDefault(reqSkillID, DEFAULT_SKILL_REQ_AMOUNT); } @Override public void updateDatabase() { } }