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(ManagementModule.class);
|
||||
registerFeature(AFKModule.class);
|
||||
registerFeature(FartFertilizerModule.class);
|
||||
registerFeature(ChatPingModule.class);
|
||||
registerFeature(ChatSendLocModule.class);
|
||||
registerFeature(LongNightModule.class);
|
||||
|
||||
@@ -31,6 +31,12 @@ public interface SFCallbacks {
|
||||
l -> (s, c) -> first(l, t -> t.onMotd(s, c)));
|
||||
Event<PlayerIdlingCallback> PLAYER_IDLE = EventFactory.createArrayBacked(PlayerIdlingCallback.class,
|
||||
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 {
|
||||
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.playSoundToPlayer(
|
||||
SoundEvent.of(SoundEvents.ENTITY_ITEM_PICKUP.getId()),
|
||||
SoundEvents.ENTITY_ITEM_PICKUP,
|
||||
SoundCategory.PLAYERS,
|
||||
0.8f,
|
||||
0.5f
|
||||
|
||||
@@ -5,6 +5,10 @@ import io.ib67.sfcraft.SFCraft;
|
||||
import io.ib67.sfcraft.config.SFConfig;
|
||||
import io.ib67.sfcraft.geoip.GeoIPService;
|
||||
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.LavaFluid;
|
||||
import net.minecraft.fluid.WaterFluid;
|
||||
@@ -93,4 +97,9 @@ public class Helper {
|
||||
public static int fromRgb(int r, int g, int b) {
|
||||
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.SleepManagerMixin",
|
||||
"server.ServerWorldMixin",
|
||||
"server.EntityMixin",
|
||||
"server.AbstractFurnaceBlockMixin",
|
||||
"server.ServerHandshakeNetworkHandlerMixin",
|
||||
"server.LegacyQueryHandlerMixin",
|
||||
|
||||
Reference in new issue
Block a user