Skip to content

Commit

Permalink
burn crafting
Browse files Browse the repository at this point in the history
  • Loading branch information
brachy84 committed Aug 20, 2023
1 parent 9df0bd9 commit 620318c
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 1 deletion.
6 changes: 6 additions & 0 deletions examples/postInit/in_world_crafting.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ inWorldCrafting.explosion.recipeBuilder()
.output(item('minecraft:nether_star'))
.chance(0.4f)
.register()

inWorldCrafting.burning.recipeBuilder()
.input(item('minecraft:netherrack'))
.output(item('minecraft:nether_star'))
//.ticks(40f)
.register()
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package com.cleanroommc.groovyscript.compat.inworldcrafting;

import com.cleanroommc.groovyscript.api.GroovyBlacklist;
import com.cleanroommc.groovyscript.api.GroovyLog;
import com.cleanroommc.groovyscript.api.IIngredient;
import com.cleanroommc.groovyscript.compat.vanilla.VanillaModule;
import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder;
import com.cleanroommc.groovyscript.registry.VirtualizedRegistry;
import com.cleanroommc.groovyscript.sandbox.ClosureHelper;
import groovy.lang.Closure;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

public class Burning extends VirtualizedRegistry<Burning.Recipe> {

private static final Map<EntityItem, Recipe> runningRecipes = new Object2ObjectOpenHashMap<>();

private final List<Recipe> recipes = new ArrayList<>();

@Override
public void onReload() {
this.recipes.addAll(getBackupRecipes());
getScriptedRecipes().forEach(this.recipes::remove);
}

@Override
public void afterScriptLoad() {
super.afterScriptLoad();
this.recipes.sort(Comparator.comparingInt(Recipe::getTicks));
}

public void add(Recipe recipe) {
this.recipes.add(recipe);
addScripted(recipe);
}

public boolean remove(Recipe recipe) {
if (this.recipes.remove(recipe)) {
addBackup(recipe);
return true;
}
return false;
}

public RecipeBuilder recipeBuilder() {
return new RecipeBuilder();
}

public static class Recipe {

private final IIngredient input;
private final ItemStack output;
private final int ticks;
private final Closure<Boolean> beforeRecipe;

public Recipe(IIngredient input, ItemStack output, int ticks, Closure<Boolean> beforeRecipe) {
this.input = input;
this.output = output;
this.ticks = ticks;
this.beforeRecipe = beforeRecipe;
}

public boolean isValidInput(EntityItem entityItem, ItemStack itemStack) {
return this.input.test(itemStack) && (this.beforeRecipe == null || ClosureHelper.call(true, this.beforeRecipe, entityItem));
}

public int getTicks() {
return ticks;
}
}

public static class RecipeBuilder extends AbstractRecipeBuilder<Recipe> {

private int ticks = 40;
private Closure<Boolean> beforeRecipe;

public RecipeBuilder ticks(int ticks) {
this.ticks = ticks;
return this;
}

public RecipeBuilder beforeRecipe(Closure<Boolean> beforeRecipe) {
this.beforeRecipe = beforeRecipe;
return this;
}

@Override
public String getErrorMsg() {
return "Error adding in world explosion recipe";
}

@Override
public void validate(GroovyLog.Msg msg) {
validateItems(msg, 1, 1, 1, 1);
validateFluids(msg);
if (this.ticks < 0) {
GroovyLog.get().warn("Burning recipe chance should be greater than 0.");
this.ticks = 40;
}
}

@Override
public @Nullable Recipe register() {
if (!validate()) return null;
Recipe recipe = new Recipe(this.input.get(0), this.output.get(0), this.ticks, this.beforeRecipe);
VanillaModule.inWorldCrafting.burning.add(recipe);
return recipe;
}
}

@GroovyBlacklist
public Recipe findRecipe(EntityItem entityItem) {
Recipe recipe = runningRecipes.get(entityItem);
if (recipe != null) return recipe;
ItemStack itemStack = entityItem.getItem();
for (Recipe recipe1 : this.recipes) {
if (recipe1.isValidInput(entityItem, itemStack)) {
runningRecipes.put(entityItem, recipe1);
return recipe1;
}
}
return null;
}

@GroovyBlacklist
public void updateRecipeProgress(EntityItem entityItem) {
Recipe recipe = findRecipe(entityItem);
if (recipe == null) return;
int prog = entityItem.getEntityData().getInteger("burn_time") + 1;
entityItem.getEntityData().setInteger("burn_time", prog);
entityItem.setEntityInvulnerable(true);
if (prog >= recipe.ticks) {
ItemStack newStack = recipe.output.copy();
newStack.setCount(entityItem.getItem().getCount());
entityItem.setItem(newStack);
removeBurningItem(entityItem);
}
}

@GroovyBlacklist
public static boolean removeBurningItem(EntityItem entityItem) {
entityItem.getEntityData().removeTag("burn_item");
return runningRecipes.remove(entityItem) != null;
}

public static boolean isRunningRecipe(EntityItem entityItem) {
return runningRecipes.containsKey(entityItem) && entityItem.getEntityData().getInteger("burn_time") > 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class InWorldCrafting implements IScriptReloadable {
public final FluidToItem fluidToItem = new FluidToItem();
public final FluidToBlock fluidToBlock = new FluidToBlock();
public final Explosion explosion = new Explosion();
public final Burning burning = new Burning();

@GroovyBlacklist
@Override
Expand All @@ -17,6 +18,7 @@ public void onReload() {
this.fluidToItem.onReload();
this.fluidToBlock.onReload();
this.explosion.onReload();
this.burning.onReload();
}

@GroovyBlacklist
Expand All @@ -26,5 +28,6 @@ public void afterScriptLoad() {
this.fluidToItem.afterScriptLoad();
this.fluidToBlock.afterScriptLoad();
this.explosion.afterScriptLoad();
this.burning.afterScriptLoad();
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
package com.cleanroommc.groovyscript.core.mixin;

import com.cleanroommc.groovyscript.compat.inworldcrafting.Burning;
import com.cleanroommc.groovyscript.compat.inworldcrafting.FluidRecipe;
import com.cleanroommc.groovyscript.compat.vanilla.VanillaModule;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fluids.Fluid;
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(EntityItem.class)
public abstract class EntityItemMixin {
public abstract class EntityItemMixin extends Entity {

private EntityItemMixin(World worldIn) {
super(worldIn);
}

@Inject(method = "onUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/item/EntityItem;handleWaterMovement()Z"), cancellable = true)
public void onUpdate(CallbackInfo ci) {
Expand All @@ -25,7 +33,21 @@ public void onUpdate(CallbackInfo ci) {
FluidRecipe.findAndRunRecipe(fluid, thisEntity.world, pos, blockState) &&
thisEntity.isDead) {
ci.cancel();
return;
}

if (thisEntity.fire > 0) {
VanillaModule.inWorldCrafting.burning.updateRecipeProgress(thisEntity);
ci.cancel();
} else if (Burning.removeBurningItem(thisEntity)) {
thisEntity.setEntityInvulnerable(false);
}
}
}

@Override
public void onRemovedFromWorld() {
super.onRemovedFromWorld();
Burning.removeBurningItem((EntityItem) (Object) this);
}
}

0 comments on commit 620318c

Please sign in to comment.