Skip to content

Commit

Permalink
enhance: New skill item activate method
Browse files Browse the repository at this point in the history
  • Loading branch information
MATRIX-feather committed Oct 7, 2024
1 parent 3317fa8 commit 861636a
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 9 deletions.
3 changes: 2 additions & 1 deletion src/main/java/xiamomc/morph/commands/MorphPluginCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public FormattableMessage getHelpMessage()
new StatSubCommand(),
new CheckUpdateSubCommand(),
new LookupSubCommand(),
new SkinCacheSubCommand()
new SkinCacheSubCommand(),
new DisguiseItemSubCommand()
//new BackendSubCommand()
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package xiamomc.morph.commands.subcommands.plugin;

import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xiamomc.morph.MorphPluginObject;
import xiamomc.morph.messages.CommandStrings;
import xiamomc.morph.messages.MessageUtils;
import xiamomc.morph.misc.NmsRecord;
import xiamomc.morph.utilities.ItemUtils;
import xiamomc.pluginbase.Command.ISubCommand;
import xiamomc.pluginbase.Messages.FormattableMessage;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

public class DisguiseItemSubCommand extends MorphPluginObject implements ISubCommand
{
public DisguiseItemSubCommand()
{
CompletableFuture.supplyAsync(() ->
{
Map<String, Material> items = new Object2ObjectOpenHashMap<>();

for (Material value : Material.values())
{
if (!value.isItem()) continue;

items.put(value.getKey().asString(), value);
}

return items;
}).thenAccept(this.availableItems::putAll);
}

private final Map<String, Material> availableItems = new Object2ObjectOpenHashMap<>();

@Override
public @NotNull String getCommandName()
{
return "disguise_item";
}

@Override
public FormattableMessage getHelpMessage()
{
return new FormattableMessage(plugin, "disguise item");
}

private final List<String> emptyList = List.of();

@Override
public @Nullable List<String> onTabComplete(List<String> args, CommandSender source)
{
if (args.size() > 1) return emptyList;

return availableItems.keySet().stream().filter(s -> s.contains(args.get(0))).toList();
}

@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull String[] args)
{
if (args.length < 1)
{
sender.sendMessage(MessageUtils.prefixes(sender, CommandStrings.listNoEnoughArguments()));
return true;
}

if (!(sender instanceof Player player))
{
sender.sendMessage(MessageUtils.prefixes(sender, CommandStrings.noPermissionMessage()));
return true;
}

var itemId = args[0];
var material = availableItems.getOrDefault(itemId, null);

if (material == null)
{
sender.sendMessage(MessageUtils.prefixes(sender, CommandStrings.illegalArgumentString().resolve("detail", "'%s' -> null".formatted(itemId))));
return true;
}

var item = ItemUtils.buildSkillItemFrom(ItemStack.of(material));
player.getInventory().addItem(item);

sender.sendMessage(MessageUtils.prefixes(sender, CommandStrings.grantItemSuccess()));

return true;
}
}
1 change: 1 addition & 0 deletions src/main/java/xiamomc/morph/config/ConfigOption.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public enum ConfigOption
@Deprecated
ACTION_ITEM(ConfigNode.create().append("action_item"), "", true),
SKILL_ITEM(ConfigNode.create().append("skill_item"), "minecraft:feather"),
SKILL_ITEM_USE_COMPONENT(ConfigNode.create().append("skill_item_use_component_detection"), true),

ARMORSTAND_SHOW_ARMS(ConfigNode.create().append("armorstand_show_arms"), true),

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/xiamomc/morph/config/MorphConfigManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public void reload()
});

//更新配置
int targetVersion = 35;
int targetVersion = 36;

var configVersion = getOrDefault(Integer.class, ConfigOption.VERSION);

Expand Down
26 changes: 20 additions & 6 deletions src/main/java/xiamomc/morph/events/CommonEventProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.bukkit.event.player.*;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import xiamomc.morph.MorphManager;
import xiamomc.morph.MorphPluginObject;
import xiamomc.morph.RevealingHandler;
Expand All @@ -31,7 +32,6 @@
import xiamomc.morph.messages.SkillStrings;
import xiamomc.morph.messages.vanilla.VanillaMessageStore;
import xiamomc.morph.misc.DisguiseTypes;
import xiamomc.morph.misc.NetworkingHelper;
import xiamomc.morph.misc.OfflineDisguiseResult;
import xiamomc.morph.misc.playerList.PlayerListHandler;
import xiamomc.morph.misc.permissions.CommonPermissions;
Expand All @@ -41,6 +41,7 @@
import xiamomc.morph.network.server.ServerSetEquipCommand;
import xiamomc.morph.skills.MorphSkillHandler;
import xiamomc.morph.utilities.EntityTypeUtils;
import xiamomc.morph.utilities.ItemUtils;
import xiamomc.pluginbase.Annotations.Initializer;
import xiamomc.pluginbase.Annotations.Resolved;
import xiamomc.pluginbase.Bindables.Bindable;
Expand All @@ -67,11 +68,10 @@ public class CommonEventProcessor extends MorphPluginObject implements Listener
@Resolved(shouldSolveImmediately = true)
private RevealingHandler revealingHandler;

@Resolved(shouldSolveImmediately = true)
private NetworkingHelper networkingHelper;

private Bindable<Boolean> unMorphOnDeath;

private final Bindable<Boolean> useNewSkillItemMethod = new Bindable<>(true);

@EventHandler
public void onEntityDeath(EntityDeathEvent e)
{
Expand Down Expand Up @@ -155,6 +155,7 @@ private void load()
config.bind(allowAcquireMorphs, ConfigOption.ALLOW_ACQUIRE_MORPHS);

unMorphOnDeath = config.getBindable(Boolean.class, ConfigOption.UNMORPH_ON_DEATH);
config.bind(this.useNewSkillItemMethod, ConfigOption.SKILL_ITEM_USE_COMPONENT);
this.addSchedule(this::update);
}

