Skip to content

Commit

Permalink
Allows command rune run some command after a delay.
Browse files Browse the repository at this point in the history
Took 3 hours 36 minutes
  • Loading branch information
xkball committed Nov 7, 2024
1 parent 9accbd6 commit ec363ed
Show file tree
Hide file tree
Showing 16 changed files with 354 additions and 81 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ mod_name=Power Tool
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=GPL-3.0
# The mod version. See https://semver.org/
mod_version=1.4.20
mod_version=1.4.21
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ public void appendHoverText(ItemStack stack, Item.TooltipContext context, List<C
}

@Override
@SuppressWarnings("deprecation")
public RenderShape getRenderShape(BlockState pState) {
return RenderShape.MODEL;
}
Expand Down Expand Up @@ -130,8 +129,9 @@ protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Lev
}
return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
}

@Override
@SuppressWarnings("deprecation")
public ItemStack getCloneItemStack(LevelReader level, BlockPos pos, BlockState state) {
if (level.getBlockEntity(pos) instanceof ItemDisplayBlockEntity theBE) {
return theBE.itemToDisplay.copyWithCount(1);
Expand All @@ -140,13 +140,11 @@ public ItemStack getCloneItemStack(LevelReader level, BlockPos pos, BlockState s
}

@Override
@SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}

@Override
@SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState state, Level level, BlockPos pos) {
if (level.getBlockEntity(pos) instanceof ItemDisplayBlockEntity theBE) {
return theBE.itemToDisplay.isEmpty() ? 0 : theBE.rotation / 45 + 1;
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/org/teacon/powertool/block/PowerToolBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
import org.teacon.powertool.block.entity.TrashCanWithContainerBlockEntity;
import org.teacon.powertool.block.holo_sign.HolographicSignBlock;
import org.teacon.powertool.block.holo_sign.SignType;
import org.teacon.powertool.item.PowerToolItems;
import org.teacon.powertool.item.PowerToolDataComponents;

import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -277,10 +277,10 @@ public static void register(IEventBus bus) {
ITEMS.register("mechanical_register", () -> new BlockItem(MECHANICAL_REGISTER.get(), new Item.Properties()));
ITEMS.register("tech_register", () -> new BlockItem(TECH_REGISTER.get(), new Item.Properties()));
ITEMS.register("temple", () -> new BlockItem(TEMPLE.get(), new Item.Properties()));
ITEMS.register("safe", () -> new BlockItem(SAFE.get(), new Item.Properties().component(PowerToolItems.COMMAND, "/ac safe")));
ITEMS.register("gorgeous_safe", () -> new BlockItem(GORGEOUS_SAFE.get(), new Item.Properties().component(PowerToolItems.COMMAND, "/ac safe")));
ITEMS.register("mechanical_safe", () -> new BlockItem(MECHANICAL_SAFE.get(), new Item.Properties().component(PowerToolItems.COMMAND, "/ac safe")));
ITEMS.register("tech_safe", () -> new BlockItem(TECH_SAFE.get(), new Item.Properties().component(PowerToolItems.COMMAND, "/ac safe")));
ITEMS.register("safe", () -> new BlockItem(SAFE.get(), new Item.Properties().component(PowerToolDataComponents.COMMAND, "/ac safe")));
ITEMS.register("gorgeous_safe", () -> new BlockItem(GORGEOUS_SAFE.get(), new Item.Properties().component(PowerToolDataComponents.COMMAND, "/ac safe")));
ITEMS.register("mechanical_safe", () -> new BlockItem(MECHANICAL_SAFE.get(), new Item.Properties().component(PowerToolDataComponents.COMMAND, "/ac safe")));
ITEMS.register("tech_safe", () -> new BlockItem(TECH_SAFE.get(), new Item.Properties().component(PowerToolDataComponents.COMMAND, "/ac safe")));
ITEMS.register("observer_realtime",() -> new BlockItem(REAL_TIME_OBSERVER.get(), new Item.Properties()));
ITEMS.register("observer_realtime_cyl",() -> new BlockItem(REAL_TIME_CYCLE_OBSERVER.get(),new Item.Properties()));
ITEMS.register("observer_gametime_cyl",() -> new BlockItem(GAME_TIME_CYCLE_OBSERVER.get(), new Item.Properties()));
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/teacon/powertool/block/SafeBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.phys.BlockHitResult;
import org.teacon.powertool.block.entity.SafeBlockEntity;
import org.teacon.powertool.item.PowerToolItems;
import org.teacon.powertool.item.PowerToolDataComponents;

public class SafeBlock extends BaseEntityBlock {

Expand Down Expand Up @@ -68,7 +68,7 @@ public BlockState getStateForPlacement(BlockPlaceContext context) {
@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
if (level.getBlockEntity(pos) instanceof SafeBlockEntity theSafe) {
String cmd = theSafe.components().getOrDefault(PowerToolItems.COMMAND.get(), "/ac safe");
String cmd = theSafe.components().getOrDefault(PowerToolDataComponents.COMMAND.get(), "/ac safe");
var server = level.getServer();
if (server != null) {
server.getCommands().performPrefixedCommand(player.createCommandSourceStack(), cmd);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import net.neoforged.neoforge.network.PacketDistributor;
import org.teacon.powertool.datagen.PowerToolBlockTagsProvider;
import org.teacon.powertool.item.ExamineHoloGlass;
import org.teacon.powertool.item.PowerToolItems;
import org.teacon.powertool.item.PowerToolDataComponents;
import org.teacon.powertool.network.server.UpdateItemStackData;

import javax.annotation.Nullable;
Expand Down Expand Up @@ -73,8 +73,8 @@ protected Checkbox.OnValueChange withTag(TagKey<Block> tag) {
@Override
public void removed() {
var patch = DataComponentPatch.builder()
.set(PowerToolItems.BLOCK_TAGS_DATA.get(),new ExamineHoloGlass.BlockTagsComponent(new ArrayList<>(tagsData)))
.set(PowerToolItems.BLOCKS_DATA.get(),new ExamineHoloGlass.BlockComponents(new ArrayList<>(blocksData)))
.set(PowerToolDataComponents.BLOCK_TAGS_DATA.get(),new ExamineHoloGlass.BlockTagsComponent(new ArrayList<>(tagsData)))
.set(PowerToolDataComponents.BLOCKS_DATA.get(),new ExamineHoloGlass.BlockComponents(new ArrayList<>(blocksData)))
.build();
PacketDistributor.sendToServer(new UpdateItemStackData(slot,patch));
}
Expand Down
74 changes: 64 additions & 10 deletions src/main/java/org/teacon/powertool/client/gui/SetCommandScreen.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.teacon.powertool.client.gui;

import com.mojang.datafixers.util.Pair;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.Checkbox;
import net.minecraft.client.gui.screens.Screen;
Expand All @@ -11,17 +13,29 @@
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.network.PacketDistributor;
import org.teacon.powertool.client.gui.widget.DelayCommandList;
import org.teacon.powertool.client.gui.widget.ObjectInputBox;
import org.teacon.powertool.item.PowerToolItems;
import org.teacon.powertool.item.CommandRune;
import org.teacon.powertool.item.PowerToolDataComponents;
import org.teacon.powertool.network.server.UpdateItemStackData;

import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@ParametersAreNonnullByDefault
public class SetCommandScreen extends Screen {

protected final ItemStack itemStack;
protected final EquipmentSlot slot;
protected ObjectInputBox<String> name;
protected ObjectInputBox<String> input;
protected Checkbox consume;
protected Button appendCommand;
protected DelayCommandList commandList;
protected Button closeButton;
public final List<CommandRune.DelayedCommandData> delayedCommands = new ArrayList<>();

public SetCommandScreen(ItemStack stack, EquipmentSlot slot) {
super(Component.translatable("powertool.setcommand.gui"));
Expand All @@ -33,18 +47,28 @@ public SetCommandScreen(ItemStack stack, EquipmentSlot slot) {
protected void init() {
var mc = Minecraft.getInstance();
var font = mc.font;
this.addRenderableWidget(new Button.Builder(CommonComponents.GUI_DONE, btn -> this.onDone())
.pos(this.width / 2 - 100, this.height / 4 + 120)
.size(200, 20).build());
var box_l = (int)Math.max(100,width*0.4);
this.name = new ObjectInputBox<>(font,width/2-box_l/2,height/2-60,box_l,20,Component.literal("name"),ObjectInputBox.PASS_VALIDATOR,ObjectInputBox.PASS_RESPONDER);
var startY = (int)(height*0.15);
delayedCommands.clear();
if(itemStack.has(PowerToolDataComponents.DELAYED_COMMANDS)) delayedCommands.addAll(Objects.requireNonNull(itemStack.get(PowerToolDataComponents.DELAYED_COMMANDS)));
this.name = new ObjectInputBox<>(font,width/2-box_l/2,startY,box_l,20,Component.literal("name"),ObjectInputBox.PASS_VALIDATOR,ObjectInputBox.PASS_RESPONDER);
this.name.setMaxLength(114514);
this.name.setRenderState(false);
this.input = new ObjectInputBox<>(font,width/2-box_l/2,height/2-35,box_l,20,Component.literal("command"),ObjectInputBox.PASS_VALIDATOR,ObjectInputBox.PASS_RESPONDER);
this.input = new ObjectInputBox<>(font,width/2-box_l/2,startY+25,box_l,20,Component.literal("command"),ObjectInputBox.PASS_VALIDATOR,ObjectInputBox.PASS_RESPONDER);
this.input.setMaxLength(114514);
this.input.setRenderState(false);
this.consume = Checkbox.builder(Component.literal("consumable"),font).pos(width/2-box_l/2,height/2-10).selected(Boolean.TRUE.equals(itemStack.get(PowerToolItems.CONSUME))).build();
String command = itemStack.get(PowerToolItems.COMMAND);
this.appendCommand = Button.builder(Component.literal("+"),(b) -> {
if(this.commandList != null) commandList.appendEntry();
this.refreshContentPos();
}).size(20,20).pos(width/2+box_l/2-25,startY+52).build();
this.commandList = new DelayCommandList(this,box_l,startY+50);
var listEndY = startY+50+commandList.getHeight_();
this.consume = Checkbox.builder(Component.literal("consumable"),font).pos(width/2-box_l/2, listEndY+5).selected(Boolean.TRUE.equals(itemStack.get(PowerToolDataComponents.CONSUME))).build();
this.closeButton = new Button.Builder(CommonComponents.GUI_DONE, btn -> this.onDone())
.pos((int) (this.width / 2f - box_l*0.3f), listEndY+30)
.size((int) (box_l*0.6), 20).build();

String command = itemStack.get(PowerToolDataComponents.COMMAND);
if (command != null) {
this.input.setValue(command);
}
Expand All @@ -53,9 +77,28 @@ protected void init() {
this.addRenderableWidget(this.name);
this.addRenderableWidget(this.input);
this.addRenderableWidget(this.consume);
this.addRenderableWidget(this.commandList);
this.addRenderableWidget(this.appendCommand);
this.addRenderableWidget(this.closeButton);
super.init();
}

public void refreshContentPos(){
var startY = (int)(height*0.15);
this.commandList.resize();
var listEndY = startY+50+commandList.getHeight_();
this.consume.setPosition(consume.getX(), listEndY+5);
this.closeButton.setPosition(closeButton.getX(), listEndY+30);
refreshDelayedCommandsFromList();
}

public void refreshDelayedCommandsFromList(){
this.delayedCommands.clear();
for(var entry : this.commandList.entries()){
delayedCommands.add(new CommandRune.DelayedCommandData(entry.delay(),entry.command()));
}
}

protected void onDone() {
if (this.minecraft != null) {
this.minecraft.setScreen(null);
Expand All @@ -65,9 +108,20 @@ protected void onDone() {
@Override
public void removed() {
if(input == null || name == null || consume == null) return;
refreshDelayedCommandsFromList();
var patch = DataComponentPatch.builder().set(DataComponents.CUSTOM_NAME,Component.literal(name.getValue()));
if(!input.getValue().isEmpty()) patch.set(PowerToolItems.COMMAND.get(),input.getValue());
patch.set(PowerToolItems.CONSUME.get(),consume.selected());
if(!input.getValue().isEmpty()) patch.set(PowerToolDataComponents.COMMAND.get(),input.getValue());
patch.set(PowerToolDataComponents.CONSUME.get(),consume.selected());
patch.set(PowerToolDataComponents.DELAYED_COMMANDS.get(),delayedCommands);
PacketDistributor.sendToServer(new UpdateItemStackData(slot,patch.build()));
}

@Override
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
super.render(guiGraphics, mouseX, mouseY, partialTick);
var box_l = (int)Math.max(100,width*0.4);
var startY = (int)(height*0.15);
var text = "delayed commands";
guiGraphics.drawString(font,text,width/2-box_l/2-font.width(text)-2,startY+52,0xFFFFFF);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package org.teacon.powertool.client.gui.widget;

import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.network.chat.Component;
import org.teacon.powertool.client.gui.SetCommandScreen;

import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class DelayCommandList extends ContainerObjectSelectionList<DelayCommandList.CommandEntry> {

private final SetCommandScreen screen;
private int id = 0;

public DelayCommandList(SetCommandScreen screen,int width,int y) {
super(Minecraft.getInstance(), width,100,y,45);
this.screen = screen;
this.setX((int) (screen.width*0.3));
this.setRenderHeader(true,24);
for(var data : screen.delayedCommands){
this.addEntry(new CommandEntry(id,data.delay(), data.command()));
id++;
}
this.resize();
//this.addEntry(new AppendEntry());
}

public void resize(){
this.setHeight(getHeight_());
this.updateSizeAndPosition(width,height,getY());
this.setX((int) (screen.width*0.3));
}

public int getHeight_(){
return (int) Math.min(Math.max(100,24+45*id),screen.height*0.6);
}

public List<CommandEntry> entries(){
return children();
}

public void appendEntry(){
this.addEntry(new CommandEntry(id,0,""));
id++;
}

public void removeEntry(int id){
var newEntries = new ArrayList<CommandEntry>();
int nid = 0;
for(var entry : children()){
if(entry.id!=id){
newEntries.add(new CommandEntry(nid, entry.delay(),entry.command()));
nid++;
}
}
this.replaceEntries(newEntries);
screen.refreshContentPos();
}

@Override
public int getRowWidth() {
return width-4;
}


public class CommandEntry extends ContainerObjectSelectionList.Entry<CommandEntry> {
public final int id;
public final ObjectInputBox<Integer> delay_;
public final ObjectInputBox<String> command_;
protected final Button remove;

public CommandEntry(int id,int delay,String command) {
this.id = id;
var box_l = (int)Math.max(100,DelayCommandList.this.screen.width*0.4);
this.delay_ = new ObjectInputBox<>(Minecraft.getInstance().font,-1,-1,(box_l-20)/2,20,Component.literal("delay"),ObjectInputBox.INT_VALIDATOR,ObjectInputBox.INT_RESPONDER);
this.delay_.setMaxLength(4);
this.delay_.setValue(String.valueOf(delay));
this.command_ = new ObjectInputBox<>(Minecraft.getInstance().font,-1,-1,box_l-20,20,Component.literal("command"),ObjectInputBox.PASS_VALIDATOR,ObjectInputBox.PASS_RESPONDER);
this.command_.setMaxLength(114514);
this.command_.setRenderState(false);
this.command_.setValue(command);
this.remove = Button.builder(Component.literal("-"),(b) -> {
DelayCommandList.this.removeEntry(id);
} ).size(20,20).build();
}


@Override
public List<? extends NarratableEntry> narratables() {
return List.of(delay_,command_,remove);
}

@Override
public void render(GuiGraphics guiGraphics, int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean hovering, float partialTick) {
var sx = DelayCommandList.this.getX();
this.delay_.setPosition(sx+20,top);
this.delay_.render(guiGraphics, mouseX, mouseY, partialTick);
this.command_.setPosition(sx+20,top+20);
this.command_.render(guiGraphics, mouseX, mouseY, partialTick);
this.remove.setPosition(sx+DelayCommandList.this.getWidth()-50,top);
this.remove.render(guiGraphics, mouseX, mouseY, partialTick);
}

@Override
public List<? extends GuiEventListener> children() {
return List.of(delay_,command_,remove);
}

public int delay(){
return Objects.requireNonNullElse(this.delay_.get(),0);
}

public String command(){
return Objects.requireNonNullElse(this.command_.get(),"");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ public T get(){
@Override
public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
super.renderWidget(guiGraphics, mouseX, mouseY, partialTick);
var font = Minecraft.getInstance().font;
var rec = guiGraphics.scissorStack.stack.isEmpty() ? null : guiGraphics.scissorStack.stack.peekLast();
if(rec != null){
guiGraphics.disableScissor();
guiGraphics.enableScissor(rec.position().x()-100, rec.position().y(), rec.position().x()+rec.width(), rec.position().y()+rec.height());
}
if (this.visible) {
if(renderState){
if(validator.test(getValue())) {
Expand All @@ -115,10 +121,13 @@ public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float
}
var title = this.getMessage().getString();
if(!title.isEmpty()){
var font = Minecraft.getInstance().font;
guiGraphics.drawString(font,title,getX()-font.width(title)-(renderState?12:2),getY()+2,0xFFFFFF);
}
}
if(rec != null){
guiGraphics.disableScissor();
guiGraphics.enableScissor(rec.position().x(), rec.position().y(), rec.position().x()+rec.width(), rec.position().y()+rec.height());
}
}

public boolean isRenderState() {
Expand Down
Loading

0 comments on commit ec363ed

Please sign in to comment.