forked from Clones/Controlify
Only allow handpicked bindings for radial menu (and all modded binds) with hand-picked icons for all.
This commit is contained in:
@ -3,12 +3,14 @@ package dev.isxander.controlify.api.bind;
|
||||
import com.google.gson.JsonObject;
|
||||
import dev.isxander.controlify.bindings.BindContext;
|
||||
import dev.isxander.controlify.bindings.IBind;
|
||||
import dev.isxander.controlify.bindings.RadialIcons;
|
||||
import dev.isxander.yacl3.api.Option;
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
@ -70,6 +72,8 @@ public interface ControllerBinding {
|
||||
|
||||
void tick();
|
||||
|
||||
Optional<ResourceLocation> radialIcon();
|
||||
|
||||
record KeyMappingOverride(KeyMapping keyMapping, BooleanSupplier toggleable) {
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
package dev.isxander.controlify.api.bind;
|
||||
|
||||
import dev.isxander.controlify.bindings.BindContext;
|
||||
import dev.isxander.controlify.bindings.ControllerBindingImpl;
|
||||
import dev.isxander.controlify.bindings.GamepadBinds;
|
||||
import dev.isxander.controlify.bindings.IBind;
|
||||
import dev.isxander.controlify.bindings.*;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.controller.ControllerState;
|
||||
import net.minecraft.client.KeyMapping;
|
||||
@ -76,6 +73,8 @@ public interface ControllerBindingBuilder<T extends ControllerState> {
|
||||
|
||||
ControllerBindingBuilder<T> context(BindContext... contexts);
|
||||
|
||||
ControllerBindingBuilder<T> radialCandidate(ResourceLocation icon);
|
||||
|
||||
/**
|
||||
* Specifies are vanilla override for the binding.
|
||||
* Will emulate presses of the vanilla keybind when the controller binding is pressed.
|
||||
|
@ -25,10 +25,7 @@ import net.minecraft.resources.ResourceLocation;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
public class ControllerBindingImpl<T extends ControllerState> implements ControllerBinding {
|
||||
@ -39,13 +36,14 @@ public class ControllerBindingImpl<T extends ControllerState> implements Control
|
||||
private final ResourceLocation id;
|
||||
private final Component name, description, category;
|
||||
private final Set<BindContext> contexts;
|
||||
private final ResourceLocation radialIcon;
|
||||
private final KeyMappingOverride override;
|
||||
|
||||
private static final Map<Controller<?, ?>, Set<IBind<?>>> pressedBinds = new HashMap<>();
|
||||
|
||||
private int fakePressState = 0;
|
||||
|
||||
private ControllerBindingImpl(Controller<T, ?> controller, IBind<T> defaultBind, ResourceLocation id, KeyMappingOverride vanillaOverride, Component name, Component description, Component category, Set<BindContext> contexts) {
|
||||
private ControllerBindingImpl(Controller<T, ?> controller, IBind<T> defaultBind, ResourceLocation id, KeyMappingOverride vanillaOverride, Component name, Component description, Component category, Set<BindContext> contexts, ResourceLocation icon) {
|
||||
this.controller = controller;
|
||||
this.bind = this.defaultBind = defaultBind;
|
||||
this.renderer = new BindRendererImpl(bind);
|
||||
@ -55,6 +53,7 @@ public class ControllerBindingImpl<T extends ControllerState> implements Control
|
||||
this.description = description;
|
||||
this.category = category;
|
||||
this.contexts = ImmutableSet.copyOf(contexts);
|
||||
this.radialIcon = icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -118,6 +117,11 @@ public class ControllerBindingImpl<T extends ControllerState> implements Control
|
||||
fakePressState = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ResourceLocation> radialIcon() {
|
||||
return Optional.ofNullable(this.radialIcon);
|
||||
}
|
||||
|
||||
public IBind<T> currentBind() {
|
||||
return bind;
|
||||
}
|
||||
@ -233,6 +237,7 @@ public class ControllerBindingImpl<T extends ControllerState> implements Control
|
||||
private Component name = null, description = null, category = null;
|
||||
private KeyMappingOverride override = null;
|
||||
private final Set<BindContext> contexts = new HashSet<>();
|
||||
private ResourceLocation radialIcon = null;
|
||||
|
||||
public ControllerBindingBuilderImpl(Controller<T, ?> controller) {
|
||||
this.controller = controller;
|
||||
@ -290,6 +295,12 @@ public class ControllerBindingImpl<T extends ControllerState> implements Control
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ControllerBindingBuilder<T> radialCandidate(ResourceLocation icon) {
|
||||
this.radialIcon = icon;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ControllerBindingBuilder<T> vanillaOverride(KeyMapping keyMapping, BooleanSupplier toggleable) {
|
||||
this.override = new KeyMappingOverride(keyMapping, toggleable);
|
||||
@ -318,7 +329,7 @@ public class ControllerBindingImpl<T extends ControllerState> implements Control
|
||||
}
|
||||
}
|
||||
|
||||
return new ControllerBindingImpl<>(controller, bind, id, override, name, description, category, contexts);
|
||||
return new ControllerBindingImpl<>(controller, bind, id, override, name, description, category, contexts, radialIcon);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,8 @@ import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.ToggleKeyMapping;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BooleanSupplier;
|
||||
@ -140,6 +142,7 @@ public class ControllerBindings<T extends ControllerState> {
|
||||
.defaultBind(GamepadBinds.A_BUTTON)
|
||||
.category(MOVEMENT_CATEGORY)
|
||||
.context(BindContexts.INGAME)
|
||||
.radialCandidate(RadialIcons.getEffect(MobEffects.JUMP))
|
||||
.build());
|
||||
register(SPRINT = ControllerBindingBuilder.create(controller)
|
||||
.identifier("controlify", "sprint")
|
||||
@ -173,12 +176,14 @@ public class ControllerBindings<T extends ControllerState> {
|
||||
.defaultBind(GamepadBinds.DPAD_DOWN)
|
||||
.category(GAMEPLAY_CATEGORY)
|
||||
.context(BindContexts.INGAME, BindContexts.INVENTORY)
|
||||
.radialCandidate(RadialIcons.getItem(Items.BARRIER))
|
||||
.build());
|
||||
register(DROP_STACK = ControllerBindingBuilder.create(controller)
|
||||
.identifier("controlify", "drop_stack")
|
||||
.defaultBind(new EmptyBind<>())
|
||||
.category(GAMEPLAY_CATEGORY)
|
||||
.context(BindContexts.INGAME)
|
||||
.radialCandidate(RadialIcons.getItem(Items.TNT))
|
||||
.build());
|
||||
register(NEXT_SLOT = ControllerBindingBuilder.create(controller)
|
||||
.identifier("controlify", "next_slot")
|
||||
@ -197,30 +202,35 @@ public class ControllerBindings<T extends ControllerState> {
|
||||
.defaultBind(GamepadBinds.START)
|
||||
.category(GAMEPLAY_CATEGORY)
|
||||
.context(BindContexts.INGAME)
|
||||
.radialCandidate(RadialIcons.getItem(Items.STRUCTURE_VOID))
|
||||
.build());
|
||||
register(INVENTORY = ControllerBindingBuilder.create(controller)
|
||||
.identifier("controlify", "inventory")
|
||||
.defaultBind(GamepadBinds.Y_BUTTON)
|
||||
.category(INVENTORY_CATEGORY)
|
||||
.context(BindContexts.INGAME)
|
||||
.radialCandidate(RadialIcons.getItem(Items.CHEST))
|
||||
.build());
|
||||
register(CHANGE_PERSPECTIVE = ControllerBindingBuilder.create(controller)
|
||||
.identifier("controlify", "change_perspective")
|
||||
.defaultBind(GamepadBinds.BACK)
|
||||
.category(GAMEPLAY_CATEGORY)
|
||||
.context(BindContexts.INGAME)
|
||||
.radialCandidate(RadialIcons.getItem(Items.PAINTING))
|
||||
.build());
|
||||
register(SWAP_HANDS = ControllerBindingBuilder.create(controller)
|
||||
.identifier("controlify", "swap_hands")
|
||||
.defaultBind(GamepadBinds.X_BUTTON)
|
||||
.category(INVENTORY_CATEGORY)
|
||||
.context(BindContexts.INGAME, BindContexts.INVENTORY)
|
||||
.radialCandidate(RadialIcons.getItem(Items.BONE))
|
||||
.build());
|
||||
register(OPEN_CHAT = ControllerBindingBuilder.create(controller)
|
||||
.identifier("controlify", "open_chat")
|
||||
.defaultBind(GamepadBinds.DPAD_UP)
|
||||
.category(MISC_CATEGORY)
|
||||
.context(BindContexts.INGAME)
|
||||
.radialCandidate(RadialIcons.getItem(Items.WRITABLE_BOOK))
|
||||
.vanillaOverride(options.keyChat, () -> false)
|
||||
.build());
|
||||
register(GUI_PRESS = ControllerBindingBuilder.create(controller)
|
||||
@ -282,6 +292,7 @@ public class ControllerBindings<T extends ControllerState> {
|
||||
.defaultBind(GamepadBinds.DPAD_LEFT)
|
||||
.category(GAMEPLAY_CATEGORY)
|
||||
.context(BindContexts.INGAME)
|
||||
.radialCandidate(RadialIcons.getItem(Items.STICK))
|
||||
.vanillaOverride(options.keyPickItem, () -> false)
|
||||
.build());
|
||||
register(TOGGLE_HUD_VISIBILITY = ControllerBindingBuilder.create(controller)
|
||||
@ -289,12 +300,14 @@ public class ControllerBindings<T extends ControllerState> {
|
||||
.defaultBind(new EmptyBind<>())
|
||||
.category(MISC_CATEGORY)
|
||||
.context(BindContexts.INGAME)
|
||||
.radialCandidate(RadialIcons.getEffect(MobEffects.INVISIBILITY))
|
||||
.build());
|
||||
register(SHOW_PLAYER_LIST = ControllerBindingBuilder.create(controller)
|
||||
.identifier("controlify", "show_player_list")
|
||||
.defaultBind(GamepadBinds.DPAD_RIGHT)
|
||||
.category(MISC_CATEGORY)
|
||||
.context(BindContexts.INGAME)
|
||||
.radialCandidate(RadialIcons.getItem(Items.PLAYER_HEAD))
|
||||
.build());
|
||||
register(RADIAL_MENU = ControllerBindingBuilder.create(controller)
|
||||
.identifier("controlify", "radial_menu")
|
||||
@ -520,6 +533,7 @@ public class ControllerBindings<T extends ControllerState> {
|
||||
.name(Component.translatable(keyMapping.getName()))
|
||||
.description(Component.translatable("controlify.custom_binding.vanilla_description").withStyle(ChatFormatting.GRAY))
|
||||
.category(Component.translatable(keyMapping.getCategory()))
|
||||
.radialCandidate(RadialIcons.FABRIC_ICON)
|
||||
.vanillaOverride(keyMapping, toggleOverride)
|
||||
.build();
|
||||
|
||||
|
@ -1,11 +0,0 @@
|
||||
package dev.isxander.controlify.bindings;
|
||||
|
||||
import dev.isxander.controlify.gui.screen.RadialMenuScreen;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public record RadialAction(ResourceLocation binding, ResourceLocation icon) {
|
||||
public static final RadialAction EMPTY = new RadialAction(
|
||||
RadialMenuScreen.EMPTY_ACTION,
|
||||
RadialIcons.EMPTY
|
||||
);
|
||||
}
|
@ -5,15 +5,11 @@ import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.MobEffectTextureManager;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -23,11 +19,19 @@ public final class RadialIcons {
|
||||
private static final Minecraft minecraft = Minecraft.getInstance();
|
||||
|
||||
public static final ResourceLocation EMPTY = new ResourceLocation("controlify", "empty");
|
||||
public static final ResourceLocation FABRIC_ICON = new ResourceLocation("fabricloader", "icon");
|
||||
|
||||
private static final Map<ResourceLocation, Icon> icons = Util.make(() -> {
|
||||
Map<ResourceLocation, Icon> map = new HashMap<>();
|
||||
|
||||
map.put(EMPTY, (graphics, x, y) -> {});
|
||||
map.put(FABRIC_ICON, ((graphics, x, y) -> {
|
||||
graphics.pose().pushPose();
|
||||
graphics.pose().translate(x, y, 0);
|
||||
graphics.pose().scale(0.5f, 0.5f, 1f);
|
||||
graphics.blit(FABRIC_ICON, 0, 0, 0, 0, 32, 32);
|
||||
graphics.pose().popPose();
|
||||
}));
|
||||
addItems(map);
|
||||
addPotionEffects(map);
|
||||
|
||||
@ -38,6 +42,14 @@ public final class RadialIcons {
|
||||
return icons;
|
||||
}
|
||||
|
||||
public static ResourceLocation getItem(Item item) {
|
||||
return prefixLocation("item", BuiltInRegistries.ITEM.getKey(item));
|
||||
}
|
||||
|
||||
public static ResourceLocation getEffect(MobEffect effect) {
|
||||
return prefixLocation("effect", BuiltInRegistries.MOB_EFFECT.getKey(effect));
|
||||
}
|
||||
|
||||
private static void addItems(Map<ResourceLocation, Icon> map) {
|
||||
BuiltInRegistries.ITEM.entrySet().forEach(entry -> {
|
||||
ResourceKey<Item> key = entry.getKey();
|
||||
|
@ -2,7 +2,6 @@ package dev.isxander.controlify.controller;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import dev.isxander.controlify.bindings.RadialAction;
|
||||
import dev.isxander.controlify.gui.screen.RadialMenuScreen;
|
||||
import dev.isxander.controlify.rumble.RumbleSource;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@ -39,15 +38,15 @@ public abstract class ControllerConfig implements Serializable {
|
||||
|
||||
public boolean mixedInput = false;
|
||||
|
||||
public RadialAction[] radialActions = new RadialAction[]{
|
||||
RadialAction.EMPTY,
|
||||
RadialAction.EMPTY,
|
||||
RadialAction.EMPTY,
|
||||
RadialAction.EMPTY,
|
||||
RadialAction.EMPTY,
|
||||
RadialAction.EMPTY,
|
||||
RadialAction.EMPTY,
|
||||
RadialAction.EMPTY,
|
||||
public ResourceLocation[] radialActions = new ResourceLocation[]{
|
||||
RadialMenuScreen.EMPTY_ACTION,
|
||||
RadialMenuScreen.EMPTY_ACTION,
|
||||
RadialMenuScreen.EMPTY_ACTION,
|
||||
RadialMenuScreen.EMPTY_ACTION,
|
||||
RadialMenuScreen.EMPTY_ACTION,
|
||||
RadialMenuScreen.EMPTY_ACTION,
|
||||
RadialMenuScreen.EMPTY_ACTION,
|
||||
RadialMenuScreen.EMPTY_ACTION,
|
||||
};
|
||||
|
||||
public abstract void setDeadzone(int axis, float deadzone);
|
||||
|
@ -2,7 +2,6 @@ package dev.isxander.controlify.gui.screen;
|
||||
|
||||
import dev.isxander.controlify.Controlify;
|
||||
import dev.isxander.controlify.api.bind.ControllerBinding;
|
||||
import dev.isxander.controlify.bindings.RadialAction;
|
||||
import dev.isxander.controlify.bindings.RadialIcons;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.controller.gamepad.GamepadState;
|
||||
@ -36,6 +35,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class RadialMenuScreen extends Screen implements ScreenControllerEventListener {
|
||||
@ -188,15 +188,16 @@ public class RadialMenuScreen extends Screen implements ScreenControllerEventLis
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
RadialAction action = controller.config().radialActions[index];
|
||||
if (!EMPTY_ACTION.equals(action.binding())) {
|
||||
this.binding = controller.bindings().get(action.binding());
|
||||
ResourceLocation binding = controller.config().radialActions[index];
|
||||
if (!EMPTY_ACTION.equals(binding)) {
|
||||
this.binding = controller.bindings().get(binding);
|
||||
this.icon = RadialIcons.getIcons().get(this.binding.radialIcon().orElseThrow());
|
||||
this.name = MultiLineLabel.create(font, this.binding.name(), 76);
|
||||
} else {
|
||||
this.binding = null;
|
||||
this.name = MultiLineLabel.EMPTY;
|
||||
this.icon = RadialIcons.getIcons().get(RadialIcons.EMPTY);
|
||||
}
|
||||
this.icon = RadialIcons.getIcons().get(action.icon());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -305,11 +306,12 @@ public class RadialMenuScreen extends Screen implements ScreenControllerEventLis
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
controller.bindings().registry().forEach((id, binding) -> {
|
||||
children.add(new ActionEntry(id));
|
||||
});
|
||||
controller.bindings().registry().entrySet().stream()
|
||||
.filter(entry -> entry.getValue().radialIcon().isPresent())
|
||||
.map(Map.Entry::getKey)
|
||||
.forEach(id -> children.add(new ActionEntry(id)));
|
||||
|
||||
var selectedBind = controller.config().radialActions[radialIndex].binding();
|
||||
var selectedBind = controller.config().radialActions[radialIndex];
|
||||
children.stream()
|
||||
.filter(action -> action.binding.equals(selectedBind))
|
||||
.findAny()
|
||||
@ -447,8 +449,7 @@ public class RadialMenuScreen extends Screen implements ScreenControllerEventLis
|
||||
public boolean overrideControllerButtons(ScreenProcessor<?> screen, Controller<?, ?> controller) {
|
||||
if (controller == RadialMenuScreen.this.controller) {
|
||||
if (controller.bindings().GUI_PRESS.justPressed()) {
|
||||
var icon = RadialIcons.getIcons().keySet().toArray(new ResourceLocation[0])[minecraft.level.random.nextInt(RadialIcons.getIcons().size())];
|
||||
controller.config().radialActions[radialIndex] = new RadialAction(binding, icon);
|
||||
controller.config().radialActions[radialIndex] = binding;
|
||||
Controlify.instance().config().setDirty();
|
||||
|
||||
playClickSound();
|
||||
|
Reference in New Issue
Block a user