Skip to content

Commit fb6bcc4

Browse files
committed
feat: eatable rekara, commands and empry casting
1 parent 7c1075b commit fb6bcc4

38 files changed

Lines changed: 745 additions & 31 deletions

build.gradle

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ plugins {
22
id 'fabric-loom' version '1.10-SNAPSHOT'
33
id 'maven-publish'
44
id "org.jetbrains.kotlin.jvm" version "2.1.20"
5+
id 'org.jetbrains.kotlin.plugin.serialization' version '2.1.20'
56
}
67

78
version = project.mod_version
@@ -17,6 +18,10 @@ repositories {
1718
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
1819
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
1920
// for more information about repositories.
21+
maven {
22+
name = 'Ladysnake Mods'
23+
url = 'https://maven.ladysnake.org/releases'
24+
}
2025
}
2126

2227
loom {
@@ -46,6 +51,10 @@ dependencies {
4651
// Fabric API. This is technically optional, but you probably want it anyway.
4752
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
4853
modImplementation "net.fabricmc:fabric-language-kotlin:${project.fabric_kotlin_version}"
54+
55+
// Cardinal Components API
56+
modImplementation "org.ladysnake.cardinal-components-api:cardinal-components-base:6.3.1"
57+
modImplementation "org.ladysnake.cardinal-components-api:cardinal-components-entity:6.3.1"
4958
}
5059

5160
processResources {
@@ -100,4 +109,4 @@ publishing {
100109
// The repositories here will be used for publishing your artifact, not for
101110
// retrieving dependencies.
102111
}
103-
}
112+
}

src/client/java/com/hcgstudio/reninjacraft/mixin/client/ExampleClientMixin.java

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.hcgstudio.reninjacraft.mixin.client;
2+
3+
import net.minecraft.client.MinecraftClient;
4+
import net.minecraft.client.input.Input;
5+
import net.minecraft.client.input.KeyboardInput;
6+
import net.minecraft.util.PlayerInput;
7+
import net.minecraft.util.math.Vec2f;
8+
import org.lwjgl.glfw.GLFW;
9+
import org.spongepowered.asm.mixin.Mixin;
10+
import org.spongepowered.asm.mixin.Unique;
11+
import org.spongepowered.asm.mixin.injection.At;
12+
import org.spongepowered.asm.mixin.injection.Inject;
13+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
14+
15+
@Mixin(KeyboardInput.class)
16+
public class KeyboardInputMixin extends Input {
17+
@Inject(method = "tick", at = @At("TAIL"))
18+
private void tick(CallbackInfo ci) {
19+
if (isCtrlPressed()) {
20+
this.playerInput = PlayerInput.DEFAULT;
21+
this.movementVector = Vec2f.ZERO;
22+
}
23+
}
24+
25+
@Unique
26+
private boolean isCtrlPressed() {
27+
var window = MinecraftClient.getInstance().getWindow().getHandle();
28+
return GLFW.glfwGetKey(window, GLFW.GLFW_KEY_LEFT_CONTROL) == GLFW.GLFW_PRESS
29+
|| GLFW.glfwGetKey(window, GLFW.GLFW_KEY_RIGHT_CONTROL) == GLFW.GLFW_PRESS;
30+
}
31+
}

src/client/kotlin/com/hcgstudio/reninjacraft/ReninjaCraftClient.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package com.hcgstudio.reninjacraft
22

