Skip to content

Commit

Permalink
Cool wand
Browse files Browse the repository at this point in the history
  • Loading branch information
enjarai committed Jun 15, 2024
1 parent d57da2b commit 4014091
Show file tree
Hide file tree
Showing 32 changed files with 749 additions and 80 deletions.
24 changes: 16 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ repositories {
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.

repositories {
maven { url 'https://maven.wispforest.io' }
maven {
url 'https://maven.wispforest.io'
}

maven {
url "https://maven.enjarai.dev/releases"
}
}

Expand All @@ -37,19 +41,23 @@ loom {

dependencies {
// To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
minecraft "com.mojang:minecraft:${property('deps.minecraft')}"
mappings "net.fabricmc:yarn:${property('deps.yarn')}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"

// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${property('deps.fabric-api')}"

modImplementation "io.wispforest:owo-lib:${project.owo_version}"
include "io.wispforest:owo-sentinel:${project.owo_version}"
modImplementation "io.wispforest:owo-lib:${property('deps.owo-lib')}"
include "io.wispforest:owo-sentinel:${property('deps.owo-lib')}"

modImplementation "io.wispforest:lavender:${project.lavender_version}"
modImplementation "io.wispforest:lavender:${property('deps.lavender')}"
// implementation "io.wispforest:endec:0.1.0-pre.8"
modLocalRuntime "io.wispforest.lavender-md:owo-ui:0.1.2+1.21"

modImplementation("nl.enjarai:cicada-lib:${property('deps.cicada')}") {
exclude group: "net.fabricmc.fabric-api"
}
}

processResources {
Expand Down
11 changes: 6 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ org.gradle.parallel=true

# Fabric Properties
# check these on https://fabricmc.net/develop
minecraft_version=1.21-pre3
yarn_mappings=1.21-pre3+build.1
deps.minecraft=1.21
deps.yarn=1.21+build.2
loader_version=0.15.11

# Mod Properties
Expand All @@ -14,6 +14,7 @@ maven_group=dev.enjarai.trickster
archives_base_name=trickster

# Dependencies
fabric_version=0.99.5+1.21
owo_version=0.12.8-alpha.7+1.21
lavender_version=0.1.9-pre.1+1.21
deps.fabric-api=0.100.1+1.21
deps.owo-lib=0.12.8-alpha.7+1.21
deps.lavender=0.1.9-pre.1+1.21
deps.cicada=0.8.0+1.21-and-above
27 changes: 27 additions & 0 deletions src/client/java/dev/enjarai/trickster/ModSounds.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package dev.enjarai.trickster;

import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.sound.SoundEvent;
import net.minecraft.util.math.random.LocalRandom;
import net.minecraft.util.math.random.Random;

public class ModSounds {
public static final SoundEvent DRAW = register("draw");
public static final SoundEvent COMPLETE = register("complete");

private static SoundEvent register(String path) {
var id = Trickster.id(path);
return Registry.register(Registries.SOUND_EVENT, id, SoundEvent.of(id));
}

public static void register() {

}

private static final Random PITCH_RANDOM = new LocalRandom(0xCAFEBABE);

public static float randomPitch(float start, float range) {
return start - range + PITCH_RANDOM.nextFloat() * range * 2;
}
}
4 changes: 3 additions & 1 deletion src/client/java/dev/enjarai/trickster/TricksterClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ public class TricksterClient implements ClientModInitializer {
public void onInitializeClient() {
ModHandledScreens.register();
ModKeyBindings.register();
ModSounds.register();

UIParsing.registerFactory(Trickster.id("glyph"), GlyphComponent::parse);
UIParsing.registerFactory(Trickster.id("glyph"), GlyphComponent::parseTrick);
UIParsing.registerFactory(Trickster.id("pattern"), GlyphComponent::parseList);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package dev.enjarai.trickster.screen;

import com.mojang.blaze3d.systems.RenderSystem;
import dev.enjarai.trickster.ModSounds;
import dev.enjarai.trickster.Trickster;
import dev.enjarai.trickster.spell.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.*;
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
import net.minecraft.client.render.*;
import net.minecraft.sound.SoundCategory;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
Expand Down Expand Up @@ -397,10 +399,18 @@ protected boolean selectPattern(SpellPart part, float x, float y, float size, do

if (drawingPattern.size() >= 2 && drawingPattern.get(drawingPattern.size() - 2) == (byte) i) {
drawingPattern.removeLast();
MinecraftClient.getInstance().player.playSoundToPlayer(
ModSounds.DRAW, SoundCategory.MASTER,
1f, ModSounds.randomPitch(0.6f, 0.2f)
);
} else if (drawingPattern.isEmpty() ||
(drawingPattern.getLast() != (byte) i && !hasOverlappingLines(drawingPattern, drawingPattern.getLast(), (byte) i))) {
drawingPattern.add((byte) i);
// TODO click sound?
MinecraftClient.getInstance().player.playSoundToPlayer(
ModSounds.DRAW, SoundCategory.MASTER,
1f, ModSounds.randomPitch(1f, 0.2f)
);
}

return true;
Expand All @@ -412,6 +422,7 @@ protected boolean selectPattern(SpellPart part, float x, float y, float size, do

protected void stopDrawing() {
var compiled = Pattern.from(drawingPattern);
var patternSize = drawingPattern.size();

if (compiled.equals(CREATE_SUBCIRCLE_GLYPH)) {
drawingPart.subParts.add(Optional.of(new SpellPart()));
Expand All @@ -432,14 +443,19 @@ protected void stopDrawing() {
} else if (compiled.equals(COPY_OFFHAND_EXECUTE)) {
toBeReplaced = drawingPart;
initializeReplace.run();
} else if (drawingPattern.size() > 1) {
} else if (patternSize > 1) {
drawingPart.glyph = new PatternGlyph(compiled, drawingPattern);
}

drawingPart = null;
drawingPattern = null;

updateListener.accept(spellPart);

MinecraftClient.getInstance().player.playSoundToPlayer(
ModSounds.COMPLETE, SoundCategory.MASTER,
1f, patternSize > 1 ? 1f : 0.6f
);
}

public void replaceCallback(Fragment fragment) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
package dev.enjarai.trickster.screen.owo;

import dev.enjarai.trickster.spell.Pattern;
import dev.enjarai.trickster.spell.tricks.Trick;
import dev.enjarai.trickster.spell.tricks.Tricks;
import io.wispforest.owo.ui.base.BaseComponent;
import io.wispforest.owo.ui.core.OwoUIDrawContext;
import io.wispforest.owo.ui.core.Sizing;
import io.wispforest.owo.ui.parsing.UIParsing;
import org.joml.Vector2f;
import org.w3c.dom.Element;

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;

import static dev.enjarai.trickster.screen.SpellPartWidget.*;

public class GlyphComponent extends BaseComponent {
protected Trick trick;
protected Pattern pattern;
protected List<Integer> patternList;
protected int size;

public GlyphComponent(Trick trick, int size) {
this(trick.getPattern(), size);
}

public GlyphComponent(Pattern pattern, int size) {
super();
this.trick = trick;
this.pattern = pattern;
this.size = size;
this.patternList = trick.getPattern()
this.patternList = pattern
.entries().stream()
.flatMapToInt(e -> IntStream.of(e.p1(), e.p2()))
.distinct()
Expand All @@ -49,7 +54,7 @@ public void draw(OwoUIDrawContext context, int mouseX, int mouseY, float partial
}, 0, 0, 0, 0, isLinked ? 0.9f : 0.5f);
}

for (var line : trick.getPattern().entries()) {
for (var line : pattern.entries()) {
var now = getPatternDotPosition(x + patternSize + 4, y + patternSize + 4, line.p1(), patternSize);
var last = getPatternDotPosition(x + patternSize + 4, y + patternSize + 4, line.p2(), patternSize);
drawGlyphLine(context, last, now, 1, false, 0, 0.9f);
Expand All @@ -66,7 +71,7 @@ protected int determineVerticalContentSize(Sizing sizing) {
return size + 8;
}

public static GlyphComponent parse(Element element) {
public static GlyphComponent parseTrick(Element element) {
UIParsing.expectAttributes(element, "trick-id");
UIParsing.expectAttributes(element, "size");

Expand All @@ -81,4 +86,18 @@ public static GlyphComponent parse(Element element) {

return new GlyphComponent(trick, size);
}

public static GlyphComponent parseList(Element element) {
UIParsing.expectAttributes(element, "pattern");
UIParsing.expectAttributes(element, "size");

var patternString = element.getAttributeNode("pattern").getTextContent();

var pattern = Pattern.from(Arrays.stream(patternString.split(","))
.map(s -> Byte.valueOf(s, 10)).toList());

var size = UIParsing.parseUnsignedInt(element.getAttributeNode("size"));

return new GlyphComponent(pattern, size);
}
}
3 changes: 3 additions & 0 deletions src/main/java/dev/enjarai/trickster/item/ModItems.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public class ModItems {
.component(DataComponentTypes.CONTAINER,
ContainerComponent.fromStacks(DefaultedList.ofSize(27, ItemStack.EMPTY)))
.component(ModComponents.SELECTED_SLOT, new SelectedSlotComponent(0, 27))));
public static final WandItem WAND = register("wand",
new WandItem(new Item.Settings().maxCount(1)
.component(ModComponents.SPELL, new SpellComponent(new SpellPart()))));

public static final TagKey<Item> CAN_EVALUATE_DYNAMICALLY = TagKey.of(RegistryKeys.ITEM, Trickster.id("can_evaluate_dynamically"));
public static final TagKey<Item> HOLDABLE_HAT = TagKey.of(RegistryKeys.ITEM, Trickster.id("holdable_hat"));
Expand Down
29 changes: 9 additions & 20 deletions src/main/java/dev/enjarai/trickster/item/ScrollAndQuillItem.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
package dev.enjarai.trickster.item;

import dev.enjarai.trickster.item.component.ModComponents;
import dev.enjarai.trickster.screen.ScrollAndQuillScreenHandler;
import dev.enjarai.trickster.spell.PlayerSpellContext;
import dev.enjarai.trickster.spell.SpellContext;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
Expand All @@ -28,24 +24,17 @@ public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand han
var otherStack = user.getStackInHand(hand == Hand.MAIN_HAND ? Hand.OFF_HAND : Hand.MAIN_HAND);
var slot = hand == Hand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND;

if (user.isSneaking()) {
user.openHandledScreen(new NamedScreenHandlerFactory() {
@Override
public Text getDisplayName() {
return Text.translatable("trickster.screen.scroll_and_quill");
}
user.openHandledScreen(new NamedScreenHandlerFactory() {
@Override
public Text getDisplayName() {
return Text.translatable("trickster.screen.scroll_and_quill");
}

@Override
public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
return new ScrollAndQuillScreenHandler(syncId, playerInventory, stack, otherStack, slot, false);
}
});
} else if (!world.isClient()) { // TODO remove
var spell = stack.get(ModComponents.SPELL);
if (spell != null) {
spell.spell().runSafely(new PlayerSpellContext((ServerPlayerEntity) user, slot));
@Override
public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
return new ScrollAndQuillScreenHandler(syncId, playerInventory, stack, otherStack, slot, false);
}
}
});

return TypedActionResult.success(stack);
}
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/dev/enjarai/trickster/item/WandItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package dev.enjarai.trickster.item;

import dev.enjarai.trickster.item.component.ModComponents;
import dev.enjarai.trickster.spell.PlayerSpellContext;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.world.World;

public class WandItem extends Item {
public WandItem(Settings settings) {
super(settings);
}

@Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
var stack = user.getStackInHand(hand);
var slot = hand == Hand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND;

if (!world.isClient()) {
var spell = stack.get(ModComponents.SPELL);
if (spell != null) {
spell.spell().runSafely(new PlayerSpellContext((ServerPlayerEntity) user, slot));
}
}

return TypedActionResult.success(stack);
}
}
21 changes: 16 additions & 5 deletions src/main/java/dev/enjarai/trickster/spell/PlayerSpellContext.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package dev.enjarai.trickster.spell;

import dev.enjarai.trickster.item.component.ModComponents;
import dev.enjarai.trickster.item.component.SpellComponent;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import org.joml.Vector3d;

import java.util.Optional;

Expand All @@ -26,15 +27,25 @@ public Optional<ServerPlayerEntity> getPlayer() {
@Override
public Optional<ItemStack> getOtherHandSpellStack() {
if (slot == EquipmentSlot.MAINHAND) {
return Optional.ofNullable(player.getOffHandStack()).filter(s -> s.contains(ModComponents.SPELL));
return Optional.ofNullable(player.getOffHandStack()).filter(this::isSpellStack);
} else if (slot == EquipmentSlot.OFFHAND) {
return Optional.ofNullable(player.getMainHandStack()).filter(s -> s.contains(ModComponents.SPELL));
return Optional.ofNullable(player.getMainHandStack()).filter(this::isSpellStack);
}

return Optional
.ofNullable(player.getMainHandStack())
.filter(s -> s.contains(ModComponents.SPELL))
.filter(this::isSpellStack)
.or(() -> Optional.ofNullable(player.getOffHandStack())
.filter(s -> s.contains(ModComponents.SPELL)));
.filter(this::isSpellStack));
}

protected boolean isSpellStack(ItemStack stack) {
return stack.contains(ModComponents.SPELL) ||
(stack.contains(DataComponentTypes.CONTAINER) && stack.contains(ModComponents.SELECTED_SLOT));
}

@Override
public Vector3d getPosition() {
return new Vector3d(player.getX(), player.getY(), player.getZ());
}
}
Loading

0 comments on commit 4014091

Please sign in to comment.