Block skill refines that break a trained power's skill requirement

The old check looked up power requirements by power id instead of rune id,
so it never ran. Refining a skill below a trained power's requirement let
calculatePowers delete the power and its trains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MagicBotandClaude Opus 5.5 committed 2026-10-26 11:41:23 -04:00
1 parent 17d82066d6
commit 24e91cc0a9
2 files changed
+46 -11

No files matched your search

@@ -88,6 +88,9 @@ public class RefineMsgHandler extends AbstractClientMsgHandler {
public static boolean refineSkill(ClientConnection origin, PlayerCharacter pc, int token, RefineMsg msg) { public static boolean refineSkill(ClientConnection origin, PlayerCharacter pc, int token, RefineMsg msg) {
CharacterSkill skill = null; CharacterSkill skill = null;
ConcurrentHashMap<String, CharacterSkill> skills = pc.getSkills(); ConcurrentHashMap<String, CharacterSkill> skills = pc.getSkills();
int refinedAmount;
int requiredAmount;
for (CharacterSkill sk : skills.values()) { for (CharacterSkill sk : skills.values()) {
if (sk == null) if (sk == null)
continue; continue;
@@ -106,17 +109,16 @@ public class RefineMsgHandler extends AbstractClientMsgHandler {
//TODO verify if any skills have this as prereq //TODO verify if any skills have this as prereq
//TODO verify if any powers have this as a prereq // Dropping below a trained power's skill requirement would make calculatePowers delete the power and its trains
//get all players powers refinedAmount = Math.round(skill.getBaseAmountBeforeMods() + skill.calculateAmountAfterTrains(skill.getNumTrains() - 1));
for (CharacterPower power : pc.getPowers().values()) { for (CharacterPower power : pc.getPowers().values()) {
ArrayList<PowerReq> reqs = PowerReq.getPowerReqsForRune(power.getPowerID()); if (power.getTrains() < 1)
for (PowerReq req : reqs) { continue;
ConcurrentHashMap<String, CharacterSkill> playerSkills = pc.getSkills(); requiredAmount = getRequiredSkillAmount(pc, power.getPower().getToken(), token);
CharacterSkill playerSkill = playerSkills.get(token); if (refinedAmount < requiredAmount) {
int currentSkillLevel = playerSkill.getTotalSkillPercet(); ErrorPopupMsg.sendErrorMsg(pc, "You must refine " + power.getPower().getName() + " to 0 before refining any more from this skill.");
if (token == req.getToken() && req.getLevel() == currentSkillLevel) { return false;
return false;
}
} }
} }
@@ -124,6 +126,36 @@ public class RefineMsgHandler extends AbstractClientMsgHandler {
return skill.refine(pc); return skill.refine(pc);
} }
private static int getRequiredSkillAmount(PlayerCharacter pc, int powerToken, int skillToken) {
int requiredAmount = 0;
if (pc.race != null)
requiredAmount = Math.max(requiredAmount, getRequiredSkillAmount(pc.race.getPowersGranted(), powerToken, skillToken));
if (pc.baseClass != null)
requiredAmount = Math.max(requiredAmount, getRequiredSkillAmount(pc.baseClass.getPowersGranted(), powerToken, skillToken));
if (pc.promotionClass != null)
requiredAmount = Math.max(requiredAmount, getRequiredSkillAmount(pc.promotionClass.getPowersGranted(), powerToken, skillToken));
if (pc.getRunes() != null)
for (CharacterRune rune : pc.getRunes())
requiredAmount = Math.max(requiredAmount, getRequiredSkillAmount(rune.getPowersGranted(), powerToken, skillToken));
return requiredAmount;
}
private static int getRequiredSkillAmount(ArrayList<PowerReq> powersGranted, int powerToken, int skillToken) {
Byte requiredAmount;
for (PowerReq powerReq : powersGranted) {
if (powerReq.getToken() != powerToken)
continue;
requiredAmount = powerReq.getSkillReqs().get(skillToken);
if (requiredAmount != null)
return requiredAmount;
}
return 0;
}
public static boolean refinePower(ClientConnection origin, PlayerCharacter pc, int token, RefineMsg msg) { public static boolean refinePower(ClientConnection origin, PlayerCharacter pc, int token, RefineMsg msg) {
CharacterPower power = null; CharacterPower power = null;
ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers(); ConcurrentHashMap<Integer, CharacterPower> powers = pc.getPowers();
+4 -1
View File
@@ -1136,9 +1136,12 @@ public class CharacterSkill extends AbstractGameObject {
Logger.error("SkillsBase not found for skill " + this.getObjectUUID()); Logger.error("SkillsBase not found for skill " + this.getObjectUUID());
this.modifiedAmount = this.baseAmount; this.modifiedAmount = this.baseAmount;
} }
return calculateAmountAfterTrains(this.numTrains.get());
}
public float calculateAmountAfterTrains(int trains) {
int amount; int amount;
int trains = this.numTrains.get();
if (trains < 10) if (trains < 10)
amount = (trains * 2); amount = (trains * 2);
else if (trains < 90) else if (trains < 90)