Expand Down Expand Up @@ -215,6 +216,19 @@ public void onPlayerInteract(PlayerInteractEvent e)
e.setCancelled(true);
}

/**
*
* @param actionItemType The type of the action item.
* @param item The item to check
*/
private boolean isItemASkillItem(Material actionItemType, ItemStack item)
{
if (useNewSkillItemMethod.get())
return ItemUtils.isSkillActivateItem(item);
else
return item.getType() == actionItemType;
}

/**
* 尝试使用技能或快速伪装
* @param player 目标玩家
Expand All @@ -230,13 +244,13 @@ private boolean tryInvokeSkillOrQuickDisguise(Player player, Action action, Equi
var mainHandItem = player.getEquipment().getItemInMainHand();
var mainHandItemType = mainHandItem.getType();

if (mainHandItemType.isAir() || !player.isSneaking()) return false;
if (mainHandItemType.isAir() || (useNewSkillItemMethod.get() ? false : !player.isSneaking())) return false;

//右键玩家头颅:快速伪装
if (!action.equals(Action.RIGHT_CLICK_BLOCK) && !action.isLeftClick() && morphs.doQuickDisguise(player, false))
return true;

if (mainHandItemType != actionItem || state == null) return false;
if (!isItemASkillItem(actionItem, mainHandItem) || state == null) return false;

//激活技能或取消伪装
if (action.isLeftClick())
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/xiamomc/morph/messages/CommandStrings.java
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ public static FormattableMessage goingToPlayAnimation()
"即将播放动画 <italic><what></italic>");
}

public static FormattableMessage grantItemSuccess()
{
return getFormattable(getKey("grant_item_success"), "[Fallback] 成功给与物品。如果没有请检查是否背包已满");
}

private static String getKey(String key)
{
return "commands." + key;
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/xiamomc/morph/utilities/ItemUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mojang.serialization.JsonOps;
import net.minecraft.core.component.DataComponents;
import net.minecraft.world.item.component.CustomData;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xiamomc.morph.MorphPlugin;

public class ItemUtils
Expand Down Expand Up @@ -73,6 +76,30 @@ public static String itemToStr(ItemStack stack)
}
}

public static final String SKILL_ACTIVATE_ITEM_KEY = "feathermorph:is_skill_item";

public static ItemStack buildSkillItemFrom(ItemStack stack)
{
var nms = net.minecraft.world.item.ItemStack.fromBukkitCopy(stack);
var customData = nms.getComponents().get(DataComponents.CUSTOM_DATA);
if (customData == null) customData = CustomData.EMPTY;

customData = customData.update(tag -> tag.putBoolean(SKILL_ACTIVATE_ITEM_KEY, true));
nms.set(DataComponents.CUSTOM_DATA, customData);

return nms.asBukkitMirror();
}

public static boolean isSkillActivateItem(ItemStack stack)
{
var nms = net.minecraft.world.item.ItemStack.fromBukkitCopy(stack);
var customData = nms.getComponents().get(DataComponents.CUSTOM_DATA);

if (customData == null || !customData.contains(SKILL_ACTIVATE_ITEM_KEY)) return false;

return customData.copyTag().getBoolean(SKILL_ACTIVATE_ITEM_KEY);
}

/**
* Check if the given {@link Material} is a continuous usable type (have consuming animation).
* @param type {@link Material}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/assets/feathermorph/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"commands.not_disguised": "<red>You're not disguised!",
"commands.no_such_animation": "<red>No such animation",
"commands.going_to_play_animation": "Going to play animation <italic><what></italic>",
"commands.grant_item_success": "Successfully grant item. If the item is not found please check if the inventory is full.",
"common.command_not_found": "<color:red>Command not found",
"common.player_not_defined": "<color:red>No player specified",
"common.player_not_found": "<color:red>No such player or they are offline",
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/assets/feathermorph/lang/zh_cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"commands.not_disguised": "<red>你没有进行伪装!",
"commands.no_such_animation": "<red>此动画不可用",
"commands.going_to_play_animation": "即将播放动作 <italic><what></italic>",
"commands.grant_item_success": "成功给与物品。如果没有请检查是否背包已满",
"common.command_not_found" : "<color:red>未找到此指令",
"common.player_not_defined" : "<color:red>未指定玩家",
"common.player_not_found" : "<color:red>未找到目标玩家或对方已离线",
Expand Down
16 changes: 15 additions & 1 deletion src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,22 @@ root:

# Skill item
# Defines which item should players use to disguise/undisguise or activate skills.
#
# ATTENTION! This will do nothing if `skill_item_use_component_detection` is enabled.
skill_item: minecraft:feather

# Use item component to detect skill items
# Once enabled, players will ONLY need to use the item to activate their disguise skill, no need to sneak!
# This could make skill activation easier for players without using client mods.
#
# In order to make an item a "Skill item", add `"feathermorph:is_skill_item": true` to the item's custom data
#
# For example, to give yourself a feather as a skill item:
# /give @s minecraft:feather[minecraft:custom_data={"feathermorph:is_skill_item": true}]
# Or:
# /fm disguise_item minecraft:feather
skill_item_use_component_detection: true

# Should we make Armor Stand disguises show arms by default?
armorstand_show_arms: true

Expand Down Expand Up @@ -347,4 +361,4 @@ root:
- SelectedItem

# Do not touch unless you know what you're doing!
version: 35
version: 36

0 comments on commit 861636a

Please sign in to comment.