Fix enchantment switching gems

This commit is contained in:
Coldsmiles
2026-10-05 02:27:30 +08:00
parent d87fc866ab
commit 09380ecd24
6 changed files with 76 additions and 13 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ plugins/
```text ```text
plugins/ plugins/
├─ MagicGem-Reforged-1.0.0.jar ├─ MagicGem-Reforged-1.0.1.jar
├─ MagicGem/ ├─ MagicGem/
└─ MagicGem-Reforged/ └─ MagicGem-Reforged/
``` ```
+1 -1
View File
@@ -39,4 +39,4 @@ plugins/MagicGem → plugins/MagicGem-Reforged
mvn clean package mvn clean package
``` ```
产物位于 `target/MagicGem-Reforged-1.0.0.jar`。 产物位于 `target/MagicGem-Reforged-1.0.1.jar`。
+1 -1
View File
@@ -6,7 +6,7 @@
<groupId>cn.infstar</groupId> <groupId>cn.infstar</groupId>
<artifactId>magicgem-reforged</artifactId> <artifactId>magicgem-reforged</artifactId>
<version>1.0.0</version> <version>1.0.1</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>MagicGem-Reforged</name> <name>MagicGem-Reforged</name>
@@ -217,10 +217,10 @@ public final class SkillEngine implements Listener {
switch (normalize(mechanic.type())) { switch (normalize(mechanic.type())) {
case "reward" -> { case "reward" -> {
ItemStack changed = applyReward(player, item, mechanic, false); ItemStack changed = applyReward(player, item, mechanic, false);
if (changed != item) replaceMatchingItem(player, item, changed); if (changed != item) replaceMatchingItem(player, slot, item, changed);
} }
case "rewardswitch" -> { } case "rewardswitch" -> { }
case "switch" -> switchSkill(player, item, skill, mechanic); case "switch" -> switchSkill(player, item, slot, mechanic);
case "potionbuff" -> potionBuff(player, item, mechanic, action.target(), target, action.worldLimits()); case "potionbuff" -> potionBuff(player, item, mechanic, action.target(), target, action.worldLimits());
case "blink" -> blink(player, item, mechanic, action.target(), target, context.location()); case "blink" -> blink(player, item, mechanic, action.target(), target, context.location());
case "timestart" -> timeStart(player, item, skill, mechanic); case "timestart" -> timeStart(player, item, skill, mechanic);
@@ -251,7 +251,7 @@ public final class SkillEngine implements Listener {
return rewardContext.item(); return rewardContext.item();
} }
private void switchSkill(Player player, ItemStack item, SkillDefinition source, Directive mechanic) private void switchSkill(Player player, ItemStack item, String slot, Directive mechanic)
throws RewardException { throws RewardException {
List<String> cycle = new ArrayList<>(); List<String> cycle = new ArrayList<>();
String first = mechanic.argument("", "skills", "list", "s"); String first = mechanic.argument("", "skills", "list", "s");
@@ -277,7 +277,7 @@ public final class SkillEngine implements Listener {
if (newSkill != null) for (SkillAction action : newSkill.actions()) if (newSkill != null) for (SkillAction action : newSkill.actions())
if (normalize(action.mechanic().type()).equals("rewardswitch")) if (normalize(action.mechanic().type()).equals("rewardswitch"))
changed = applyReward(player, changed, action.mechanic(), false); changed = applyReward(player, changed, action.mechanic(), false);
replaceMatchingItem(player, item, changed); replaceItemInSlot(player, slot, item, changed);
} }
private void potionBuff(Player player, ItemStack item, Directive mechanic, String selector, Entity target, private void potionBuff(Player player, ItemStack item, Directive mechanic, String selector, Entity target,
@@ -525,16 +525,46 @@ public final class SkillEngine implements Listener {
return value.toLowerCase(Locale.ROOT).replace("_", "").replace("-", ""); return value.toLowerCase(Locale.ROOT).replace("_", "").replace("-", "");
} }
private void replaceMatchingItem(Player player, ItemStack original, ItemStack changed) { private void replaceMatchingItem(Player player, String configuredSlot, ItemStack original, ItemStack changed) {
EquipmentSlot expected = equipmentSlot(configuredSlot);
if (expected != null) {
ItemStack equipped = player.getInventory().getItem(expected);
if (equipped == original || equipped != null && original != null && equipped.isSimilar(original)) {
player.getInventory().setItem(expected, changed);
return;
}
}
for (EquipmentSlot slot : EquipmentSlot.values()) { for (EquipmentSlot slot : EquipmentSlot.values()) {
ItemStack equipped = player.getInventory().getItem(slot); ItemStack equipped = player.getInventory().getItem(slot);
if (equipped == original) { if (equipped == original || equipped != null && original != null && equipped.isSimilar(original)) {
player.getInventory().setItem(slot, changed); player.getInventory().setItem(slot, changed);
return; return;
} }
} }
} }
private void replaceItemInSlot(Player player, String configuredSlot, ItemStack original, ItemStack changed) {
EquipmentSlot expected = equipmentSlot(configuredSlot);
if (expected != null) {
player.getInventory().setItem(expected, changed);
return;
}
replaceMatchingItem(player, configuredSlot, original, changed);
}
private EquipmentSlot equipmentSlot(String configuredSlot) {
if (configuredSlot == null) return null;
return switch (configuredSlot.toLowerCase(Locale.ROOT)) {
case "mainhand", "hand" -> EquipmentSlot.HAND;
case "offhand" -> EquipmentSlot.OFF_HAND;
case "head", "helmet" -> EquipmentSlot.HEAD;
case "chest", "chestplate" -> EquipmentSlot.CHEST;
case "legs", "leggings" -> EquipmentSlot.LEGS;
case "feet", "boots" -> EquipmentSlot.FEET;
default -> null;
};
}
private Player attackingPlayer(Entity damager) { private Player attackingPlayer(Entity damager) {
if (damager instanceof Player player) return player; if (damager instanceof Player player) return player;
if (damager instanceof Projectile projectile && projectile.getShooter() instanceof Player player) return player; if (damager instanceof Projectile projectile && projectile.getShooter() instanceof Player player) return player;
+5 -4
View File
@@ -38,12 +38,12 @@
- Switch{s=精准;时运} ~onShiftUse - Switch{s=精准;时运} ~onShiftUse
精准: 精准:
Skills: Skills:
- RewardSwitch{Enchant{name=SILK_TOUCH;limit=1}} - RewardSwitch{Enchant{name=SILK_TOUCH;level=1;limit=1}}
- RewardSwitch{ActionBar{m=&b&l切换为精准模式}} - RewardSwitch{ActionBar{m=&b&l切换为精准模式}}
时运: 时运:
Skills: Skills:
- RewardSwitch{Enchant{name=LOOT_BONUS_BLOCKS;level=0}} - RewardSwitch{Enchant{name=LOOT_BONUS_BLOCKS;level=1;limit=1}}
- RewardSwitch{ActionBar{m=&a&l切换为时运模式}} - RewardSwitch{ActionBar{m=&a&l切换为时运模式}}
忠诚/激流切换: 忠诚/激流切换:
@@ -55,12 +55,13 @@
激流: 激流:
Skills: Skills:
- RewardSwitch{Enchant{name=RIPTIDE;level=0}} - RewardSwitch{Enchant{name=RIPTIDE;level=1;limit=1}}
- RewardSwitch{ActionBar{m=&b&l切换为激流模式}} - RewardSwitch{ActionBar{m=&b&l切换为激流模式}}
忠诚: 忠诚:
Skills: Skills:
- RewardSwitch{ActionBar{m=&a&l切换为时忠诚模式}} - RewardSwitch{Enchant{name=LOYALTY;level=1;limit=1}}
- RewardSwitch{ActionBar{m=&a&l切换为忠诚模式}}
禁飞DEBUFF: 禁飞DEBUFF:
Cooldown: 5.0 Cooldown: 5.0
@@ -12,8 +12,10 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Set; import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
@@ -94,4 +96,34 @@ class BundledConfigurationTest {
} }
} }
} }
@Test
void enchantmentSwitchModesDefineSymmetricPositiveLevels() {
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(
new File("src/main/resources/skills/DefaultSkills.yml"));
Map<String, String> expected = Map.of(
"精准", "SILK_TOUCH",
"时运", "LOOT_BONUS_BLOCKS",
"激流", "RIPTIDE",
"忠诚", "LOYALTY");
for (Map.Entry<String, String> entry : expected.entrySet()) {
String path = entry.getKey() + ".Skills";
String source = yaml.getStringList(path).stream()
.filter(line -> line.trim().startsWith("RewardSwitch{Enchant{"))
.findFirst()
.orElse(null);
assertNotNull(source, path + " must contain an enchantment RewardSwitch");
Directive rewardSwitch = parser.parse(source);
String nestedSource = rewardSwitch.positional().isEmpty()
? rewardSwitch.argument("", "reward", "r")
: rewardSwitch.positional().getFirst();
Directive enchant = parser.parse(nestedSource);
assertEquals("Enchant", enchant.type(), path);
assertEquals(entry.getValue(), enchant.argument("", "name"), path);
assertEquals(1, enchant.intArgument(1, "level", "l"), path);
assertEquals(1, enchant.intArgument(0, "limit"), path);
}
}
} }