working
This commit is contained in:
parent
fc78faffb5
commit
e3166bbf1a
@ -2,6 +2,8 @@ package net.Chipperfluff.chipi.client;
|
||||
|
||||
import net.Chipperfluff.chipi.block.ModBlocks;
|
||||
import net.Chipperfluff.chipi.client.entity.ModEntityRenderers;
|
||||
import net.Chipperfluff.chipi.client.hud.ChipiStatusBar;
|
||||
import net.Chipperfluff.chipi.util.ClientTickScheduler;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
@ -13,5 +15,7 @@ public class ChipiClient implements ClientModInitializer {
|
||||
BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CHIPPER_PORTAL, RenderLayer.getTranslucent());
|
||||
ModEntityRenderers.register();
|
||||
ModTooltips.register();
|
||||
ChipiStatusBar.register();
|
||||
ClientTickScheduler.init();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,83 @@
|
||||
package net.Chipperfluff.chipi.client.hud;
|
||||
|
||||
import net.Chipperfluff.chipi.item.ModItems;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
|
||||
import static net.Chipperfluff.chipi.util.ChipiTrackedData.CHIPI_ENERGY;
|
||||
|
||||
public class ChipiStatusBar {
|
||||
|
||||
private static final int ORANGE = 0xFFFF8000;
|
||||
private static final int OUTLINE_LIGHT = 0xFFB0B0B0;
|
||||
private static final int OUTLINE_DARK = 0xFF404040;
|
||||
private static final int BAR_HEIGHT = 6;
|
||||
|
||||
public static void register() {
|
||||
HudRenderCallback.EVENT.register(ChipiStatusBar::render);
|
||||
}
|
||||
|
||||
private static void render(DrawContext ctx, float tickDelta) {
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
if (client.player == null || client.options.hudHidden) return;
|
||||
if (!hasFullChipperArmor(client.player)) return;
|
||||
|
||||
Float value = client.player.getDataTracker().get(CHIPI_ENERGY);
|
||||
if (value == null) return;
|
||||
|
||||
value = Math.max(0f, Math.min(1f, value));
|
||||
|
||||
int screenWidth = client.getWindow().getScaledWidth();
|
||||
int screenHeight = client.getWindow().getScaledHeight();
|
||||
|
||||
int barWidth = (int)(80 * 0.8f);
|
||||
int centerX = screenWidth / 2;
|
||||
int left = centerX - barWidth / 2;
|
||||
int right = left + barWidth;
|
||||
|
||||
int heartsY = screenHeight - 39;
|
||||
int barY = heartsY - BAR_HEIGHT - 4;
|
||||
|
||||
int fillWidth = (int)(barWidth * value);
|
||||
|
||||
float alpha = value >= 1f ? 0.65f :
|
||||
value < 0.10f
|
||||
? (float)(0.6f + 0.4f * Math.sin(System.currentTimeMillis() / 120.0))
|
||||
: 1f;
|
||||
|
||||
int outlineDark = applyAlpha(OUTLINE_DARK, alpha);
|
||||
int outlineLight = applyAlpha(OUTLINE_LIGHT, alpha);
|
||||
int fillColor = applyAlpha(ORANGE, alpha);
|
||||
|
||||
ctx.fill(left - 1, barY - 1, right + 1, barY, outlineDark);
|
||||
ctx.fill(left - 1, barY + BAR_HEIGHT, right + 1, barY + BAR_HEIGHT + 1, outlineLight);
|
||||
ctx.fill(left - 1, barY, left, barY + BAR_HEIGHT, outlineDark);
|
||||
ctx.fill(right, barY, right + 1, barY + BAR_HEIGHT, outlineLight);
|
||||
ctx.fill(left, barY, left + fillWidth, barY + BAR_HEIGHT, fillColor);
|
||||
|
||||
ctx.drawText(
|
||||
client.textRenderer,
|
||||
String.format("%03d%%", Math.round(value * 100f)),
|
||||
right + 6,
|
||||
barY - 2,
|
||||
fillColor,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
private static int applyAlpha(int color, float alpha) {
|
||||
int a = (int)(((color >> 24) & 0xFF) * alpha);
|
||||
return (a << 24) | (color & 0x00FFFFFF);
|
||||
}
|
||||
|
||||
private static boolean hasFullChipperArmor(PlayerEntity player) {
|
||||
PlayerInventory inv = player.getInventory();
|
||||
return inv.getArmorStack(3).isOf(ModItems.CHIPPER_HELMET)
|
||||
&& inv.getArmorStack(2).isOf(ModItems.CHIPPER_CHESTPLATE)
|
||||
&& inv.getArmorStack(1).isOf(ModItems.CHIPPER_LEGGINGS)
|
||||
&& inv.getArmorStack(0).isOf(ModItems.CHIPPER_BOOTS);
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,7 @@ import net.minecraft.util.Identifier;
|
||||
import net.Chipperfluff.chipi.item.tool.ChipperToolMaterial;
|
||||
import net.Chipperfluff.chipi.item.MepMilkItem;
|
||||
import net.minecraft.item.Items;
|
||||
import net.Chipperfluff.chipi.item.armor.ChipperArmorItem;
|
||||
|
||||
public class ModItems {
|
||||
|
||||
@ -94,25 +95,25 @@ public class ModItems {
|
||||
public static final Item CHIPPER_HELMET = Registry.register(
|
||||
Registries.ITEM,
|
||||
new Identifier(ChipiMod.MOD_ID, "chipper_helmet"),
|
||||
new ArmorItem(ChipperArmorMaterial.INSTANCE, ArmorItem.Type.HELMET, new Item.Settings())
|
||||
new ChipperArmorItem(ChipperArmorMaterial.INSTANCE, ArmorItem.Type.HELMET, new Item.Settings())
|
||||
);
|
||||
|
||||
public static final Item CHIPPER_CHESTPLATE = Registry.register(
|
||||
Registries.ITEM,
|
||||
new Identifier(ChipiMod.MOD_ID, "chipper_chestplate"),
|
||||
new ArmorItem(ChipperArmorMaterial.INSTANCE, ArmorItem.Type.CHESTPLATE, new Item.Settings())
|
||||
new ChipperArmorItem(ChipperArmorMaterial.INSTANCE, ArmorItem.Type.CHESTPLATE, new Item.Settings())
|
||||
);
|
||||
|
||||
public static final Item CHIPPER_LEGGINGS = Registry.register(
|
||||
Registries.ITEM,
|
||||
new Identifier(ChipiMod.MOD_ID, "chipper_leggings"),
|
||||
new ArmorItem(ChipperArmorMaterial.INSTANCE, ArmorItem.Type.LEGGINGS, new Item.Settings())
|
||||
new ChipperArmorItem(ChipperArmorMaterial.INSTANCE, ArmorItem.Type.LEGGINGS, new Item.Settings())
|
||||
);
|
||||
|
||||
public static final Item CHIPPER_BOOTS = Registry.register(
|
||||
Registries.ITEM,
|
||||
new Identifier(ChipiMod.MOD_ID, "chipper_boots"),
|
||||
new ArmorItem(ChipperArmorMaterial.INSTANCE, ArmorItem.Type.BOOTS, new Item.Settings())
|
||||
new ChipperArmorItem(ChipperArmorMaterial.INSTANCE, ArmorItem.Type.BOOTS, new Item.Settings())
|
||||
);
|
||||
|
||||
// ===== TOOLS =====
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
package net.Chipperfluff.chipi.item.armor;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.item.ArmorItem;
|
||||
import net.minecraft.item.ArmorMaterial;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ChipperArmorItem extends ArmorItem {
|
||||
|
||||
public ChipperArmorItem(
|
||||
ArmorMaterial material,
|
||||
Type type,
|
||||
Settings settings
|
||||
) {
|
||||
super(material, type, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inventoryTick(
|
||||
ItemStack stack,
|
||||
World world,
|
||||
Entity entity,
|
||||
int slot,
|
||||
boolean selected
|
||||
) {
|
||||
if (slot >= EquipmentSlot.FEET.getEntitySlotId()
|
||||
&& slot <= EquipmentSlot.HEAD.getEntitySlotId()) {
|
||||
|
||||
if (stack.getDamage() != 0) {
|
||||
stack.setDamage(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -18,16 +18,16 @@ public class ChipperArmorMaterial implements ArmorMaterial {
|
||||
private static final Map<ArmorItem.Type, Integer> PROTECTION = Util.make(
|
||||
new EnumMap<>(ArmorItem.Type.class),
|
||||
map -> {
|
||||
map.put(ArmorItem.Type.HELMET, 2);
|
||||
map.put(ArmorItem.Type.CHESTPLATE, 5);
|
||||
map.put(ArmorItem.Type.LEGGINGS, 4);
|
||||
map.put(ArmorItem.Type.BOOTS, 2);
|
||||
map.put(ArmorItem.Type.HELMET, 0);
|
||||
map.put(ArmorItem.Type.CHESTPLATE, 0);
|
||||
map.put(ArmorItem.Type.LEGGINGS, 0);
|
||||
map.put(ArmorItem.Type.BOOTS, 0);
|
||||
}
|
||||
);
|
||||
|
||||
@Override
|
||||
public int getDurability(ArmorItem.Type type) {
|
||||
return 3 * type.getEquipmentSlot().getEntitySlotId();
|
||||
return 10_000;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -57,11 +57,11 @@ public class ChipperArmorMaterial implements ArmorMaterial {
|
||||
|
||||
@Override
|
||||
public float getToughness() {
|
||||
return 2.0f;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getKnockbackResistance() {
|
||||
return 0.4f;
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
package net.Chipperfluff.chipi.mixin;
|
||||
|
||||
import net.minecraft.entity.data.DataTracker;
|
||||
import net.minecraft.entity.data.TrackedData;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(DataTracker.class)
|
||||
public abstract class DataTrackerMixin {
|
||||
|
||||
@Shadow
|
||||
protected abstract <T> DataTracker.Entry<T> getEntry(TrackedData<T> data);
|
||||
|
||||
@Inject(method = "get", at = @At("HEAD"), cancellable = true)
|
||||
private <T> void chipi$nullSafeGet(
|
||||
TrackedData<T> data,
|
||||
CallbackInfoReturnable<T> cir
|
||||
) {
|
||||
DataTracker.Entry<T> entry = this.getEntry(data);
|
||||
|
||||
if (entry == null) {
|
||||
cir.setReturnValue(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package net.Chipperfluff.chipi.mixin;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.Chipperfluff.chipi.util.ChipiTrackedData;
|
||||
import net.minecraft.entity.data.DataTracker;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(PlayerEntity.class)
|
||||
public abstract class PlayerEntityMixin {
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void chipi$initTrackedData(
|
||||
World world,
|
||||
BlockPos pos,
|
||||
float yaw,
|
||||
GameProfile profile,
|
||||
CallbackInfo ci
|
||||
) {
|
||||
PlayerEntity self = (PlayerEntity)(Object)this;
|
||||
DataTracker tracker = self.getDataTracker();
|
||||
|
||||
tracker.startTracking(ChipiTrackedData.CHIPI_ENERGY, 1.0f);
|
||||
}
|
||||
}
|
||||
@ -1,30 +1,40 @@
|
||||
package net.Chipperfluff.chipi.server;
|
||||
|
||||
import net.Chipperfluff.chipi.block.ChipperPortalBlock;
|
||||
import net.Chipperfluff.chipi.world.gen.ChipiDungeonGenerator;
|
||||
import net.Chipperfluff.chipi.SpawnPlacedState;
|
||||
|
||||
import net.Chipperfluff.chipi.block.ChipperPortalBlock;
|
||||
import net.Chipperfluff.chipi.item.ModItems;
|
||||
import net.Chipperfluff.chipi.world.gen.ChipiDungeonGenerator;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.SlabBlock;
|
||||
import net.minecraft.block.StairsBlock;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.structure.StructurePlacementData;
|
||||
import net.minecraft.structure.StructureTemplate;
|
||||
import net.minecraft.state.property.Properties;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import static net.Chipperfluff.chipi.util.ChipiTrackedData.CHIPI_ENERGY;
|
||||
|
||||
public final class ChipiServerEvents {
|
||||
|
||||
public static final RegistryKey<World> CHIPI_DIMENSION_KEY =
|
||||
RegistryKey.of(RegistryKeys.WORLD, new Identifier("chipi", "chipi_dimension"));
|
||||
|
||||
private static final float RECHARGE_RATE = 0.0005f;
|
||||
private static final float DRAIN_RATE = 0.0008f;
|
||||
|
||||
private static final Identifier SPAWN_STRUCTURE =
|
||||
new Identifier("chipi", "spawn");
|
||||
|
||||
@ -33,38 +43,52 @@ public final class ChipiServerEvents {
|
||||
private ChipiServerEvents() {}
|
||||
|
||||
public static void register() {
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
||||
SERVER = server;
|
||||
});
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> SERVER = server);
|
||||
ServerTickEvents.END_SERVER_TICK.register(ChipiServerEvents::tickEnergy);
|
||||
ServerTickEvents.END_WORLD_TICK.register(ChipiServerEvents::handleVoidFailsafe);
|
||||
|
||||
ServerWorldEvents.LOAD.register(ChipiServerEvents::onWorldLoad);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Tick logic
|
||||
// ============================================================
|
||||
private static void tickEnergy(MinecraftServer server) {
|
||||
for (ServerPlayerEntity player : server.getPlayerManager().getPlayerList()) {
|
||||
|
||||
if (!hasFullChipperArmor(player)) continue;
|
||||
|
||||
Float value = player.getDataTracker().get(CHIPI_ENERGY);
|
||||
if (value == null) continue; // ultra-safe, but should never happen now
|
||||
|
||||
boolean inChipi = player.getWorld().getRegistryKey().equals(CHIPI_DIMENSION_KEY);
|
||||
boolean onProtected = isOnProtectedBlock(player);
|
||||
|
||||
float next = value;
|
||||
|
||||
if (!inChipi || onProtected) {
|
||||
next = Math.min(1.0f, value + RECHARGE_RATE);
|
||||
} else {
|
||||
next = Math.max(0.0f, value - DRAIN_RATE);
|
||||
}
|
||||
|
||||
if (next != value) {
|
||||
player.getDataTracker().set(CHIPI_ENERGY, next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleVoidFailsafe(ServerWorld world) {
|
||||
if (!world.getRegistryKey().equals(CHIPI_DIMENSION_KEY)) return;
|
||||
|
||||
for (PlayerEntity player : world.getPlayers()) {
|
||||
if (player.getBlockY() >= 50) continue;
|
||||
if (player.getBlockY() < 50) {
|
||||
ChipperPortalBlock.teleportToChipiSpawn(world, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// World init
|
||||
// ============================================================
|
||||
private static void onWorldLoad(MinecraftServer server, ServerWorld world) {
|
||||
if (!world.getRegistryKey().equals(CHIPI_DIMENSION_KEY)) return;
|
||||
|
||||
world.setTimeOfDay(18000);
|
||||
world.getGameRules()
|
||||
.get(GameRules.DO_DAYLIGHT_CYCLE)
|
||||
.set(false, server);
|
||||
world.getGameRules().get(GameRules.DO_DAYLIGHT_CYCLE).set(false, server);
|
||||
|
||||
SpawnPlacedState state = world.getPersistentStateManager().getOrCreate(
|
||||
SpawnPlacedState::fromNbt,
|
||||
@ -75,14 +99,9 @@ public final class ChipiServerEvents {
|
||||
if (state.placed) return;
|
||||
|
||||
StructureTemplate spawnTemplate =
|
||||
world.getStructureTemplateManager()
|
||||
.getTemplate(SPAWN_STRUCTURE)
|
||||
.orElse(null);
|
||||
world.getStructureTemplateManager().getTemplate(SPAWN_STRUCTURE).orElse(null);
|
||||
|
||||
if (spawnTemplate == null) {
|
||||
System.err.println("[CHIPI] spawn.nbt not found!");
|
||||
return;
|
||||
}
|
||||
if (spawnTemplate == null) return;
|
||||
|
||||
BlockPos spawnCenter = new BlockPos(0, 80, 0);
|
||||
|
||||
@ -96,20 +115,33 @@ public final class ChipiServerEvents {
|
||||
);
|
||||
|
||||
world.setSpawnPos(spawnCenter.up(), 0.0f);
|
||||
|
||||
ChipiDungeonGenerator.generateInitialLayout(world, spawnCenter);
|
||||
|
||||
state.placed = true;
|
||||
state.markDirty();
|
||||
|
||||
System.out.println("[CHIPI] Spawn + initial dungeon generated");
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Access
|
||||
// ============================================================
|
||||
public static ServerWorld getChipiWorld() {
|
||||
if (SERVER == null) return null;
|
||||
return SERVER.getWorld(CHIPI_DIMENSION_KEY);
|
||||
return SERVER == null ? null : SERVER.getWorld(CHIPI_DIMENSION_KEY);
|
||||
}
|
||||
|
||||
private static boolean hasFullChipperArmor(PlayerEntity player) {
|
||||
PlayerInventory inv = player.getInventory();
|
||||
return inv.getArmorStack(3).isOf(ModItems.CHIPPER_HELMET)
|
||||
&& inv.getArmorStack(2).isOf(ModItems.CHIPPER_CHESTPLATE)
|
||||
&& inv.getArmorStack(1).isOf(ModItems.CHIPPER_LEGGINGS)
|
||||
&& inv.getArmorStack(0).isOf(ModItems.CHIPPER_BOOTS);
|
||||
}
|
||||
|
||||
private static boolean isOnProtectedBlock(PlayerEntity player) {
|
||||
BlockPos pos = player.getBlockPos();
|
||||
BlockState state = player.getWorld().getBlockState(pos);
|
||||
|
||||
if (!state.contains(Properties.WATERLOGGED) || !state.get(Properties.WATERLOGGED)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return state.getBlock() instanceof StairsBlock
|
||||
|| state.getBlock() instanceof SlabBlock;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
package net.Chipperfluff.chipi.util;
|
||||
|
||||
import net.minecraft.entity.data.DataTracker;
|
||||
import net.minecraft.entity.data.TrackedData;
|
||||
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
||||
public final class ChipiTrackedData {
|
||||
|
||||
public static final TrackedData<Float> CHIPI_ENERGY =
|
||||
DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||
|
||||
private ChipiTrackedData() {}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package net.Chipperfluff.chipi.util;
|
||||
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ClientTickScheduler {
|
||||
|
||||
private static final List<ScheduledTask> TASKS = new LinkedList<>();
|
||||
private static boolean registered = false;
|
||||
|
||||
public static void init() {
|
||||
if (registered) return;
|
||||
registered = true;
|
||||
|
||||
ClientTickEvents.END_CLIENT_TICK.register(ClientTickScheduler::tick);
|
||||
}
|
||||
|
||||
public static void schedule(int delayTicks, Runnable action) {
|
||||
TASKS.add(new ScheduledTask(delayTicks, action));
|
||||
}
|
||||
|
||||
private static void tick(MinecraftClient client) {
|
||||
Iterator<ScheduledTask> it = TASKS.iterator();
|
||||
while (it.hasNext()) {
|
||||
ScheduledTask task = it.next();
|
||||
task.ticks--;
|
||||
|
||||
if (task.ticks <= 0) {
|
||||
try {
|
||||
task.action.run();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ScheduledTask {
|
||||
int ticks;
|
||||
Runnable action;
|
||||
|
||||
ScheduledTask(int ticks, Runnable action) {
|
||||
this.ticks = ticks;
|
||||
this.action = action;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,8 @@
|
||||
"package": "net.Chipperfluff.chipi.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"DataTrackerMixin",
|
||||
"PlayerEntityMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user