add(feat): fertilize nearby sapling & crops by shifting continuously #8
This commit is contained in:
7 files changed
+110
-1
No files matched your search
@@ -44,6 +44,7 @@ public class SFCraftInitializer extends GuiceModInitializer {
|
|||||||
registerFeature(BackModule.class);
|
registerFeature(BackModule.class);
|
||||||
registerFeature(ManagementModule.class);
|
registerFeature(ManagementModule.class);
|
||||||
registerFeature(AFKModule.class);
|
registerFeature(AFKModule.class);
|
||||||
|
registerFeature(FartFertilizerModule.class);
|
||||||
registerFeature(ChatPingModule.class);
|
registerFeature(ChatPingModule.class);
|
||||||
registerFeature(ChatSendLocModule.class);
|
registerFeature(ChatSendLocModule.class);
|
||||||
registerFeature(LongNightModule.class);
|
registerFeature(LongNightModule.class);
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ public interface SFCallbacks {
|
|||||||
l -> (s, c) -> first(l, t -> t.onMotd(s, c)));
|
l -> (s, c) -> first(l, t -> t.onMotd(s, c)));
|
||||||
Event<PlayerIdlingCallback> PLAYER_IDLE = EventFactory.createArrayBacked(PlayerIdlingCallback.class,
|
Event<PlayerIdlingCallback> PLAYER_IDLE = EventFactory.createArrayBacked(PlayerIdlingCallback.class,
|
||||||
l -> (p, a) -> forEach(l, i -> i.onSwitchIdle(p, a)));
|
l -> (p, a) -> forEach(l, i -> i.onSwitchIdle(p, a)));
|
||||||
|
Event<PlayerSneakingCallback> PLAYER_SNEAKING = EventFactory.createArrayBacked(PlayerSneakingCallback.class,
|
||||||
|
l -> (p, a) -> forEach(l, i -> i.onSneaking(p, a)));
|
||||||
|
|
||||||
|
interface PlayerSneakingCallback {
|
||||||
|
void onSneaking(PlayerEntity player, boolean sneak);
|
||||||
|
}
|
||||||
|
|
||||||
interface PlayerIdlingCallback {
|
interface PlayerIdlingCallback {
|
||||||
void onSwitchIdle(ServerPlayerEntity player, boolean afk);
|
void onSwitchIdle(ServerPlayerEntity player, boolean afk);
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package io.ib67.sfcraft.mixin.server;
|
||||||
|
|
||||||
|
import io.ib67.sfcraft.callback.SFCallbacks;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(Entity.class)
|
||||||
|
public abstract class EntityMixin {
|
||||||
|
@Inject(method = "setSneaking", at = @At("HEAD"))
|
||||||
|
public void onSneaking(boolean sneaking, CallbackInfo ci) {
|
||||||
|
if ($this() instanceof PlayerEntity pe) {
|
||||||
|
SFCallbacks.PLAYER_SNEAKING.invoker().onSneaking(pe, sneaking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private Entity $this() {
|
||||||
|
return (Entity) (Object) this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package io.ib67.sfcraft.module;
|
||||||
|
|
||||||
|
import io.ib67.sfcraft.ServerModule;
|
||||||
|
import io.ib67.sfcraft.callback.SFCallbacks;
|
||||||
|
import io.ib67.sfcraft.util.Helper;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PlayerLookup;
|
||||||
|
import net.minecraft.block.Fertilizable;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.particle.ParticleTypes;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
|
||||||
|
public class FartFertilizerModule extends ServerModule {
|
||||||
|
private final Object2LongMap<PlayerEntity> lastSneaked = new Object2LongOpenHashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitialize() {
|
||||||
|
SFCallbacks.PLAYER_SNEAKING.register(this::onSneaking);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onSneaking(PlayerEntity player, boolean sneak) {
|
||||||
|
if (sneak) {
|
||||||
|
var lastSneak = lastSneaked.getOrDefault(player, 0);
|
||||||
|
var dlta = Math.min(System.currentTimeMillis() - lastSneak, 100);
|
||||||
|
if (player.getRandom().nextBetween(50, 150) > dlta) {
|
||||||
|
var playerPos = player.getBlockPos();
|
||||||
|
var start = playerPos.add(-2, 0, -2);
|
||||||
|
var end = playerPos.add(2, 1, 2);
|
||||||
|
for (int dX = 0; dX < end.getX() - start.getX(); dX++) {
|
||||||
|
for (int dZ = 0; dZ < end.getZ() - start.getZ(); dZ++) {
|
||||||
|
for (int dY = 0; dY < end.getY() - start.getY(); dY++) {
|
||||||
|
var blockPos = start.add(dX, dY, dZ);
|
||||||
|
var state = player.getWorld().getBlockState(blockPos);
|
||||||
|
var block = state.getBlock();
|
||||||
|
if (Helper.canFertilize(block)) {
|
||||||
|
var wld = (ServerWorld) player.getWorld();
|
||||||
|
wld.spawnParticles(
|
||||||
|
ParticleTypes.COMPOSTER,
|
||||||
|
blockPos.getX(), blockPos.getY(), blockPos.getZ(), 5,
|
||||||
|
Math.max(0.5, Math.random()), Math.max(0.5, Math.random()), Math.max(0.5, Math.random()),
|
||||||
|
0.4
|
||||||
|
);
|
||||||
|
for (ServerPlayerEntity serverPlayerEntity : PlayerLookup.around(wld, blockPos, 6f)) {
|
||||||
|
serverPlayerEntity.playSoundToPlayer(
|
||||||
|
SoundEvents.BLOCK_COMPOSTER_FILL,
|
||||||
|
SoundCategory.BLOCKS,
|
||||||
|
((6 - serverPlayerEntity.distanceTo(player) + 1) / 6) * 50,
|
||||||
|
3f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (player.getRandom().nextInt(10) < 3) {
|
||||||
|
((Fertilizable) block).grow(wld,
|
||||||
|
wld.getRandom(), blockPos, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastSneaked.put(player, System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,7 +55,7 @@ public class ChatPingModule extends ServerModule implements MessageDecorator {
|
|||||||
foundPlayer.sendMessage(Text.literal(sender.getName().getLiteralString() + " 正在叫你。").withColor(Colors.LIGHT_GRAY));
|
foundPlayer.sendMessage(Text.literal(sender.getName().getLiteralString() + " 正在叫你。").withColor(Colors.LIGHT_GRAY));
|
||||||
}
|
}
|
||||||
foundPlayer.playSoundToPlayer(
|
foundPlayer.playSoundToPlayer(
|
||||||
SoundEvent.of(SoundEvents.ENTITY_ITEM_PICKUP.getId()),
|
SoundEvents.ENTITY_ITEM_PICKUP,
|
||||||
SoundCategory.PLAYERS,
|
SoundCategory.PLAYERS,
|
||||||
0.8f,
|
0.8f,
|
||||||
0.5f
|
0.5f
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ import io.ib67.sfcraft.SFCraft;
|
|||||||
import io.ib67.sfcraft.config.SFConfig;
|
import io.ib67.sfcraft.config.SFConfig;
|
||||||
import io.ib67.sfcraft.geoip.GeoIPService;
|
import io.ib67.sfcraft.geoip.GeoIPService;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.CropBlock;
|
||||||
|
import net.minecraft.block.Fertilizable;
|
||||||
|
import net.minecraft.block.SaplingBlock;
|
||||||
import net.minecraft.fluid.EmptyFluid;
|
import net.minecraft.fluid.EmptyFluid;
|
||||||
import net.minecraft.fluid.LavaFluid;
|
import net.minecraft.fluid.LavaFluid;
|
||||||
import net.minecraft.fluid.WaterFluid;
|
import net.minecraft.fluid.WaterFluid;
|
||||||
@@ -93,4 +97,9 @@ public class Helper {
|
|||||||
public static int fromRgb(int r, int g, int b) {
|
public static int fromRgb(int r, int g, int b) {
|
||||||
return ((r & 0x0ff) << 16) | ((g & 0x0ff) << 8) | (b & 0x0ff);
|
return ((r & 0x0ff) << 16) | ((g & 0x0ff) << 8) | (b & 0x0ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean canFertilize(Block block) {
|
||||||
|
return block instanceof SaplingBlock
|
||||||
|
|| block instanceof CropBlock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
"server.ServerPlayNetworkHandlerMixin",
|
"server.ServerPlayNetworkHandlerMixin",
|
||||||
"server.SleepManagerMixin",
|
"server.SleepManagerMixin",
|
||||||
"server.ServerWorldMixin",
|
"server.ServerWorldMixin",
|
||||||
|
"server.EntityMixin",
|
||||||
"server.AbstractFurnaceBlockMixin",
|
"server.AbstractFurnaceBlockMixin",
|
||||||
"server.ServerHandshakeNetworkHandlerMixin",
|
"server.ServerHandshakeNetworkHandlerMixin",
|
||||||
"server.LegacyQueryHandlerMixin",
|
"server.LegacyQueryHandlerMixin",
|
||||||
|
|||||||
Reference in new issue
Block a user