diff --git a/src/main/java/org/arsparadox/mobtalkerredux/CustomItem.java b/src/main/java/org/arsparadox/mobtalkerredux/CustomItem.java index d30118c..f9b344c 100644 --- a/src/main/java/org/arsparadox/mobtalkerredux/CustomItem.java +++ b/src/main/java/org/arsparadox/mobtalkerredux/CustomItem.java @@ -12,8 +12,8 @@ public class CustomItem extends Item { // No Like, Literally Custom Item - public CustomItem(Properties properties) { - super(properties); + public CustomItem() { + super(new Item.Properties()); } @Override @@ -24,11 +24,10 @@ public Component getName(ItemStack stack) { return super.getName(stack); } - // Override texture retrieval @Override public void appendHoverText(ItemStack stack, @Nullable Level level, List tooltip, TooltipFlag flag) { - if (stack.hasTag() && stack.getTag().contains("TextureKey")) { - tooltip.add(Component.translatable("Texture: " + stack.getTag().getString("TextureKey"))); + if (stack.hasTag() && stack.getTag().contains("Description")) { + tooltip.add(Component.translatable("Description: " + stack.getTag().getString("Description"))); } super.appendHoverText(stack, level, tooltip, flag); } diff --git a/src/main/java/org/arsparadox/mobtalkerredux/CustomItemUtils.java b/src/main/java/org/arsparadox/mobtalkerredux/CustomItemUtils.java new file mode 100644 index 0000000..ce7725d --- /dev/null +++ b/src/main/java/org/arsparadox/mobtalkerredux/CustomItemUtils.java @@ -0,0 +1,38 @@ +package org.arsparadox.mobtalkerredux; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; + +public class CustomItemUtils { + // Basic version - just give a variant + public static void giveCustomItem(Player player, String variantName) { + ItemStack itemStack = new ItemStack(MobTalkerRedux.RegistryEvents.CUSTOM_ITEM.get()); + CompoundTag tag = new CompoundTag(); + tag.putString("CustomName", "item.mobtalkerredux." + variantName); + tag.putString("TextureKey", "custom_item_" + variantName); + tag.putInt("CustomModelData", getVariantId(variantName)); + itemStack.setTag(tag); + + giveItemToPlayer(player, itemStack); + } + + + // Private helper methods + private static void giveItemToPlayer(Player player, ItemStack stack) { + if (!player.getInventory().add(stack)) { + // If inventory is full, spawn item in world + player.drop(stack, false); + } + } + + private static int getVariantId(String variantName) { + // You can expand this method to map variant names to custom model data IDs + return switch (variantName.toLowerCase()) { + case "variant1" -> 1; + case "variant2" -> 2; + case "variant3" -> 3; + default -> 1; + }; + } +} \ No newline at end of file diff --git a/src/main/java/org/arsparadox/mobtalkerredux/DemoCommand.java b/src/main/java/org/arsparadox/mobtalkerredux/DemoCommand.java index 289206f..c3e1ba2 100644 --- a/src/main/java/org/arsparadox/mobtalkerredux/DemoCommand.java +++ b/src/main/java/org/arsparadox/mobtalkerredux/DemoCommand.java @@ -7,8 +7,8 @@ import net.minecraft.commands.Commands; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; -import org.arsparadox.mobtalkerredux.vn.controller.vnmodules.PlayerInventoryHandler; import org.arsparadox.mobtalkerredux.vn.controller.VisualNovelEngine; +import org.arsparadox.mobtalkerredux.vn.controller.vnmodules.PlayerInventoryHandler; import org.arsparadox.mobtalkerredux.vn.model.ScriptLoader; import org.arsparadox.mobtalkerredux.vn.view.DialogueScreen; @@ -22,7 +22,7 @@ public static void register(CommandDispatcher dispatcher) { dispatcher.register(Commands.literal("mob_talker") .executes(context -> { if (context.getSource().getEntity() instanceof ServerPlayer player) { - serverSideExecute(player, "demo.json"); + serverSideExecute(player, "demo"); } return 1; }) @@ -43,12 +43,12 @@ private static void serverSideExecute(ServerPlayer player, String scriptFileName boolean day = player.level().isDay(); try { - List> script = ScriptLoader.loadScript(scriptFileName,null,uid); + List> script = ScriptLoader.loadScript(scriptFileName,"default",uid); List> global = ScriptLoader.loadGlobal(uid); VisualNovelEngine vnEngine = new VisualNovelEngine( script, scriptFileName, - null, + "demo", uid, day, inventory, diff --git a/src/main/java/org/arsparadox/mobtalkerredux/MobTalkerItem.java b/src/main/java/org/arsparadox/mobtalkerredux/MobTalkerItem.java index 0be49f6..3636edc 100644 --- a/src/main/java/org/arsparadox/mobtalkerredux/MobTalkerItem.java +++ b/src/main/java/org/arsparadox/mobtalkerredux/MobTalkerItem.java @@ -9,6 +9,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; +import org.arsparadox.mobtalkerredux.command.TeamHandler; import org.arsparadox.mobtalkerredux.vn.controller.VisualNovelEngine; import org.arsparadox.mobtalkerredux.vn.controller.vnmodules.PlayerInventoryHandler; import org.arsparadox.mobtalkerredux.vn.model.ScriptLoader; @@ -39,16 +40,21 @@ public MobTalkerItem() { // Safely check and cast to ServerPlayer } else { // Client-side: Open dialogue screen Minecraft minecraft = Minecraft.getInstance(); + //CustomItemUtils.giveCustomItem(player,"variant1"); minecraft.execute(() -> { sendClientMessage(player,"The Entity's type is: "+entityType); VisualNovelEngine vn = serverSideExecute(player, entityType, entityName,target); - clientSideRenderDialogueScreen(vn,target,player); + if(vn!=null){ + clientSideRenderDialogueScreen(vn,target,player); + + } + }); } return InteractionResult.SUCCESS; } } catch (Exception ignored) { - + System.out.println(ignored.toString()); } return InteractionResult.PASS; // Return PASS if the entity doesn't have a custom name @@ -75,6 +81,7 @@ private static VisualNovelEngine serverSideExecute(Player player, String entityT globalSave, localSave ); + TeamHandler.addToPlayerTeam(player,target); return vnEngine; // sendClientMessage(player, "Trying to load the file mobtalkerredux/" + scriptFileName); //clientSideRenderDialogueScreen(vnEngine,target,player); diff --git a/src/main/java/org/arsparadox/mobtalkerredux/MobTalkerRedux.java b/src/main/java/org/arsparadox/mobtalkerredux/MobTalkerRedux.java index 359d4cb..9864f84 100644 --- a/src/main/java/org/arsparadox/mobtalkerredux/MobTalkerRedux.java +++ b/src/main/java/org/arsparadox/mobtalkerredux/MobTalkerRedux.java @@ -73,6 +73,7 @@ public static class RegistryEvents { public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID); public static final RegistryObject MOB_TALKER_ITEM = ITEMS.register("mob_talker_item", MobTalkerItem::new); + public static final RegistryObject CUSTOM_ITEM = ITEMS.register("custom_item", CustomItem::new); // Command registration stays on Forge event bus @SubscribeEvent diff --git a/src/main/java/org/arsparadox/mobtalkerredux/vn/controller/VisualNovelEngine.java b/src/main/java/org/arsparadox/mobtalkerredux/vn/controller/VisualNovelEngine.java index 607a2f6..735389f 100644 --- a/src/main/java/org/arsparadox/mobtalkerredux/vn/controller/VisualNovelEngine.java +++ b/src/main/java/org/arsparadox/mobtalkerredux/vn/controller/VisualNovelEngine.java @@ -4,10 +4,7 @@ import org.arsparadox.mobtalkerredux.vn.controller.vnmodules.SaveHandler; import org.arsparadox.mobtalkerredux.vn.data.DialogueState; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; @@ -152,9 +149,9 @@ private void processAction(Map action) { } break; case "unlock_dialogues": - List events = (List) this.localVariables.getOrDefault("unlocked_events", new ArrayList<>()); + Set events = new HashSet<>((List) this.localVariables.getOrDefault("unlocked_events", new ArrayList<>())); events.addAll((List) action.get("events")); - this.localVariables.put("unlocked_events", events); + this.localVariables.put("unlocked_events", new ArrayList<>(events)); this.currentState.incrementAndGet(); break; case "play_sound": diff --git a/src/main/java/org/arsparadox/mobtalkerredux/vn/view/DialogueScreen.java b/src/main/java/org/arsparadox/mobtalkerredux/vn/view/DialogueScreen.java index 72841c1..c4ddb4c 100644 --- a/src/main/java/org/arsparadox/mobtalkerredux/vn/view/DialogueScreen.java +++ b/src/main/java/org/arsparadox/mobtalkerredux/vn/view/DialogueScreen.java @@ -41,6 +41,8 @@ public class DialogueScreen extends Screen{ public Mob mob; private Player player; + private boolean hiddenDialogue = false; + @@ -48,8 +50,6 @@ public DialogueScreen(VisualNovelEngine vn, LivingEntity target, Player player) super(Component.empty()); this.vn = vn; this.se = new SoundUtils(); - this.mob = (Mob)target; - this.player = player; } @@ -120,15 +120,34 @@ public void updateSprites(DialogueState state){ @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { if (button == 0) { - vn.isEngineRunning.set(true); - vn.runEngine(); - //Tell Engine to update the Globals, as in like, get the current state and put it in the global in this class - update(); + if(!hiddenDialogue){ + vn.isEngineRunning.set(true); + vn.runEngine(); + //Tell Engine to update the Globals, as in like, get the current state and put it in the global in this class + update(); + } + } return super.mouseClicked(mouseX, mouseY, button); } + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (keyCode == 32 || keyCode == 257) { // 32 = Space, 257 = Enter + if(!hiddenDialogue){ + vn.isEngineRunning.set(true); + vn.runEngine(); + update(); + } + + } + else if(keyCode == 72){ + hiddenDialogue = !hiddenDialogue; + } + return super.keyPressed(keyCode, scanCode, modifiers); + } + private void startScene() { vn.isEngineRunning.set(true); vn.runEngine();//run the engine, let it do some loops and backflips, engine's globals shouldn't affect this sacred place @@ -151,14 +170,14 @@ public void render(GuiGraphics poseStack, int mouseX, int mouseY, float partialT // Render the Sprites and Everything In Foreground if (spritesToRender != null && !spritesToRender.isEmpty()) { ForegroundComponent.processForeground( - poseStack, this.width, this.height, spritesToRender + poseStack, this.width, this.height, spritesToRender,vn.localVariables ); } // Render the Dialogue Box - if (content != null && !content.isEmpty()) { + if (content != null && !content.isEmpty() && !hiddenDialogue) { poseStack = DialogueBoxManager.processGui( - poseStack,this.width,this.height,content,label,this.font + poseStack,this.width,this.height,content,label,this.font,vn.localVariables ); } diff --git a/src/main/java/org/arsparadox/mobtalkerredux/vn/view/components/DialogueBoxManager.java b/src/main/java/org/arsparadox/mobtalkerredux/vn/view/components/DialogueBoxManager.java index 6140546..cdb597c 100644 --- a/src/main/java/org/arsparadox/mobtalkerredux/vn/view/components/DialogueBoxManager.java +++ b/src/main/java/org/arsparadox/mobtalkerredux/vn/view/components/DialogueBoxManager.java @@ -5,16 +5,20 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class DialogueBoxManager { - public static GuiGraphics processGui(GuiGraphics poseStack, int width,int height,String content, String label, Font font){ + public static GuiGraphics processGui(GuiGraphics poseStack, int width,int height,String content, String label, Font font, Map variables){ int CHARACTER_NAME_OFFSET = 40; int DISPLAYED_SPRITE_HEIGHT = 300; int dialogueBoxHeight = 80; int DIALOGUE_BOX_PADDING = 15; if (content != null && !content.isEmpty()) { // Set dialogue box dimensions and position + content = replaceTemplateVariables(variables,content); int boxWidth = Math.min(600, width - 40); // Max width of 600 or screen width - 40 int boxX = (width - boxWidth) / 2; int boxY = height - dialogueBoxHeight - 5; // 20 pixels from bottom @@ -178,6 +182,27 @@ private static List wrapText(String text, int maxWidth, Font font) { return lines; } + public static String replaceTemplateVariables(Map variables, String template) { + if (template == null || variables == null) { + return template; + } + + String result = template; + Pattern pattern = Pattern.compile("<(.*?)>"); + Matcher matcher = pattern.matcher(template); + + while (matcher.find()) { + String key = matcher.group(1); + Object value = variables.get(key); + + if (value != null) { + result = result.replace("<" + key + ">", value.toString()); + } + } + + return result; + } + } diff --git a/src/main/java/org/arsparadox/mobtalkerredux/vn/view/components/ForegroundComponent.java b/src/main/java/org/arsparadox/mobtalkerredux/vn/view/components/ForegroundComponent.java index cf41517..2abb2ce 100644 --- a/src/main/java/org/arsparadox/mobtalkerredux/vn/view/components/ForegroundComponent.java +++ b/src/main/java/org/arsparadox/mobtalkerredux/vn/view/components/ForegroundComponent.java @@ -6,6 +6,9 @@ import org.arsparadox.mobtalkerredux.vn.data.SpriteState; import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class ForegroundComponent { // MINECRAFT RENDERING SYSTEM IS A NIGHTMARE!!! @@ -25,11 +28,13 @@ public class ForegroundComponent { // Yeah... // So in the FSM, determining position should be like: // (Screen Ratio, Image Ratio, Coordinate Position) -> (16x9, 3x5, 8x1) - public static GuiGraphics processForeground(GuiGraphics poseStack, int width, int height, List spritesToRender){ + public static GuiGraphics processForeground(GuiGraphics poseStack, int width, int height, List spritesToRender, Map variables){ for (SpriteState sprite : spritesToRender) { + String spriteLocationRaw = sprite.getLocation(); + String spriteLocation = replaceTemplateVariables(variables,spriteLocationRaw); ResourceLocation currentSprite = new ResourceLocation( - "mobtalkerredux", "textures/" + sprite.getLocation() + "mobtalkerredux", "textures/" + spriteLocation ); RenderSystem.setShaderTexture(0, currentSprite); @@ -77,4 +82,27 @@ public static GuiGraphics processForeground(GuiGraphics poseStack, int width, in return poseStack; } + + + public static String replaceTemplateVariables(Map variables, String template) { + if (template == null || variables == null) { + return template; + } + + String result = template; + Pattern pattern = Pattern.compile("<(.*?)>"); + Matcher matcher = pattern.matcher(template); + + while (matcher.find()) { + String key = matcher.group(1); + Object value = variables.getOrDefault(key, "default"); + + result = result.replace("<" + key + ">", value.toString()); + } + + return result; + } + + + } diff --git a/src/main/resources/assets/mobtalkerredux/lang/en_us.json b/src/main/resources/assets/mobtalkerredux/lang/en_us.json index 7a8ba22..c170b4f 100644 --- a/src/main/resources/assets/mobtalkerredux/lang/en_us.json +++ b/src/main/resources/assets/mobtalkerredux/lang/en_us.json @@ -1,3 +1,7 @@ { - "item.mobtalkerredux.mob_talker_item": "The Mob Talker" + "item.mobtalkerredux.mob_talker_item": "The Mob Talker", + "item.mobtalkerredux.custom_item": "Custom Item", + "item.mobtalkerredux.variant1": "Variant 1 Item", + "item.mobtalkerredux.variant2": "Variant 2 Item" + } \ No newline at end of file diff --git a/src/main/resources/assets/mobtalkerredux/models/item/custom_item.json b/src/main/resources/assets/mobtalkerredux/models/item/custom_item.json new file mode 100644 index 0000000..37d0a26 --- /dev/null +++ b/src/main/resources/assets/mobtalkerredux/models/item/custom_item.json @@ -0,0 +1,20 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "mobtalkerredux:item/custom_item" + }, + "overrides": [ + { + "predicate": { + "custom_model_data": 1 + }, + "model": "mobtalkerredux:item/custom_item_variant1" + }, + { + "predicate": { + "custom_model_data": 2 + }, + "model": "mobtalkerredux:item/custom_item_variant2" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/mobtalkerredux/models/item/custom_item_variant1.json b/src/main/resources/assets/mobtalkerredux/models/item/custom_item_variant1.json new file mode 100644 index 0000000..5657ea0 --- /dev/null +++ b/src/main/resources/assets/mobtalkerredux/models/item/custom_item_variant1.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "mobtalkerredux:item/custom_item_variant1" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/mobtalkerredux/models/item/custom_item_variant2.json b/src/main/resources/assets/mobtalkerredux/models/item/custom_item_variant2.json new file mode 100644 index 0000000..f81cdb9 --- /dev/null +++ b/src/main/resources/assets/mobtalkerredux/models/item/custom_item_variant2.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "mobtalkerredux:item/custom_item_variant2" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/mobtalkerredux/textures/item/custom_item_variant1.png b/src/main/resources/assets/mobtalkerredux/textures/item/custom_item_variant1.png new file mode 100644 index 0000000..a02e7eb Binary files /dev/null and b/src/main/resources/assets/mobtalkerredux/textures/item/custom_item_variant1.png differ diff --git a/src/main/resources/assets/mobtalkerredux/textures/item/custom_item_variant2.png b/src/main/resources/assets/mobtalkerredux/textures/item/custom_item_variant2.png new file mode 100644 index 0000000..c7ed58d Binary files /dev/null and b/src/main/resources/assets/mobtalkerredux/textures/item/custom_item_variant2.png differ diff --git a/src/main/resources/data/mobtalkerredux/recipes/custom_item_variant1.json b/src/main/resources/data/mobtalkerredux/recipes/custom_item_variant1.json new file mode 100644 index 0000000..e0ddad7 --- /dev/null +++ b/src/main/resources/data/mobtalkerredux/recipes/custom_item_variant1.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + " G ", + " I ", + " S " + ], + "key": { + "I": { + "item": "minecraft:iron_ingot" + }, + "G": { + "item": "minecraft:glowstone" + }, + "S": { + "item": "mobtalkerredux:custom_item", + "nbt": { + "CustomModelData": 1 + } + } + }, + "result": { + "item": "mobtalkerredux:custom_item", + "nbt": { + "CustomModelData": 2, + "CustomName": "item.mobtalkerredux.variant2", + "TextureKey": "custom_item_variant2" + }, + "count": 1 + } +} \ No newline at end of file diff --git a/src/main/resources/data/mobtalkerredux/recipes/custom_item_variant2.json b/src/main/resources/data/mobtalkerredux/recipes/custom_item_variant2.json new file mode 100644 index 0000000..486e8df --- /dev/null +++ b/src/main/resources/data/mobtalkerredux/recipes/custom_item_variant2.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + " G ", + " S ", + " S " + ], + "key": { + "G": { + "item": "minecraft:glowstone" + }, + "S": { + "item": "mobtalkerredux:custom_item", + "nbt": { + "CustomModelData": 2 + } + } + }, + "result": { + "item": "mobtalkerredux:custom_item", + "nbt": { + "CustomModelData": 1, + "CustomName": "item.mobtalkerredux.variant1", + "TextureKey": "custom_item_variant1" + }, + "count": 1 + } +} \ No newline at end of file