Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.wintercogs.beyonddimensions.api.storage.key.impl.EnergyStackKey;
import com.wintercogs.beyonddimensions.api.storage.key.impl.FluidStackKey;
import com.wintercogs.beyonddimensions.api.storage.key.impl.ItemStackKey;
import com.wintercogs.beyonddimensions.api.storage.key.impl.PigStackKey;
import com.wintercogs.beyonddimensions.common.init.*;
import com.wintercogs.beyonddimensions.integration.IntegrationManager;
import net.minecraft.resources.ResourceLocation;
Expand Down Expand Up @@ -66,6 +67,7 @@ private void commonSetup(final FMLCommonSetupEvent event)
StackKeyRegistry.registerType(ItemStackKey.EMPTY);
StackKeyRegistry.registerType(FluidStackKey.EMPTY);
StackKeyRegistry.registerType(EnergyStackKey.INSTANCE);
StackKeyRegistry.registerType(PigStackKey.INSTANCE);

// 注册方块能力类型,用于动态为方块注册能力
CapabilityHelper.BlockCapabilityMap.put(ItemStackKey.ID, Capabilities.ItemHandler.BLOCK);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.wintercogs.beyonddimensions.api.storage.key.KeyAmount;
import com.wintercogs.beyonddimensions.api.storage.key.impl.EnergyStackKey;
import com.wintercogs.beyonddimensions.api.storage.key.impl.ItemStackKey;
import com.wintercogs.beyonddimensions.api.storage.key.impl.PigStackKey;
import com.wintercogs.beyonddimensions.common.init.BDItems;
import com.wintercogs.beyonddimensions.config.ServerConfigRuntime;
import com.wintercogs.beyonddimensions.util.PlayerNameHelper;
Expand All @@ -16,6 +17,7 @@
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.saveddata.SavedData;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.neoforge.common.NeoForge;
Expand Down Expand Up @@ -93,6 +95,13 @@ public class DimensionsNet extends SavedData
*/
private int currentTime = 0;

/**
* 维度养猪场繁殖进度。正常猪被喂食后约需5分钟才能再次繁殖,
* 因此网络每6000 tick消耗两根胡萝卜并增加一只猪。
*/
private int pigBreedingTime = 0;
private static final int PIG_BREEDING_INTERVAL = 6000;

