diff --git a/src/main/java/jesse/keeblarcraft/Callbacks/MobSpawnCallback.java b/src/main/java/jesse/keeblarcraft/Callbacks/MobSpawnCallback.java new file mode 100644 index 0000000..9505a1c --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/Callbacks/MobSpawnCallback.java @@ -0,0 +1,24 @@ +package jesse.keeblarcraft.Callbacks; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.entity.mob.MobEntity; +import net.minecraft.util.ActionResult; +import net.minecraft.world.World; + +public interface MobSpawnCallback { + Event EVENT = EventFactory.createArrayBacked(MobSpawnCallback.class, + (listeners) -> (world, mob) -> { + for (MobSpawnCallback listener : listeners) { + ActionResult result = listener.interact(world, mob); + + if (result != ActionResult.PASS) { + return result; + } + } + + return ActionResult.PASS; + }); + + ActionResult interact(World world, MobEntity mob); +} diff --git a/src/main/java/jesse/keeblarcraft/ChatStuff/ChatMenu.java b/src/main/java/jesse/keeblarcraft/ChatStuff/ChatMenu.java index 54a6454..5efc12d 100644 --- a/src/main/java/jesse/keeblarcraft/ChatStuff/ChatMenu.java +++ b/src/main/java/jesse/keeblarcraft/ChatStuff/ChatMenu.java @@ -5,18 +5,27 @@ import java.util.List; import jesse.keeblarcraft.ChatStuff.ChatFormatting.COLOR_CODE; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.MutableText; import net.minecraft.text.Text; // Create a "chat menu" which is just a menu in chat with pages that a user can click to display // the next page. public class ChatMenu { - private List msgList = new ArrayList<>(); + private ArrayList msgList = new ArrayList<>(); private Text header; + private Text headerFooterSpacing = Text.of(" "); private Text leftArrow; private Text rightArrow; - private int pageLimit = 5; // Messages per page in this menu + private int pageLimit = 25; // Messages per page in this menu (//TODO: This is being increased to show all info at once. Need to add callback to flip a page somehow) private int pageCount = 1; // Calculated at runtime private ChatMsg formatter = new ChatMsg(); + private int currentPage = 0; + ServerPlayerEntity lastTarget; + + private enum TURN_DIRECTION { + BACK, + FORWARD + } public ChatMenu() { // Initialize default header and arrows @@ -35,7 +44,7 @@ public class ChatMenu { } public void SetHeader(ChatMsg msg) { - this.header = msg.regularText; + this.header = msg.mutableText; } public void SetLeftArrow(Text leftArrow) { @@ -46,6 +55,57 @@ public class ChatMenu { this.rightArrow = rightArrow; } + private Text MakeFooter() { + // leftArrow = (Text) formatter.MakeClickCallback((MutableText) leftArrow, new ChatMsgClickEvent(() -> TurnPage(TURN_DIRECTION.BACK))); + // leftArrow = Text.literal("TEST").styled(style -> style.withClickEvent(new ChatMsgClickEvent(() -> { + // System.out.println("Click event called from server"); + // }))); + + MutableText footer = (MutableText) leftArrow; + + // This spacing is arbitrary and may be changed in future. It just looks OK for now + footer.append(Text.of(" ")); + + // rightArrow = formatter.MakeClickCallback((MutableText) rightArrow, new ChatMsgClickEvent(() -> TurnPage(TURN_DIRECTION.FORWARD))); + footer.append(rightArrow); + + return (Text) footer; + } + + private void TurnPage(TURN_DIRECTION turn) { + System.out.println("TurnPage called"); + // The page we need to turn to will be calculated as so: + // msgList[index] where index = (0 + pageLimit) * currentPage(+- 1) + pageCount = (int) Math.ceil(msgList.size() / (double) pageLimit); + + // Guard clause: Cannot turn further than end of all pages or before page 1 + if ((turn == TURN_DIRECTION.BACK && currentPage == 1) || (turn == TURN_DIRECTION.FORWARD && currentPage == pageCount)) { + return; + } + + // Adjust new page number + if (turn == TURN_DIRECTION.BACK) { + --currentPage; + } else { + ++currentPage; + } + + // Send updated message to player (msg takes care of printing page) + if (lastTarget != null) { + SendMsg(lastTarget); + } + } + + private Text MakeHeader() { + MutableText head = (MutableText) Text.of(" "); + head.append(header); + head.append(Text.of(" ")); + + header = (Text) head; + + return header; + } + public void AddMsg(Text newMsg) { msgList.add(newMsg); } @@ -55,7 +115,17 @@ public class ChatMenu { } public void AddMsg(ChatMsg newMsg) { - AddMsg(newMsg.regularText); + AddMsg(newMsg.mutableText); + } + + public void AddMsg(List newMsgList) { + for (int i = 0; i < newMsgList.size(); i++) { + AddMsg(newMsgList.get(i)); + } + } + + public void AddNewLine() { + AddMsg(Text.of("")); } public void ClearList() { @@ -69,23 +139,48 @@ public class ChatMenu { } } + // Prints the current page public void SendMsg(ServerPlayerEntity target) { // Calculate number of pages pageCount = (int) Math.ceil(msgList.size() / (double) pageLimit); + int startIdx = currentPage * pageLimit; // Send the header - target.sendMessage(header); - target.sendMessage(Text.of("")); // Spacer + target.sendMessage(MakeHeader()); + int maxCapoutDebug = 20; - // Send the body - int msgIndex = 0; - for (int page = 0; page < pageCount; page++) { - for (int i = 0; i < pageLimit; i++) { - target.sendMessage(msgList.get(msgIndex++)); + int stopIdx = startIdx + pageLimit; + for (int pageItem = startIdx; pageItem < stopIdx && pageItem < msgList.size(); pageItem++) { + target.sendMessage(msgList.get(pageItem)); + + --maxCapoutDebug; + + if (maxCapoutDebug <= 0) { + break; } } + // Send the body + // int msgIndex = 0; + // for (int page = 0; page < pageCount && msgList.get(msgIndex) != null; page++) { + // for (int i = 0; i < pageLimit && msgList.get(msgIndex) != null; i++) { + // Text msg = msgList.get(msgIndex); + // if (msg == null) { + // target.sendMessage(msg); + // } + // } + // } + // Send the footer - // target.sendMessage(footer); + target.sendMessage(MakeFooter()); + + // ChatMsg temp = new ChatMsg(); + // Text test = (Text) temp.MakeCopyableTxt("<<", "Click to copy", "Copied string"); + // Text test2 = (Text) temp.MakeCopyableTxt(">>", "Click to copy", "Copied"); + + // MutableText temp3 = (MutableText) test; + // temp3.append(test2); + + // target.sendMessage((Text) temp3); } } diff --git a/src/main/java/jesse/keeblarcraft/ChatStuff/ChatMsg.java b/src/main/java/jesse/keeblarcraft/ChatStuff/ChatMsg.java index 087387e..6b5c95d 100644 --- a/src/main/java/jesse/keeblarcraft/ChatStuff/ChatMsg.java +++ b/src/main/java/jesse/keeblarcraft/ChatStuff/ChatMsg.java @@ -19,9 +19,8 @@ import net.minecraft.text.Style; import net.minecraft.text.Text; public class ChatMsg { - // May be null; store last message of each type so class can be referenced as object - MutableText mutableText; - Text regularText; + public Text regularText = Text.of(""); + public MutableText mutableText = (MutableText) regularText; ///////////////////////////////////////////////////////////////////////////// /// @fn MakeCopyableTxt /// @@ -71,6 +70,11 @@ public class ChatMsg { return MakeCopyableTxt(terminalTxt, hoverTxt, expanded); } + // public MutableText MakeClickCallback(MutableText text, ChatMsgClickEvent callback) { + // text.styled(style -> style.withClickEvent(callback)); + // return text; + // } + ///////////////////////////////////////////////////////////////////////////// /// @fn MakeCopyableTxt /// @@ -88,15 +92,11 @@ public class ChatMsg { public MutableText MakeCopyableTxt(String terminalTxt, String hoverTxt, String copyStr) { Text copyableText = Text.of(terminalTxt); MutableText testTxt = (MutableText) copyableText; - System.out.println("Making hoverable stuff"); testTxt.setStyle(Style.EMPTY.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, copyStr)) .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of(hoverTxt)))); - System.out.println("Done making hoverable stuff"); - - System.out.println("Value of copyAbleText: " + copyableText.getString()); - System.out.println("Value of testTxt: " + testTxt.getString()); mutableText = testTxt; + regularText = copyableText; return testTxt; } @@ -114,6 +114,8 @@ public class ChatMsg { /// @return Formatted string of colored text ///////////////////////////////////////////////////////////////////////////// public String ColorMsg(Integer msg, COLOR_CODE color) { + regularText = Text.of(ChatFormatting.GetColor(color) + msg + ChatFormatting.COLOR_END); + mutableText = (MutableText) regularText; return ChatFormatting.GetColor(color) + msg + ChatFormatting.COLOR_END; } @@ -136,6 +138,7 @@ public class ChatMsg { ///////////////////////////////////////////////////////////////////////////// public Text ColorMsg(Text msg, COLOR_CODE color) { regularText = Text.of(ChatFormatting.GetColor(color) + msg.getString() + ChatFormatting.COLOR_END); + mutableText = (MutableText) regularText; return regularText; } diff --git a/src/main/java/jesse/keeblarcraft/Commands/FactionCommands.java b/src/main/java/jesse/keeblarcraft/Commands/FactionCommands.java index 37b0ef6..86d6997 100644 --- a/src/main/java/jesse/keeblarcraft/Commands/FactionCommands.java +++ b/src/main/java/jesse/keeblarcraft/Commands/FactionCommands.java @@ -259,7 +259,9 @@ public class FactionCommands { // Returns information on the players current faction private int GetFactionInformation(ServerPlayerEntity player) { + System.out.println("GETTING FACTION INFO"); FactionManager.GetInstance().GetFactionInformation(player); + System.out.println("ENDING FACTION INFO"); return 0; } diff --git a/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockEntities/FactionBlockEntity.java b/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockEntities/FactionBlockEntity.java index 524d868..1703158 100644 --- a/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockEntities/FactionBlockEntity.java +++ b/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockEntities/FactionBlockEntity.java @@ -3,6 +3,7 @@ package jesse.keeblarcraft.CustomBlocks.BlockEntities; import java.util.ArrayList; import jesse.keeblarcraft.AttributeMgr.AttributeMgr; +import jesse.keeblarcraft.Callbacks.MobSpawnCallback; import jesse.keeblarcraft.FactionMgr.FactionManager; import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerEnteredBaseCallback; import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerExitedBaseCallback; @@ -14,6 +15,7 @@ import jesse.keeblarcraft.world.ImplementedInventory; import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventories; @@ -50,6 +52,12 @@ public class FactionBlockEntity extends BlockEntity implements ExtendedScreenHan public FactionBlockEntity(BlockPos pos, BlockState state, String faction) { this(pos, state); this.faction = faction; + + System.out.println("Subscribing to mob spawning"); + MobSpawnCallback.EVENT.register((world, mob) -> { + HandleMobSpawn(world, mob); + return ActionResult.PASS; + }); } public void SetFaction(String faction) { @@ -84,6 +92,15 @@ public class FactionBlockEntity extends BlockEntity implements ExtendedScreenHan }; } + // TODO: Make sure mobs are within range before targeting! + private void HandleMobSpawn(World world, MobEntity mob) { + if (world.isClient()) { + return; + } + + mob.kill(); + } + @Override public Text getDisplayName() { return Text.literal("Faction Home Base Station"); // Replace with proper en_us format later diff --git a/src/main/java/jesse/keeblarcraft/FactionMgr/FactionConfig.java b/src/main/java/jesse/keeblarcraft/FactionMgr/FactionConfig.java index b1e59ae..280d5ee 100644 --- a/src/main/java/jesse/keeblarcraft/FactionMgr/FactionConfig.java +++ b/src/main/java/jesse/keeblarcraft/FactionMgr/FactionConfig.java @@ -360,10 +360,8 @@ public class FactionConfig { public String FindFactionOfPlayer(String playerUuid) { String faction = ""; - System.out.println("Attempting to find player factions with uuid " + playerUuid); for (Entry entry : allFactions.entrySet()) { if (entry.getValue().factionPlayerList.containsKey(playerUuid)) { - System.out.println("FAC [" + entry.getKey() + "]: PLAY-LIST: " + entry.getValue().factionPlayerList); faction = entry.getKey(); break; } diff --git a/src/main/java/jesse/keeblarcraft/FactionMgr/FactionManager.java b/src/main/java/jesse/keeblarcraft/FactionMgr/FactionManager.java index 9a80288..08612d6 100644 --- a/src/main/java/jesse/keeblarcraft/FactionMgr/FactionManager.java +++ b/src/main/java/jesse/keeblarcraft/FactionMgr/FactionManager.java @@ -95,27 +95,25 @@ public class FactionManager { System.out.println((fPower == null ? "YES":"NO") + " " + (displayNames == null ? "YES":"NO") + " " + (fBankBalance == null ? "YES":"NO")); - ArrayList nameMapToList = new ArrayList(); - ChatMsg chatPlayerList = new ChatMsg(); + ArrayList chatPlayerList = new ArrayList<>(); for (Entry entry : displayNames.entrySet()) { - nameMapToList.add(chatPlayerList.ColorMsg(entry.getKey() + " - " + entry.getValue().name(), COLOR_CODE.BLUE)); + ChatMsg temp = new ChatMsg(); + temp.ColorMsg(entry.getKey() + " - " + entry.getValue().name(), COLOR_CODE.BLUE); + chatPlayerList.add(temp); } - System.out.println("name map null? " + nameMapToList == null ? "YES":"NO"); - // Let's make our chat objects first so things are copyable and whatnot ChatMsg chatHeader = new ChatMsg(); - chatHeader.ColorMsg(Text.of(factionName), COLOR_CODE.GOLD); + chatHeader.ColorMsg(Text.of("----[" + factionName + "]----"), COLOR_CODE.GOLD); ChatMsg chatBalance = new ChatMsg(); - chatBalance.ColorMsg(Text.of(Integer.toString(fBankBalance)), COLOR_CODE.GREEN); + chatBalance.ColorMsg(Text.of("Balance: " + Integer.toString(fBankBalance)), COLOR_CODE.GREEN); ChatMsg chatPower = new ChatMsg(); - chatPower.ColorMsg(Text.of(Integer.toString(fPower)), COLOR_CODE.RED); + chatPower.ColorMsg(Text.of("Power: " + Integer.toString(fPower)), COLOR_CODE.RED); ChatMenu chatBlock = new ChatMenu(); chatBlock.SetHeader(chatHeader); - chatBlock.AddMsg(chatPlayerList); chatBlock.AddMsg(chatBalance); chatBlock.AddMsg(chatPower); diff --git a/src/main/java/jesse/keeblarcraft/mixin/EntitySpawnMixin.java b/src/main/java/jesse/keeblarcraft/mixin/EntitySpawnMixin.java new file mode 100644 index 0000000..e8c7c22 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/mixin/EntitySpawnMixin.java @@ -0,0 +1,33 @@ +package jesse.keeblarcraft.mixin; + +import net.minecraft.entity.mob.MobEntity; + +// import javax.annotation.Nullable; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.ModifyReceiver; + + import jesse.keeblarcraft.Callbacks.MobSpawnCallback; +import net.minecraft.entity.EntityData; +import net.minecraft.entity.SpawnReason; +import net.minecraft.nbt.NbtCompound; + import net.minecraft.util.ActionResult; +import net.minecraft.world.LocalDifficulty; +import net.minecraft.world.ServerWorldAccess; +import net.minecraft.world.SpawnHelper; + +@Mixin(SpawnHelper.class) +public class EntitySpawnMixin { + @ModifyReceiver( + method = "spawnEntitiesInChunk(Lnet/minecraft/entity/SpawnGroup;Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/world/chunk/Chunk;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/SpawnHelper$Checker;Lnet/minecraft/world/SpawnHelper$Runner;)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/mob/MobEntity;initialize(Lnet/minecraft/world/ServerWorldAccess;Lnet/minecraft/world/LocalDifficulty;Lnet/minecraft/entity/SpawnReason;Lnet/minecraft/entity/EntityData;Lnet/minecraft/nbt/NbtCompound;)Lnet/minecraft/entity/EntityData;") + ) + private static MobEntity mobEntity(MobEntity instance, ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, EntityData entityData, NbtCompound entityNbt) { + // Do stuff + ActionResult action = MobSpawnCallback.EVENT.invoker().interact(instance.getWorld(), instance); + + return instance; + } +} diff --git a/src/main/resources/keeblarcraft.mixins.json b/src/main/resources/keeblarcraft.mixins.json index b185abb..88ccd00 100644 --- a/src/main/resources/keeblarcraft.mixins.json +++ b/src/main/resources/keeblarcraft.mixins.json @@ -7,7 +7,8 @@ "PlayerMixin", "ServerPlayNetworkHandlerMixin", "PlayerEntityInteractionHandler", - "ServerPlayerInteractionManagerMixin" + "ServerPlayerInteractionManagerMixin", + "EntitySpawnMixin" ], "client": [ "ClientPlayerInteractionManagerMixin"