Fixed %mmocore_cast_slot_offset_<slot>%. New option for skill bar casting mode to not use lowest keybinds

This commit is contained in:
Jules 2024-10-22 15:11:17 +02:00
parent c84e52a963
commit bfc91619a9
10 changed files with 76 additions and 36 deletions

View File

@ -1136,7 +1136,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) return false;
this.skillCasting = SkillCastingMode.getCurrent().newInstance(this);
this.skillCasting = SkillCastingMode.getInstance().newInstance(this);
return true;
}
@ -1321,6 +1321,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
unbindSkill(slot);
final SkillSlot skillSlot = getProfess().getSkillSlot(slot);
boundSkills.put(slot, new BoundSkillInfo(skillSlot, skill, this));
SkillCastingMode.getInstance().onSkillBound(this);
}
@Nullable

View File

@ -3,6 +3,7 @@ package net.Indyuce.mmocore.command;
import io.lumine.mythic.lib.command.api.CommandTreeRoot;
import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.command.rpg.CastCommandTreeNode;
import net.Indyuce.mmocore.command.rpg.CoinsCommandTreeNode;
import net.Indyuce.mmocore.command.rpg.NoteCommandTreeNode;
import net.Indyuce.mmocore.command.rpg.ReloadCommandTreeNode;
@ -26,6 +27,7 @@ public class MMOCoreCommandTreeRoot extends CommandTreeRoot implements CommandEx
super("mmocore", "mmocore.admin");
addChild(new ReloadCommandTreeNode(this));
addChild(new CastCommandTreeNode(this));
addChild(new CoinsCommandTreeNode(this));
addChild(new NoteCommandTreeNode(this));
addChild(new AdminCommandTreeNode(this));

View File