3+
import com.hcgstudio.reninjacraft.casting.NinjutsuCastHandler
4+
import com.hcgstudio.reninjacraft.client.HudRenderer
5+
import com.hcgstudio.reninjacraft.client.ServerMessageHandler
6+
import com.hcgstudio.reninjacraft.config.ModKeyBinding
37
import com.hcgstudio.reninjacraft.items.ModSounds
48
import net.fabricmc.api.ClientModInitializer
59
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
@@ -16,13 +20,19 @@ object ReninjaCraftClient : ClientModInitializer {
1620
ClientTickEvents.END_CLIENT_TICK.register { client: MinecraftClient ->
1721
if (!hasPlayedMenuSound && client.currentScreen is TitleScreen) {
1822
val sound = PositionedSoundInstance.master(
19-
ModSounds.reninjaSounds["scared_and_release_ninjutsu"]!!, // 你注册的自定义 SoundEvent
23+
ModSounds.reninjaSounds["scared_and_release_ninjutsu"]!!,
2024
1.0f
2125
)
2226
client.soundManager.play(sound)
2327
logger.info("Playing init sound")
2428
hasPlayedMenuSound = true
2529
}
2630
}
31+
32+
ModKeyBinding.initialize()
33+
34+
ServerMessageHandler.initialize()
35+
NinjutsuCastHandler.initialize()
36+
HudRenderer.initialize()
2737
}
2838
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.hcgstudio.reninjacraft.casting
2+
3+
import com.hcgstudio.reninjacraft.ReninjaCraftClient
4+
import com.hcgstudio.reninjacraft.client.ClientNinjutsuRegistry
5+
import com.hcgstudio.reninjacraft.items.ModSounds
6+
import com.hcgstudio.reninjacraft.ninjutsu.NinjutsuKeys
7+
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
8+
import net.minecraft.client.sound.PositionedSoundInstance
9+
import org.lwjgl.glfw.GLFW
10+
11+
object NinjutsuCastHandler {
12+
val castingInputQueue = mutableListOf<NinjutsuKeys>()
13+
var wPressed = false
14+
var aPressed = false
15+
var sPressed = false
16+
var dPressed = false
17+
18+
fun initialize() {
19+
ClientTickEvents.END_CLIENT_TICK.register(ClientTickEvents.EndTick {
20+
// TODO: Add option to press ctrl once, arrow then cast
21+
it.world ?: return@EndTick
22+
23+
val isCtrlDown = GLFW.glfwGetKey(
24+
it.window.handle,
25+
GLFW.GLFW_KEY_LEFT_CONTROL
26+
) == GLFW.GLFW_PRESS || GLFW.glfwGetKey(it.window.handle, GLFW.GLFW_KEY_RIGHT_CONTROL) == GLFW.GLFW_PRESS
27+
28+
if (!isCtrlDown && castingInputQueue.isNotEmpty()) {
29+
val ninjutsu = ClientNinjutsuRegistry.getSyncedNinjutsu(castingInputQueue)
30+
castingInputQueue.clear()
31+
32+
if (ninjutsu == null) {
33+
return@EndTick
34+
}
35+
36+
ModSounds.reninjaSounds[ninjutsu.soundId]?.run {
37+
val sound = PositionedSoundInstance.master(
38+
this,
39+
1.0f
40+
)
41+
it.soundManager.play(sound)
42+
}
43+
44+
ReninjaCraftClient.logger.info("Casting ${ninjutsu.name}")
45+
}
46+
47+
if (!isCtrlDown)
48+
return@EndTick
49+
50+
val wPressing = GLFW.glfwGetKey(
51+
it.window.handle,
52+
GLFW.GLFW_KEY_W
53+
) == GLFW.GLFW_PRESS
54+
55+
val aPressing = GLFW.glfwGetKey(
56+
it.window.handle,
57+
GLFW.GLFW_KEY_A
58+
) == GLFW.GLFW_PRESS
59+
60+
val sPressing = GLFW.glfwGetKey(
61+
it.window.handle,
62+
GLFW.GLFW_KEY_S
63+
) == GLFW.GLFW_PRESS
64+
65+
val dPressing = GLFW.glfwGetKey(
66+
it.window.handle,
67+
GLFW.GLFW_KEY_D
68+
) == GLFW.GLFW_PRESS
69+
70+
if (wPressing) {
71+
if (!wPressed) {
72+
wPressed = true
73+
ReninjaCraftClient.logger.info("Ctrl+Up key pressed")
74+
castingInputQueue.add(NinjutsuKeys.Up)
75+
}
76+
} else {
77+
wPressed = false
78+
}
79+
80+
if (aPressing) {
81+
if (!aPressed) {
82+
aPressed = true
83+
ReninjaCraftClient.logger.info("Ctrl+Left key pressed")
84+
castingInputQueue.add(NinjutsuKeys.Left)
85+
}
86+
} else {
87+
aPressed = false
88+
}
89+
90+
if (sPressing) {
91+
if (!sPressed) {
92+
sPressed = true
93+
ReninjaCraftClient.logger.info("Ctrl+Down key pressed")
94+
castingInputQueue.add(NinjutsuKeys.Down)
95+
}
96+
} else {
97+
sPressed = false
98+
}
99+
100+
if (dPressing) {
101+
if (!dPressed) {
102+
dPressed = true
103+
ReninjaCraftClient.logger.info("Ctrl+Right key pressed")
104+
castingInputQueue.add(NinjutsuKeys.Right)
105+
}
106+
} else {
107+
dPressed = false
108+
}
109+
})
110+
}
111+
112+
113+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.hcgstudio.reninjacraft.client
2+
3+
import com.hcgstudio.reninjacraft.event.SyncedNinjutsu
4+
import com.hcgstudio.reninjacraft.ninjutsu.NinjutsuKeys
5+
6+
object ClientNinjutsuRegistry {
7+
private val ninjutsuMap = mutableMapOf<String, SyncedNinjutsu>()
8+
9+
fun getSyncedNinjutsu(sequence: List<NinjutsuKeys>): SyncedNinjutsu? {
10+
return ninjutsuMap[sequence.joinToString(",")]
11+
}
12+
13+
fun refreshSyncedNinjutsu(content: List<SyncedNinjutsu>) {
14+
ninjutsuMap.clear()
15+
ninjutsuMap.putAll(content.associateBy { it.castSequence.joinToString(",") })
16+
}
17+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.hcgstudio.reninjacraft.client
2+
3+
import com.hcgstudio.reninjacraft.ReninjaCraft
4+
import com.hcgstudio.reninjacraft.component.SyncedRekaraComponent
5+
import net.fabricmc.fabric.api.client.rendering.v1.HudLayerRegistrationCallback
6+
import net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer
7+
import net.minecraft.client.MinecraftClient
8+
import net.minecraft.text.Text
9+
10+
object HudRenderer {
11+
val layerId = ReninjaCraft.keyOf("rekara_hud")
12+
13+
fun initialize() {
14+
HudLayerRegistrationCallback.EVENT.register {
15+
it.attachLayerBefore(IdentifiedLayer.CHAT, layerId) { context, tickCounter ->
16+
val client = MinecraftClient.getInstance() ?: return@attachLayerBefore
17+
val player = client.player ?: return@attachLayerBefore
18+
val rekara = SyncedRekaraComponent.componentKey.get(player)
19+
20+
val x = context.scaledWindowWidth / 2 + 10
21+
val y = context.scaledWindowHeight - 49 - 10
22+
23+
context.drawText(
24+
client.textRenderer,
25+
Text.translatable("hud.${ReninjaCraft.MOD_ID}.hand_hud_text", rekara.hand, rekara.maxHand),
26+
x,
27+
y,
28+
0xfde300,
29+
true
30+
)
31+
32+
context.drawText(
33+
client.textRenderer,
34+
Text.translatable("hud.${ReninjaCraft.MOD_ID}.rekara_hud_text", rekara.rekara, rekara.maxRekara),
35+
x,
36+
y + 10,
37+
0x0e700e,
38+
true
39+
)
40+
}
41+
}
42+
}
43+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.hcgstudio.reninjacraft.client
2+
3+
import com.hcgstudio.reninjacraft.ReninjaCraftClient
4+
import com.hcgstudio.reninjacraft.event.Event
5+
import com.hcgstudio.reninjacraft.event.SyncNinjutsuEvent
6+
import com.hcgstudio.reninjacraft.payload.EventPayload
7+
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
8+
9+
object ServerMessageHandler {
10+
fun initialize() {
11+
ClientPlayNetworking.registerGlobalReceiver(EventPayload.id, { payload, context ->
12+
val event = Event.parseServerToClientEvent(payload.content)
13+
14+
ReninjaCraftClient.logger.info("Received event: {}", event)
15+
16+
when (event) {
17+
is SyncNinjutsuEvent -> handleEvent(event, context)
18+
}
19+
})
20+
}
21+
22+
fun handleEvent(event: SyncNinjutsuEvent, context: ClientPlayNetworking.Context) {
23+
ClientNinjutsuRegistry.refreshSyncedNinjutsu(event.ninjutsu)
24+
}
25+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.hcgstudio.reninjacraft.config
2+
3+
import com.hcgstudio.reninjacraft.ReninjaCraft
4+
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper
5+
import net.minecraft.client.option.KeyBinding
6+
import net.minecraft.client.util.InputUtil
7+
import org.lwjgl.glfw.GLFW
8+
9+
object ModKeyBinding {
10+
lateinit var upKey: KeyBinding
11+
lateinit var downKey: KeyBinding
12+
lateinit var leftKey: KeyBinding
13+
lateinit var rightKey: KeyBinding
14+
15+
16+
fun initialize() {
17+
upKey = KeyBinding(
18+
"key.${ReninjaCraft.MOD_ID}.up",
19+
InputUtil.Type.KEYSYM,
20+
GLFW.GLFW_KEY_W,
21+
"category.${ReninjaCraft.MOD_ID}.ninjutsu_cast"
22+
)
23+
24+
downKey = KeyBinding(
25+
"key.${ReninjaCraft.MOD_ID}.down",
26+
InputUtil.Type.KEYSYM,
27+
GLFW.GLFW_KEY_S,
28+
"category.${ReninjaCraft.MOD_ID}.ninjutsu_cast"
29+
)
30+
31+
leftKey = KeyBinding(
32+
"key.${ReninjaCraft.MOD_ID}.left",
33+
InputUtil.Type.KEYSYM,
34+
GLFW.GLFW_KEY_A,
35+
"category.${ReninjaCraft.MOD_ID}.ninjutsu_cast"
36+
)
37+
38+
rightKey = KeyBinding(
39+
"key.${ReninjaCraft.MOD_ID}.right",
40+
InputUtil.Type.KEYSYM,
41+
GLFW.GLFW_KEY_D,
42+
"category.${ReninjaCraft.MOD_ID}.ninjutsu_cast"
43+
)
44+
45+
KeyBindingHelper.registerKeyBinding(upKey)
46+
KeyBindingHelper.registerKeyBinding(downKey)
47+
KeyBindingHelper.registerKeyBinding(rightKey)
48+
KeyBindingHelper.registerKeyBinding(leftKey)
49+
50+
}
51+
}

src/client/kotlin/com/hcgstudio/reninjacraft/providers/DefaultLangProvider.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,10 @@ class DefaultLangProvider(
2020
translationBuilder.add("item.${ReninjaCraft.MOD_ID}.rekara", "蕾珂拉")
2121
translationBuilder.add("item.${ReninjaCraft.MOD_ID}.rekara_ore", "蕾珂拉矿")
2222
translationBuilder.add("item.${ReninjaCraft.MOD_ID}.deepslate_rekara_ore", "深层蕾珂拉矿")
23+
24+
translationBuilder.add("hud.${ReninjaCraft.MOD_ID}.hand_hud_text", "手:%1\$s/%2\$s")
25+
translationBuilder.add("hud.${ReninjaCraft.MOD_ID}.rekara_hud_text", "蕾珂拉:%1\$s/%2\$s")
26+
27+
translationBuilder.add("commands.${ReninjaCraft.MOD_ID}.setrekara.success", "已将%1\$s的蕾珂拉设置为%2\$s")
2328
}
2429
}

0 commit comments

Comments
 (0)