[factions-banking] Added mixin to capture mob spawning. Other faction features too
Some checks are pending
build / build (21) (push) Waiting to run

This commit is contained in:
Jkibbels 2025-01-24 20:00:41 -05:00
parent bf3b1f6ed2
commit 5911c7c775
9 changed files with 203 additions and 32 deletions

View File

@ -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<MobSpawnCallback> 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);
}

View File

@ -5,18 +5,27 @@ import java.util.List;
import jesse.keeblarcraft.ChatStuff.ChatFormatting.COLOR_CODE; import jesse.keeblarcraft.ChatStuff.ChatFormatting.COLOR_CODE;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text; 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 // Create a "chat menu" which is just a menu in chat with pages that a user can click to display
// the next page. // the next page.
public class ChatMenu { public class ChatMenu {
private List<Text> msgList = new ArrayList<>(); private ArrayList<Text> msgList = new ArrayList<>();
private Text header; private Text header;
private Text headerFooterSpacing = Text.of(" ");
private Text leftArrow; private Text leftArrow;
private Text rightArrow; 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 int pageCount = 1; // Calculated at runtime
private ChatMsg formatter = new ChatMsg(); private ChatMsg formatter = new ChatMsg();
private int currentPage = 0;
ServerPlayerEntity lastTarget;
private enum TURN_DIRECTION {
BACK,
FORWARD
}
public ChatMenu() { public ChatMenu() {
// Initialize default header and arrows // Initialize default header and arrows
@ -35,7 +44,7 @@ public class ChatMenu {
} }
public void SetHeader(ChatMsg msg) { public void SetHeader(ChatMsg msg) {
this.header = msg.regularText; this.header = msg.mutableText;
} }
public void SetLeftArrow(Text leftArrow) { public void SetLeftArrow(Text leftArrow) {
@ -46,6 +55,57 @@ public class ChatMenu {
this.rightArrow = rightArrow; 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) { public void AddMsg(Text newMsg) {
msgList.add(newMsg); msgList.add(newMsg);
} }
@ -55,7 +115,17 @@ public class ChatMenu {
} }
public void AddMsg(ChatMsg newMsg) { public void AddMsg(ChatMsg newMsg) {
AddMsg(newMsg.regularText); AddMsg(newMsg.mutableText);
}
public void AddMsg(List<ChatMsg> newMsgList) {
for (int i = 0; i < newMsgList.size(); i++) {
AddMsg(newMsgList.get(i));
}
}
public void AddNewLine() {
AddMsg(Text.of(""));
} }
public void ClearList() { public void ClearList() {
@ -69,23 +139,48 @@ public class ChatMenu {
} }
} }
// Prints the current page
public void SendMsg(ServerPlayerEntity target) { public void SendMsg(ServerPlayerEntity target) {
// Calculate number of pages // Calculate number of pages
pageCount = (int) Math.ceil(msgList.size() / (double) pageLimit); pageCount = (int) Math.ceil(msgList.size() / (double) pageLimit);
int startIdx = currentPage * pageLimit;
// Send the header // Send the header
target.sendMessage(header); target.sendMessage(MakeHeader());
target.sendMessage(Text.of("")); // Spacer int maxCapoutDebug = 20;
// Send the body int stopIdx = startIdx + pageLimit;
int msgIndex = 0; for (int pageItem = startIdx; pageItem < stopIdx && pageItem < msgList.size(); pageItem++) {
for (int page = 0; page < pageCount; page++) { target.sendMessage(msgList.get(pageItem));
for (int i = 0; i < pageLimit; i++) {
target.sendMessage(msgList.get(msgIndex++)); --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 // 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);
} }
} }

View File

@ -19,9 +19,8 @@ import net.minecraft.text.Style;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public class ChatMsg { public class ChatMsg {
// May be null; store last message of each type so class can be referenced as object public Text regularText = Text.of("");
MutableText mutableText; public MutableText mutableText = (MutableText) regularText;
Text regularText;
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// @fn MakeCopyableTxt /// @fn MakeCopyableTxt
/// ///
@ -71,6 +70,11 @@ public class ChatMsg {
return MakeCopyableTxt(terminalTxt, hoverTxt, expanded); return MakeCopyableTxt(terminalTxt, hoverTxt, expanded);
} }
// public MutableText MakeClickCallback(MutableText text, ChatMsgClickEvent callback) {
// text.styled(style -> style.withClickEvent(callback));
// return text;
// }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// @fn MakeCopyableTxt /// @fn MakeCopyableTxt
/// ///
@ -88,15 +92,11 @@ public class ChatMsg {
public MutableText MakeCopyableTxt(String terminalTxt, String hoverTxt, String copyStr) { public MutableText MakeCopyableTxt(String terminalTxt, String hoverTxt, String copyStr) {
Text copyableText = Text.of(terminalTxt); Text copyableText = Text.of(terminalTxt);
MutableText testTxt = (MutableText) copyableText; MutableText testTxt = (MutableText) copyableText;
System.out.println("Making hoverable stuff");
testTxt.setStyle(Style.EMPTY.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, copyStr)) testTxt.setStyle(Style.EMPTY.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, copyStr))
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of(hoverTxt)))); .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; mutableText = testTxt;
regularText = copyableText;
return testTxt; return testTxt;
} }
@ -114,6 +114,8 @@ public class ChatMsg {
/// @return Formatted string of colored text /// @return Formatted string of colored text
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public String ColorMsg(Integer msg, COLOR_CODE color) { 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; return ChatFormatting.GetColor(color) + msg + ChatFormatting.COLOR_END;
} }
@ -136,6 +138,7 @@ public class ChatMsg {
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public Text ColorMsg(Text msg, COLOR_CODE color) { public Text ColorMsg(Text msg, COLOR_CODE color) {
regularText = Text.of(ChatFormatting.GetColor(color) + msg.getString() + ChatFormatting.COLOR_END); regularText = Text.of(ChatFormatting.GetColor(color) + msg.getString() + ChatFormatting.COLOR_END);
mutableText = (MutableText) regularText;
return regularText; return regularText;
} }

View File

@ -259,7 +259,9 @@ public class FactionCommands {
// Returns information on the players current faction // Returns information on the players current faction
private int GetFactionInformation(ServerPlayerEntity player) { private int GetFactionInformation(ServerPlayerEntity player) {
System.out.println("GETTING FACTION INFO");
FactionManager.GetInstance().GetFactionInformation(player); FactionManager.GetInstance().GetFactionInformation(player);
System.out.println("ENDING FACTION INFO");
return 0; return 0;
} }

View File

@ -3,6 +3,7 @@ package jesse.keeblarcraft.CustomBlocks.BlockEntities;
import java.util.ArrayList; import java.util.ArrayList;
import jesse.keeblarcraft.AttributeMgr.AttributeMgr; import jesse.keeblarcraft.AttributeMgr.AttributeMgr;
import jesse.keeblarcraft.Callbacks.MobSpawnCallback;
import jesse.keeblarcraft.FactionMgr.FactionManager; import jesse.keeblarcraft.FactionMgr.FactionManager;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerEnteredBaseCallback; import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerEnteredBaseCallback;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerExitedBaseCallback; 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.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventories; import net.minecraft.inventory.Inventories;
@ -50,6 +52,12 @@ public class FactionBlockEntity extends BlockEntity implements ExtendedScreenHan
public FactionBlockEntity(BlockPos pos, BlockState state, String faction) { public FactionBlockEntity(BlockPos pos, BlockState state, String faction) {
this(pos, state); this(pos, state);
this.faction = faction; 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) { 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 @Override
public Text getDisplayName() { public Text getDisplayName() {
return Text.literal("Faction Home Base Station"); // Replace with proper en_us format later return Text.literal("Faction Home Base Station"); // Replace with proper en_us format later

View File

@ -360,10 +360,8 @@ public class FactionConfig {
public String FindFactionOfPlayer(String playerUuid) { public String FindFactionOfPlayer(String playerUuid) {
String faction = ""; String faction = "";
System.out.println("Attempting to find player factions with uuid " + playerUuid);
for (Entry<String, WriteableFaction> entry : allFactions.entrySet()) { for (Entry<String, WriteableFaction> entry : allFactions.entrySet()) {
if (entry.getValue().factionPlayerList.containsKey(playerUuid)) { if (entry.getValue().factionPlayerList.containsKey(playerUuid)) {
System.out.println("FAC [" + entry.getKey() + "]: PLAY-LIST: " + entry.getValue().factionPlayerList);
faction = entry.getKey(); faction = entry.getKey();
break; break;
} }

View File

@ -95,27 +95,25 @@ public class FactionManager {
System.out.println((fPower == null ? "YES":"NO") + " " + (displayNames == null ? "YES":"NO") + " " + (fBankBalance == null ? "YES":"NO")); System.out.println((fPower == null ? "YES":"NO") + " " + (displayNames == null ? "YES":"NO") + " " + (fBankBalance == null ? "YES":"NO"));
ArrayList<String> nameMapToList = new ArrayList<String>(); ArrayList<ChatMsg> chatPlayerList = new ArrayList<>();
ChatMsg chatPlayerList = new ChatMsg();
for (Entry<String, VALID_FACTION_ROLES> entry : displayNames.entrySet()) { for (Entry<String, VALID_FACTION_ROLES> 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 // Let's make our chat objects first so things are copyable and whatnot
ChatMsg chatHeader = new ChatMsg(); ChatMsg chatHeader = new ChatMsg();
chatHeader.ColorMsg(Text.of(factionName), COLOR_CODE.GOLD); chatHeader.ColorMsg(Text.of("----[" + factionName + "]----"), COLOR_CODE.GOLD);
ChatMsg chatBalance = new ChatMsg(); 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(); 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(); ChatMenu chatBlock = new ChatMenu();
chatBlock.SetHeader(chatHeader); chatBlock.SetHeader(chatHeader);
chatBlock.AddMsg(chatPlayerList);
chatBlock.AddMsg(chatBalance); chatBlock.AddMsg(chatBalance);
chatBlock.AddMsg(chatPower); chatBlock.AddMsg(chatPower);

View File

@ -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;
}
}

View File

@ -7,7 +7,8 @@
"PlayerMixin", "PlayerMixin",
"ServerPlayNetworkHandlerMixin", "ServerPlayNetworkHandlerMixin",
"PlayerEntityInteractionHandler", "PlayerEntityInteractionHandler",
"ServerPlayerInteractionManagerMixin" "ServerPlayerInteractionManagerMixin",
"EntitySpawnMixin"
], ],
"client": [ "client": [
"ClientPlayerInteractionManagerMixin" "ClientPlayerInteractionManagerMixin"