@ -162,20 +162,15 @@ public class RPGPlaceholders extends PlaceholderExpansion {
else if (identifier.startsWith("cast_slot_offset_")) {
final Player online = player.getPlayer();
Validate.notNull(online, "Player is offline");
final AtomicInteger query = new AtomicInteger(Integer.parseInt(identifier.substring(17)));
final int query = Integer.parseInt(identifier.substring(17));
BoundSkillInfo bound = playerData.getBoundSkills().get(query.get());
BoundSkillInfo bound = playerData.getBoundSkills().get(query);
if (bound == null || bound.isPassive()) return String.valueOf(0);
// Offset due to passive skills
playerData.getBoundSkills().forEach((slot, skill) -> {
if (skill.isPassive() && slot < query.get())
query.addAndGet(-1);
});
int slot = bound.skillBarCastSlot;
// Offset due to player's hotbar location
if (online.getInventory().getHeldItemSlot() < query.get()) query.addAndGet(1);
return String.valueOf(query.get());
if (online.getInventory().getHeldItemSlot() < slot) slot++;
return String.valueOf(slot);
}
// Is there a passive skill bound to given slot

View File

@ -14,6 +14,16 @@ public class BoundSkillInfo implements Closeable {
private final PlayerData playerData;
private final ClassSkill classSkill;
/**
* If the skill casting mode is set to skill bar, then
* this corresponds to the slot the player needs to click
* (not taking into account casting slot offset) in order
* to cast this skill.
* <p>
* If it is a passive skill, this value has no meaning.
*/
public int skillBarCastSlot;
/**
* Non-permanent passive skills must be registered inside
* MythicLib when bound. When set to null, the skill is either

View File

@ -29,4 +29,8 @@ public abstract class SkillCastingHandler implements Listener {
@NotNull
public abstract SkillCastingInstance newInstance(@NotNull PlayerData player);
public void onSkillBound(@NotNull PlayerData player) {
// Nothing by default
}
}

View File

@ -78,7 +78,16 @@ public enum SkillCastingMode {
}
@NotNull
public static SkillCastingHandler getCurrent() {
public static SkillCastingHandler getInstance() {
return Objects.requireNonNull(current, "Skill casting mode hasn't been initialized yet");
}
/**
* @see #getInstance()
* @deprecated
*/
@Deprecated
public static SkillCastingHandler getCurrent() {
return getInstance();
}
}

View File

@ -1,9 +1,6 @@
package net.Indyuce.mmocore.skill.cast.handler;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.player.PlayerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.SoundEvent;
@ -21,18 +18,20 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class SkillBar extends SkillCastingHandler {
private final PlayerKey mainKey;
private final boolean disableSneak;
private final boolean disableSneak, lowestKeybinds;
public SkillBar(@NotNull ConfigurationSection config) {
super(config);
mainKey = PlayerKey.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("open"), "Could not find open key")));
disableSneak = config.getBoolean("disable-sneak");
lowestKeybinds = config.getBoolean("use-lowest-keybinds");
}
@Override
@ -45,6 +44,23 @@ public class SkillBar extends SkillCastingHandler {
return SkillCastingMode.SKILL_BAR;
}
@Override
public void onSkillBound(@NotNull PlayerData player) {
// Lowest indices = start at slot 1 and increase
if (lowestKeybinds) {
int slot = 1;
for (BoundSkillInfo bound : player.getBoundSkills().values())
// Set cast slot and increment slot
if (!bound.isPassive()) bound.skillBarCastSlot = slot++;
}
// Otherwise, direct correspondance
else player.getBoundSkills().forEach((slot, bound) -> bound.skillBarCastSlot = slot);
}
@EventHandler
public void enterSkillCasting(PlayerKeyPressEvent event) {
if (event.getPressed() != mainKey) return;
@ -80,7 +96,7 @@ public class SkillBar extends SkillCastingHandler {
}
@EventHandler
public void onSkillCast(PlayerItemHeldEvent event) {
public void onItemHeld(PlayerItemHeldEvent event) {
if (!event.getPlayer().equals(getCaster().getPlayer())) return;
// Extra option to improve support with other plugins
@ -96,18 +112,18 @@ public class SkillBar extends SkillCastingHandler {
event.setCancelled(true);
refreshTimeOut();
final int activeSlot = event.getNewSlot() + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0);
/*
* The event is called again soon after the first since when
* cancelling the first one, the player held item slot must go back
* to the previous one.
*/
if (activeSlot < getActiveSkills().size()) {
final ClassSkill classSkill = getActiveSkills().get(activeSlot).getClassSkill();
final PlayerMetadata caster = getCaster().getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND);
classSkill.toCastable(getCaster()).cast(new TriggerMetadata(caster, null, null));
}
// Look for skill with given slot
ClassSkill classSkill = findSkillToCast(player.getInventory().getHeldItemSlot(), event.getNewSlot());
if (classSkill != null) classSkill.toCastable(getCaster()).cast(getCaster().getMMOPlayerData());
}
@Nullable
private ClassSkill findSkillToCast(int currentSlot, int clickedSlot) {
for (BoundSkillInfo info : this.getActiveSkills())
if (info.skillBarCastSlot + (currentSlot < info.skillBarCastSlot ? 1 : 0) == 1 + clickedSlot)
return info.getClassSkill();
return null;
}
@EventHandler
@ -128,12 +144,12 @@ public class SkillBar extends SkillCastingHandler {
@NotNull
private String getFormat(PlayerData data) {
final StringBuilder str = new StringBuilder();
if (!data.isOnline()) return str.toString();
if (!data.isOnline()) return "";
int slot = 1;
final StringBuilder str = new StringBuilder();
for (BoundSkillInfo active : getActiveSkills()) {
final ClassSkill skill = active.getClassSkill();
final int slot = active.skillBarCastSlot;
str.append(str.isEmpty() ? "" : split).append(
(onCooldown(data, skill) ? onCooldown.replace("{cooldown}",
@ -141,8 +157,8 @@ public class SkillBar extends SkillCastingHandler {
noMana(data, skill) ? noMana : (noStamina(data, skill) ? noStamina : ready))
.replace("{index}", String.valueOf(slot + (data.getPlayer().getInventory().getHeldItemSlot() < slot ? 1 : 0)))
.replace("{skill}", skill.getSkill().getName()));
slot++;
}
return MMOCore.plugin.placeholderParser.parse(data.getPlayer(), str.toString());
}

View File

@ -4,12 +4,11 @@ import io.lumine.mythic.lib.player.skill.PassiveSkill;
import io.lumine.mythic.lib.skill.SkillMetadata;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
import io.lumine.mythic.lib.skill.result.def.SimpleSkillResult;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
public class Neptune_Gift extends SkillHandler<SimpleSkillResult> implements Listener {
public Neptune_Gift() {
@ -18,6 +17,7 @@ public class Neptune_Gift extends SkillHandler<SimpleSkillResult> implements Lis
registerModifiers("extra");
}
@NotNull
@Override
public SimpleSkillResult getResult(SkillMetadata meta) {
throw new RuntimeException("Not supported");

View File

@ -14,6 +14,7 @@ import org.bukkit.Sound;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
public class Sneaky_Picky extends SkillHandler<SimpleSkillResult> implements Listener {
public Sneaky_Picky() {
@ -22,15 +23,16 @@ public class Sneaky_Picky extends SkillHandler<SimpleSkillResult> implements Lis
registerModifiers("extra");
}
@NotNull
@Override
public SimpleSkillResult getResult(SkillMetadata meta) {
return new SimpleSkillResult(meta.hasAttackBound() && meta.hasTargetEntity() && meta.getTargetEntityOrNull() instanceof LivingEntity);
return new SimpleSkillResult(meta.hasAttackSource() && meta.hasTargetEntity() && meta.getTargetEntityOrNull() instanceof LivingEntity);
}
@Override
public void whenCast(SimpleSkillResult result, SkillMetadata skillMeta) {
LivingEntity target = (LivingEntity) skillMeta.getTargetEntity();
skillMeta.getAttack().getDamage().multiplicativeModifier(1 + skillMeta.getParameter("extra") / 100, DamageType.WEAPON);
skillMeta.getAttackSource().getDamage().multiplicativeModifier(1 + skillMeta.getParameter("extra") / 100, DamageType.WEAPON);
target.getWorld().spawnParticle(VParticle.SMOKE.get(), target.getLocation().add(0, target.getHeight() / 2, 0), 64, 0, 0, 0, .05);
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1, 2);
}

View File

@ -106,6 +106,7 @@ skill-casting:
mode: SKILL_BAR
open: SWAP_HANDS
disable-sneak: false
use-lowest-keybinds: true
loot-chests: