Skip to content

Commit b3d346b

Browse files
committed
粒子对撞机工作(进度ui不显示,明天再看看)
1 parent a7b566c commit b3d346b

File tree

6 files changed

+190
-17
lines changed

6 files changed

+190
-17
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package top.ctnstudio.futurefood.api.recipe;
2+
3+
import net.minecraft.world.item.ItemStack;
4+
import net.minecraft.world.item.crafting.Ingredient;
5+
6+
public class ParticleColliderRecipe {
7+
private final Ingredient input1;
8+
private final Ingredient input2;
9+
private final ItemStack output;
10+
private final int energyCost;
11+
private final int processingTime;
12+
13+
public ParticleColliderRecipe(Ingredient input1, Ingredient input2, ItemStack output, int energyCost, int processingTime) {
14+
this.input1 = input1;
15+
this.input2 = input2;
16+
this.output = output.copy();
17+
this.energyCost = energyCost;
18+
this.processingTime = processingTime;
19+
}
20+
21+
public boolean matches(ItemStack inputStack1, ItemStack inputStack2) {
22+
// 检查两个输入是否匹配(顺序)
23+
return this.input1.test(inputStack1) && this.input2.test(inputStack2);
24+
}
25+
public boolean matchesReverse(ItemStack inputStack1, ItemStack inputStack2) {
26+
// 检查两个输入是否匹配(无序)
27+
return matches(inputStack1, inputStack2)||matches(inputStack2, inputStack1);
28+
}
29+
30+
public ItemStack getOutput() {
31+
return this.output.copy();
32+
}
33+
34+
public int getEnergyCost() {
35+
return this.energyCost;
36+
}
37+
38+
public int getProcessingTime() {
39+
return this.processingTime;
40+
}
41+
42+
public Ingredient getInput1() {
43+
return this.input1;
44+
}
45+
46+
public Ingredient getInput2() {
47+
return this.input2;
48+
}
49+
50+
public int getEnergyPerTick() {
51+
return this.energyCost / this.processingTime;
52+
}
53+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package top.ctnstudio.futurefood.api.recipe;
2+
3+
import net.minecraft.world.item.ItemStack;
4+
import net.minecraft.world.item.Items;
5+
import net.minecraft.world.item.crafting.Ingredient;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.Optional;
10+
11+
public class ParticleColliderRecipeManager {
12+
private static final List<ParticleColliderRecipe> RECIPES = new ArrayList<>();
13+
14+
/*
15+
* 添加配方(硬匹配),输入无序
16+
*/
17+
public static void initRecipes(){
18+
// 示例(测试用):
19+
addRecipe(new ParticleColliderRecipe(
20+
Ingredient.of(Items.IRON_INGOT),
21+
Ingredient.of(Items.GOLD_INGOT),
22+
new ItemStack(Items.DIAMOND, 1),
23+
0, // 能量消耗
24+
200 // 处理时间 (ticks)
25+
));
26+
addRecipe(new ParticleColliderRecipe(
27+
Ingredient.of(Items.GOLD_INGOT),
28+
Ingredient.of(Items.GOLD_INGOT),
29+
new ItemStack(Items.DIAMOND, 2),
30+
100, // 能量消耗
31+
100 // 处理时间 (ticks)
32+
));
33+
}
34+
public static void addRecipe(ParticleColliderRecipe recipe) {
35+
RECIPES.add(recipe);
36+
}
37+
38+
public static Optional<ParticleColliderRecipe> findRecipe(ItemStack input1, ItemStack input2){
39+
return RECIPES.stream()
40+
.filter(recipe -> recipe.matchesReverse(input1, input2))// 检查两个输入是否匹配(无序)
41+
.findFirst();
42+
}
43+
44+
public static List<ParticleColliderRecipe> getALLRecipes(){
45+
return new ArrayList<>(RECIPES);
46+
}
47+
}

src/main/java/top/ctnstudio/futurefood/client/gui/screen/ParticleColliderScreen.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ protected void init() {
3030
@Override
3131
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
3232
if (progressBar != null) {
33-
progressBar.setTick(menu.getEnergy(), menu.getMaxEnergy());
33+
progressBar.setTick(menu.getRemainingTick(), menu.getMaxWorkTick());
3434
}
3535
super.render(guiGraphics, mouseX, mouseY, partialTick);
3636
}
3737

3838
@Override
3939
protected void containerTick() {
4040
if (progressBar != null) {
41-
progressBar.setTick(menu.getEnergy(), menu.getMaxEnergy());
41+
progressBar.setTick(menu.getRemainingTick(), menu.getMaxWorkTick());
4242
}
4343
super.containerTick();
4444
}
@@ -59,8 +59,8 @@ public void setMaxWorkTick(int maxWorkTick) {
5959
this.maxWorkTick = maxWorkTick;
6060
}
6161

62-
public void setTick(int energy, int maxTick) {
63-
this.remainingTick = energy;
62+
public void setTick(int remainingTick, int maxTick) {
63+
this.remainingTick = remainingTick;
6464
this.maxWorkTick = maxTick;
6565
}
6666

src/main/java/top/ctnstudio/futurefood/common/block/tile/ParticleColliderBlockEntity.java

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import net.minecraft.world.entity.player.Inventory;
88
import net.minecraft.world.entity.player.Player;
99
import net.minecraft.world.inventory.ContainerData;
10+
import net.minecraft.world.item.ItemStack;
1011
import net.minecraft.world.level.Level;
1112
import net.minecraft.world.level.block.state.BlockState;
1213
import net.neoforged.neoforge.energy.IEnergyStorage;
@@ -20,16 +21,25 @@
2021
import software.bernie.geckolib.util.GeckoLibUtil;
2122
import top.ctnstudio.futurefood.api.adapter.ModEnergyStorage;
2223
import top.ctnstudio.futurefood.api.block.IUnlimitedEntityReceive;
24+
import top.ctnstudio.futurefood.api.recipe.ParticleColliderRecipe;
25+
import top.ctnstudio.futurefood.api.recipe.ParticleColliderRecipeManager;
2326
import top.ctnstudio.futurefood.common.menu.ParticleColliderMenu;
2427
import top.ctnstudio.futurefood.core.init.ModTileEntity;
2528

29+
import java.util.Optional;
30+
2631
// TODO 自定义配方
2732
public class ParticleColliderBlockEntity extends EnergyStorageBlockEntity<ParticleColliderMenu>
2833
implements GeoBlockEntity, IUnlimitedEntityReceive {
2934
protected static final RawAnimation DEPLOY_ANIM = RawAnimation.begin();
3035

3136
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
3237

38+
// 槽位
39+
public static final int INPUT_SLOT_1 = 1;
40+
public static final int INPUT_SLOT_2 = 2;
41+
public static final int OUTPUT_SLOT = 3;
42+
3343
private final WorkTick workTick;
3444
// 使用包装类以实现同步
3545
private final WorkProgress workProgress;
@@ -46,6 +56,7 @@ public void tick(@NotNull Level level, @NotNull BlockPos pos, @NotNull BlockStat
4656
return;
4757
}
4858
controlItemEnergy(itemHandler, false);
59+
this.processRecipe();
4960
}
5061

5162
@Override
@@ -81,7 +92,7 @@ public IEnergyStorage getEnergyStorage() {
8192
@Override
8293
protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider provider) {
8394
super.loadAdditional(nbt, provider);
84-
if (nbt.contains("remainingTick")) setRemainingTick(nbt.getInt("remainingTick"));
95+
if (nbt.contains("processTick")) setProcessTick(nbt.getInt("processTick"));
8596
if (nbt.contains("maxWorkTick")) setMaxWorkTick(nbt.getInt("maxWorkTick"));
8697
}
8798

@@ -91,15 +102,15 @@ protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider provider) {
91102
@Override
92103
protected void saveAdditional(CompoundTag nbt, HolderLookup.Provider provider) {
93104
super.saveAdditional(nbt, provider);
94-
nbt.putInt("remainingTick", getRemainingTick());
105+
nbt.putInt("processTick", getProcessTick());
95106
nbt.putInt("maxWorkTick", getMaxWorkTick());
96107
}
97108

98-
public int getRemainingTick() {
99-
return workTick.getRemainingTick();
109+
public int getProcessTick() {
110+
return workTick.getProcessTick();
100111
}
101112

102-
public void setRemainingTick(int remainingTick) {
113+
public void setProcessTick(int remainingTick) {
103114
this.workTick.setMaxWorkTick(remainingTick);
104115
}
105116

@@ -123,7 +134,7 @@ public record WorkProgress(WorkTick workTick) implements ContainerData {
123134
@Override
124135
public int get(int index) {
125136
return switch (index) {
126-
case 0 -> workTick.getRemainingTick();
137+
case 0 -> workTick.getProcessTick();
127138
case 1 -> workTick.getMaxWorkTick();
128139
default -> 0;
129140
};
@@ -132,7 +143,7 @@ public int get(int index) {
132143
@Override
133144
public void set(int index, int value) {
134145
switch (index) {
135-
case 0 -> workTick.setRemainingTick(value);
146+
case 0 -> workTick.setProcessTick(value);
136147
case 1 -> workTick.setMaxWorkTick(value);
137148
}
138149
}
@@ -144,15 +155,15 @@ public int getCount() {
144155
}
145156

146157
public static class WorkTick {
147-
private int remainingTick;
158+
private int processTick;
148159
private int maxWorkTick;
149160

150-
public int getRemainingTick() {
151-
return remainingTick;
161+
public int getProcessTick() {
162+
return processTick;
152163
}
153164

154-
public void setRemainingTick(int remainingTick) {
155-
this.remainingTick = remainingTick;
165+
public void setProcessTick(int processTick) {
166+
this.processTick = processTick;
156167
}
157168

158169
public int getMaxWorkTick() {
@@ -163,4 +174,62 @@ public void setMaxWorkTick(int maxWorkTick) {
163174
this.maxWorkTick = maxWorkTick;
164175
}
165176
}
177+
178+
private void processRecipe() {
179+
ItemStack input1 = itemHandler.getStackInSlot(INPUT_SLOT_1);
180+
ItemStack input2 = itemHandler.getStackInSlot(INPUT_SLOT_2);
181+
182+
Optional<ParticleColliderRecipe> recipe = ParticleColliderRecipeManager.findRecipe(input1, input2);
183+
184+
if (recipe.isPresent()) {
185+
ParticleColliderRecipe currentRecipe = recipe.get();
186+
if(canCraft(currentRecipe)){
187+
workTick.setMaxWorkTick(currentRecipe.getProcessingTime());
188+
int energyPerTick = currentRecipe.getEnergyPerTick();
189+
190+
if(energyStorage.getEnergyStored() >= energyPerTick){
191+
energyStorage.extractEnergy(energyPerTick, false);
192+
workTick.processTick++;
193+
if(this.getProcessTick() >= this.getMaxWorkTick()){
194+
craftItem(currentRecipe);
195+
workTick.setProcessTick(0);
196+
}
197+
setChanged();
198+
}
199+
}else {
200+
workTick.setProcessTick(0);
201+
}
202+
}else {
203+
workTick.setProcessTick(0);
204+
}
205+
}
206+
207+
private boolean canCraft(ParticleColliderRecipe recipe) {
208+
if(recipe == null)return false;
209+
ItemStack output = itemHandler.getStackInSlot(OUTPUT_SLOT);
210+
ItemStack result = recipe.getOutput();
211+
212+
if(output.isEmpty())
213+
return true;
214+
if(!ItemStack.isSameItemSameComponents(output, result))
215+
return false;
216+
return output.getCount() + result.getCount() <= output.getMaxStackSize();
217+
}
218+
219+
private void craftItem(ParticleColliderRecipe recipe) {
220+
if(!canCraft(recipe))return;
221+
ItemStack result = recipe.getOutput();
222+
ItemStack output = itemHandler.getStackInSlot(OUTPUT_SLOT);
223+
224+
if(output.isEmpty()){
225+
itemHandler.setStackInSlot(OUTPUT_SLOT, result);
226+
}else {
227+
output.grow(result.getCount());
228+
}
229+
230+
itemHandler.extractItem(INPUT_SLOT_1, 1, false);
231+
itemHandler.extractItem(INPUT_SLOT_2, 1, false);
232+
233+
workTick.setProcessTick(0);
234+
}
166235
}

src/main/java/top/ctnstudio/futurefood/common/menu/ParticleColliderMenu.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public boolean mayPlace(ItemStack stack) {
4141
}
4242

4343
public int getRemainingTick() {
44-
return workProgress.get(0);
44+
return workProgress.get(1) - workProgress.get(0);
4545
}
4646

4747
public void setRemainingTick(int remainingTick) {

src/main/java/top/ctnstudio/futurefood/core/FutureFood.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import net.neoforged.fml.common.Mod;
88
import org.apache.logging.log4j.LogManager;
99
import org.apache.logging.log4j.Logger;
10+
import top.ctnstudio.futurefood.api.recipe.ParticleColliderRecipeManager;
1011
import top.ctnstudio.futurefood.core.init.*;
1112

1213
import javax.annotation.CheckForNull;
@@ -27,6 +28,9 @@ public FutureFood(IEventBus modEventBus, ModContainer modContainer) {
2728
ModTileEntity.TILES.register(modEventBus);
2829
ModCreativeModeTab.TABS.register(modEventBus);
2930
ModEffect.EFFECT.register(modEventBus);
31+
32+
//配方
33+
ParticleColliderRecipeManager.initRecipes();
3034
}
3135

3236
/**

0 commit comments

Comments
 (0)