/**
* 构造函数
*
Expand Down Expand Up @@ -380,6 +389,7 @@ public static DimensionsNet load(CompoundTag tag, HolderLookup.Provider registry

// 读取倒计时
net.currentTime = tag.getInt("currentTime");
net.pigBreedingTime = tag.getInt("pigBreedingTime");

if (tag.contains("Deleted"))
net.deleted = tag.getBoolean("Deleted");
Expand Down Expand Up @@ -428,6 +438,7 @@ public static DimensionsNet load(CompoundTag tag, HolderLookup.Provider registry

// 保存倒计时
tag.putInt("currentTime", this.currentTime);
tag.putInt("pigBreedingTime", this.pigBreedingTime);

// 保存删除状态
tag.putBoolean("Deleted", this.deleted);
Expand Down Expand Up @@ -725,9 +736,11 @@ else if (isManager(playerId))
@SubscribeEvent
public void onServerTick(ServerTickEvent.Pre event)
{
// 不对临时网络执行倒计时
if (temporary || ServerConfigRuntime.crystalGenerateTime <= 0)
return;
if (temporary) return;

tickPigBreeding();

if (ServerConfigRuntime.crystalGenerateTime <= 0) return;

currentTime++;
setDirty();
Expand All @@ -737,7 +750,40 @@ public void onServerTick(ServerTickEvent.Pre event)
this.unifiedStorage.insert(new ItemStackKey(stack), stack.getCount(), false);
currentTime = 0;
}
}

private void tickPigBreeding()
{
long pigs = unifiedStorage.getStackByKey(PigStackKey.INSTANCE).amount();
ItemStack carrot = new ItemStack(Items.CARROT);
ItemStackKey carrotKey = new ItemStackKey(carrot);
long carrots = unifiedStorage.getStackByKey(carrotKey).amount();

if (pigs < 2 || carrots < 2)
{
if (pigBreedingTime != 0)
{
pigBreedingTime = 0;
setDirty();
}
return;
}

pigBreedingTime++;
if (pigBreedingTime % 20 == 0) setDirty();
if (pigBreedingTime < PIG_BREEDING_INTERVAL) return;

long requestedBirths = Math.min(pigs / 2, carrots / 2);
long remainder = unifiedStorage.insert(PigStackKey.INSTANCE, requestedBirths, true).amount();
long births = requestedBirths - remainder;
if (births <= 0) return;

long carrotCost = births * 2;
KeyAmount extracted = unifiedStorage.extract(carrotKey, carrotCost, false, false);
if (extracted.amount() != carrotCost) return;

unifiedStorage.insert(PigStackKey.INSTANCE, births, false);
pigBreedingTime = 0;
}

private void syncPlayerMembership(UUID playerId, boolean switchPrimary)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.wintercogs.beyonddimensions.api.longtype;

import com.mojang.serialization.Codec;
import net.minecraft.network.chat.Component;

public final class PigType extends LongType<PigType>
{
public static final Codec<PigType> CODEC = createCodec(PigType::new);

public PigType(long amount)
{
this.stackCount = amount;
}

@Override
public Component getName()
{
return Component.translatable("types.beyonddimensions.pig.name");
}

@Override
public PigType getEmpty()
{
return new PigType(0);
}

@Override
public PigType copy()
{
return new PigType(stackCount);
}

@Override
public PigType copyWithAmount(long amount)
{
return new PigType(amount);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package com.wintercogs.beyonddimensions.api.storage.key.impl;

import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.MapCodec;
import com.wintercogs.beyonddimensions.api.ids.BDConstants;
import com.wintercogs.beyonddimensions.api.longtype.PigType;
import com.wintercogs.beyonddimensions.api.storage.key.IStackRender;
import com.wintercogs.beyonddimensions.api.storage.key.KeyAmount;
import com.wintercogs.beyonddimensions.api.storage.key.render.PigStackKeyRender;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.stream.Stream;

public final class PigStackKey extends LongStackKey<PigType>
{
public static final ResourceLocation ID =
ResourceLocation.fromNamespaceAndPath(BDConstants.MODID, "stack_type/pig");
public static final PigStackKey INSTANCE = new PigStackKey();

public static final MapCodec<PigStackKey> TYPE_CODEC = new MapCodec<>()
{
@Override
public <T> DataResult<PigStackKey> decode(com.mojang.serialization.DynamicOps<T> ops,
com.mojang.serialization.MapLike<T> input)
{
return DataResult.success(INSTANCE);
}

@Override
public <T> com.mojang.serialization.RecordBuilder<T> encode(PigStackKey value,
com.mojang.serialization.DynamicOps<T> ops,
com.mojang.serialization.RecordBuilder<T> prefix)
{
return prefix;
}

@Override
public <T> Stream<T> keys(com.mojang.serialization.DynamicOps<T> ops)
{
return Stream.empty();
}
};

public static final Codec<PigStackKey> CODEC = TYPE_CODEC.codec();

private PigStackKey()
{
this.stack = new PigType(0);
}

@Override
public ResourceLocation getTypeID()
{
return ID;
}

@Override
public MapCodec<PigStackKey> codec()
{
return TYPE_CODEC;
}

@Override
public @Nullable KeyAmount fromStackObject(Object stack)
{
return stack instanceof PigType pig ? new KeyAmount(INSTANCE, pig.getStackCount()) : null;
}

@Override
public @Nullable PigStackKey fromSourceObject(Object key, DataComponentPatch ignored)
{
return key instanceof PigType || key instanceof Number ? INSTANCE : null;
}

@Override
public @NotNull PigType getSource()
{
return stack;
}

@Override
public String getModId()
{
return "Minecraft";
}

@Override
public PigStackKey getEmpty()
{
return INSTANCE;
}

@Override
public PigType getEmptyStack()
{
return new PigType(0);
}

@Override
public boolean hasTag(TagKey<?> tagKey)
{
return false;
}

@Override
public Stream<? extends TagKey<?>> getTags()
{
return Stream.empty();
}

@Override
public void serialize(RegistryFriendlyByteBuf buf)
{
}

@Override
public @NotNull PigStackKey deserialize(RegistryFriendlyByteBuf buf)
{
return INSTANCE;
}

@Override
public @NotNull CompoundTag serializeNBT(HolderLookup.Provider access)
{
return new CompoundTag();
}

@Override
public @NotNull PigStackKey deserializeNBT(CompoundTag nbt, HolderLookup.Provider access)
{
return INSTANCE;
}

@Override
public @NotNull IStackRender getRender()
{
return PigStackKeyRender.INSTANCE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.wintercogs.beyonddimensions.api.storage.key.render;

import com.mojang.blaze3d.systems.RenderSystem;
import com.wintercogs.beyonddimensions.api.storage.key.IStackKey;
import com.wintercogs.beyonddimensions.api.storage.key.IStackRender;
import com.wintercogs.beyonddimensions.api.storage.key.impl.PigStackKey;
import com.wintercogs.beyonddimensions.util.StringFormat;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.Items;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.neoforged.neoforge.client.ClientTooltipFlag;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Optional;

public final class PigStackKeyRender implements IStackRender
{
public static final PigStackKeyRender INSTANCE = new PigStackKeyRender();

private PigStackKeyRender()
{
}

@Override
public void render(GuiGraphics gui, IStackKey<?> key, int x, int y)
{
gui.renderFakeItem(new ItemStack(Items.PIG_SPAWN_EGG), x, y);
}

@Override
public void renderAmount(GuiGraphics gui, long amount, int x, int y)
{
String text = getCountText(amount);
if (text.isEmpty()) return;

float scale = 0.666f;
var pose = gui.pose();
pose.pushPose();
pose.translate(0, 0, 200);
pose.scale(scale, scale, scale);
RenderSystem.disableBlend();
int width = Minecraft.getInstance().font.width(text);
int renderX = (int) ((x - 1 + 18.0f - width * scale) / scale);
int renderY = (int) ((y - 1 + 16.0f - 5.0f * scale) / scale);
gui.drawString(Minecraft.getInstance().font, text, renderX, renderY, 0xFFFFFF);
pose.popPose();
}

@Override
public String getCountText(long count)
{
return count < 0 ? "" : StringFormat.formatCount(count);
}

@Override
public Component getDisplayName(IStackKey<?> key)
{
return PigStackKey.INSTANCE.getRenderStack().getName();
}

@Override
public List<Component> getTooltipLines(IStackKey<?> key, long amount, Item.TooltipContext context,
@Nullable net.minecraft.world.entity.player.Player player,
TooltipFlag flag)
{
return List.of(getDisplayName(key),
Component.translatable("istack.beyonddimensions.storage_num.long_type", amount));
}

@Override
public Optional<TooltipComponent> getTooltipImage(IStackKey<?> key)
{
return Optional.empty();
}

@Override
public void renderTooltip(GuiGraphics gui, Font font, IStackKey<?> key, long amount, int mouseX, int mouseY)
{
var minecraft = Minecraft.getInstance();
var context = minecraft.level == null ? Item.TooltipContext.EMPTY : Item.TooltipContext.of(minecraft.level);
gui.renderTooltip(minecraft.font,
getTooltipLines(key, amount, context, minecraft.player,
ClientTooltipFlag.of(minecraft.options.advancedItemTooltips
? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL)),
getTooltipImage(key), ItemStack.EMPTY, mouseX, mouseY);
}
}
Loading