mirror of
https://github.com/Ellpeck/NaturesAura.git
synced 2024-12-22 14:59:22 +01:00
spawni boi, part 1
This commit is contained in:
parent
70ace2867c
commit
0566a81012
12 changed files with 268 additions and 5 deletions
|
@ -241,4 +241,12 @@ public final class Helper {
|
|||
if (adv != null)
|
||||
playerMp.getAdvancements().grantCriterion(adv, criterion);
|
||||
}
|
||||
|
||||
public static int getIngredientAmount(Ingredient ingredient) {
|
||||
int highestAmount = 0;
|
||||
for (ItemStack stack : ingredient.getMatchingStacks())
|
||||
if (stack.getCount() > highestAmount)
|
||||
highestAmount = stack.getCount();
|
||||
return highestAmount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import de.ellpeck.naturesaura.api.internal.StubHooks;
|
|||
import de.ellpeck.naturesaura.api.multiblock.IMultiblock;
|
||||
import de.ellpeck.naturesaura.api.multiblock.Matcher;
|
||||
import de.ellpeck.naturesaura.api.recipes.AltarRecipe;
|
||||
import de.ellpeck.naturesaura.api.recipes.AnimalSpawnerRecipe;
|
||||
import de.ellpeck.naturesaura.api.recipes.OfferingRecipe;
|
||||
import de.ellpeck.naturesaura.api.recipes.TreeRitualRecipe;
|
||||
import net.minecraft.block.BlockFlower;
|
||||
|
@ -104,6 +105,12 @@ public final class NaturesAuraAPI {
|
|||
* using the multiblock maker debug tool.
|
||||
*/
|
||||
public static final Map<ResourceLocation, IMultiblock> MULTIBLOCKS = new HashMap<>();
|
||||
/**
|
||||
* A map of all {@link AnimalSpawnerRecipe} objects that are used with the
|
||||
* animal spawner block. To register a recipe, use {@link
|
||||
* AnimalSpawnerRecipe#register()}.
|
||||
*/
|
||||
public static final Map<ResourceLocation, AnimalSpawnerRecipe> ANIMAL_SPAWNER_RECIPES = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The capability for any item or block that stores Aura in the form of an
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package de.ellpeck.naturesaura.api.recipes;
|
||||
|
||||
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class AnimalSpawnerRecipe {
|
||||
|
||||
public final ResourceLocation name;
|
||||
public final Ingredient[] ingredients;
|
||||
public final Function<World, Entity> entity;
|
||||
public final int aura;
|
||||
public final int time;
|
||||
|
||||
public AnimalSpawnerRecipe(ResourceLocation name, Function<World, Entity> entity, int aura, int time, Ingredient... ingredients) {
|
||||
this.name = name;
|
||||
this.ingredients = ingredients;
|
||||
this.entity = entity;
|
||||
this.aura = aura;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public AnimalSpawnerRecipe register() {
|
||||
NaturesAuraAPI.ANIMAL_SPAWNER_RECIPES.put(this.name, this);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package de.ellpeck.naturesaura.api.recipes;
|
||||
|
||||
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
|
||||
import de.ellpeck.naturesaura.api.recipes.ing.AmountIngredient;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
@ -9,11 +8,11 @@ import net.minecraft.util.ResourceLocation;
|
|||
public class OfferingRecipe {
|
||||
|
||||
public final ResourceLocation name;
|
||||
public final AmountIngredient input;
|
||||
public final Ingredient input;
|
||||
public final Ingredient startItem;
|
||||
public final ItemStack output;
|
||||
|
||||
public OfferingRecipe(ResourceLocation name, AmountIngredient input, Ingredient startItem, ItemStack output) {
|
||||
public OfferingRecipe(ResourceLocation name, Ingredient input, Ingredient startItem, ItemStack output) {
|
||||
this.name = name;
|
||||
this.input = input;
|
||||
this.startItem = startItem;
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package de.ellpeck.naturesaura.blocks;
|
||||
|
||||
import de.ellpeck.naturesaura.blocks.tiles.TileEntityAnimalSpawner;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.block.material.Material;
|
||||
|
||||
public class BlockAnimalSpawner extends BlockContainerImpl {
|
||||
public BlockAnimalSpawner() {
|
||||
super(Material.ROCK, "animal_spawner", TileEntityAnimalSpawner.class, "animal_spawner");
|
||||
this.setHardness(2F);
|
||||
this.setSoundType(SoundType.STONE);
|
||||
}
|
||||
}
|
|
@ -40,4 +40,5 @@ public final class ModBlocks {
|
|||
public static final Block ANIMAL_GENERATOR = new BlockAnimalGenerator();
|
||||
public static final Block END_FLOWER = new BlockEndFlower();
|
||||
public static final Block GRATED_CHUTE = new BlockGratedChute();
|
||||
public static final Block ANIMAL_SPAWNER = new BlockAnimalSpawner();
|
||||
}
|
||||
|
|
|
@ -63,4 +63,14 @@ public final class Multiblocks {
|
|||
(world, start, offset, pos, state, c) -> NaturesAuraAPI.FLOWERS.contains(state)),
|
||||
'0', ModBlocks.OFFERING_TABLE,
|
||||
' ', Matcher.wildcard());
|
||||
public static final IMultiblock ANIMAL_SPAWNER = NaturesAuraAPI.instance().createMultiblock(
|
||||
new ResourceLocation(NaturesAura.MOD_ID, "animal_spawner"),
|
||||
new String[][]{
|
||||
{" ", " ", " ", " 0 ", " ", " ", " "},
|
||||
{" HHH ", " HRRRH ", "HRWRWRH", "HRR RRH", "HRWRWRH", " HRRRH ", " HHH "}},
|
||||
'H', Blocks.HAY_BLOCK,
|
||||
'R', ModBlocks.INFUSED_BRICK,
|
||||
'W', ModBlocks.ANCIENT_PLANKS,
|
||||
'0', ModBlocks.ANIMAL_SPAWNER,
|
||||
' ', Matcher.wildcard());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
package de.ellpeck.naturesaura.blocks.tiles;
|
||||
|
||||
import de.ellpeck.naturesaura.Helper;
|
||||
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
|
||||
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
|
||||
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
|
||||
import de.ellpeck.naturesaura.api.recipes.AnimalSpawnerRecipe;
|
||||
import de.ellpeck.naturesaura.blocks.multi.Multiblocks;
|
||||
import de.ellpeck.naturesaura.packet.PacketHandler;
|
||||
import de.ellpeck.naturesaura.packet.PacketParticles;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.ITickable;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class TileEntityAnimalSpawner extends TileEntityImpl implements ITickable {
|
||||
|
||||
private AnimalSpawnerRecipe currentRecipe;
|
||||
private double spawnX;
|
||||
private double spawnZ;
|
||||
private int time;
|
||||
private Entity entityClient;
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if (!this.world.isRemote) {
|
||||
if (this.world.getTotalWorldTime() % 10 != 0)
|
||||
return;
|
||||
if (!Multiblocks.ANIMAL_SPAWNER.isComplete(this.world, this.pos)) {
|
||||
if (this.currentRecipe != null) {
|
||||
this.currentRecipe = null;
|
||||
this.time = 0;
|
||||
this.sendToClients();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.currentRecipe != null) {
|
||||
int drain = MathHelper.ceil(this.currentRecipe.aura / (float) this.currentRecipe.time * 10F);
|
||||
BlockPos spot = IAuraChunk.getHighestSpot(this.world, this.pos, 35, this.pos);
|
||||
IAuraChunk.getAuraChunk(this.world, spot).drainAura(spot, drain);
|
||||
|
||||
this.time += 10;
|
||||
if (this.time >= this.currentRecipe.time) {
|
||||
Entity entity = this.currentRecipe.entity.apply(this.world);
|
||||
entity.setPosition(this.spawnX, this.pos.getY() + 1, this.spawnZ);
|
||||
this.world.spawnEntity(entity);
|
||||
|
||||
this.currentRecipe = null;
|
||||
this.time = 0;
|
||||
this.sendToClients();
|
||||
}
|
||||
} else {
|
||||
List<EntityItem> items = this.world.getEntitiesWithinAABB(EntityItem.class,
|
||||
new AxisAlignedBB(this.pos).grow(2));
|
||||
|
||||
for (AnimalSpawnerRecipe recipe : NaturesAuraAPI.ANIMAL_SPAWNER_RECIPES.values()) {
|
||||
if (recipe.ingredients.length != items.size())
|
||||
continue;
|
||||
List<Ingredient> required = new ArrayList<>(Arrays.asList(recipe.ingredients));
|
||||
for (EntityItem item : items) {
|
||||
if (item.isDead || item.cannotPickup())
|
||||
break;
|
||||
ItemStack stack = item.getItem();
|
||||
if (stack.isEmpty())
|
||||
break;
|
||||
for (Ingredient ingredient : required) {
|
||||
if (ingredient.apply(stack) && Helper.getIngredientAmount(ingredient) == stack.getCount()) {
|
||||
required.remove(ingredient);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!required.isEmpty())
|
||||
continue;
|
||||
|
||||
for (EntityItem item : items) {
|
||||
item.setDead();
|
||||
PacketHandler.sendToAllAround(this.world, this.pos, 32,
|
||||
new PacketParticles((float) item.posX, (float) item.posY, (float) item.posZ, 19));
|
||||
}
|
||||
|
||||
this.currentRecipe = recipe;
|
||||
this.spawnX = this.pos.getX() + 0.5 + this.world.rand.nextFloat() * 4 - 2;
|
||||
this.spawnZ = this.pos.getZ() + 0.5 + this.world.rand.nextFloat() * 4 - 2;
|
||||
this.sendToClients();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this.world.getTotalWorldTime() % 5 != 0)
|
||||
return;
|
||||
if (this.currentRecipe == null) {
|
||||
this.entityClient = null;
|
||||
return;
|
||||
}
|
||||
|
||||
NaturesAuraAPI.instance().spawnParticleStream(
|
||||
this.pos.getX() + (float) this.world.rand.nextGaussian() * 5F,
|
||||
this.pos.getY() + 1 + this.world.rand.nextFloat() * 5F,
|
||||
this.pos.getZ() + (float) this.world.rand.nextGaussian() * 5F,
|
||||
this.pos.getX() + this.world.rand.nextFloat(),
|
||||
this.pos.getY() + this.world.rand.nextFloat(),
|
||||
this.pos.getZ() + this.world.rand.nextFloat(),
|
||||
this.world.rand.nextFloat() * 0.07F + 0.07F,
|
||||
IAuraType.forWorld(this.world).getColor(),
|
||||
this.world.rand.nextFloat() + 0.5F);
|
||||
|
||||
if (this.entityClient == null) {
|
||||
this.entityClient = this.currentRecipe.entity.apply(this.world);
|
||||
this.entityClient.setPosition(this.spawnX, this.pos.getY() + 1, this.spawnZ);
|
||||
}
|
||||
AxisAlignedBB bounds = this.entityClient.getEntityBoundingBox();
|
||||
for (int i = this.world.rand.nextInt(5) + 5; i >= 0; i--)
|
||||
NaturesAuraAPI.instance().spawnMagicParticle(
|
||||
bounds.minX + this.world.rand.nextFloat() * (bounds.maxX - bounds.minX),
|
||||
bounds.minY + this.world.rand.nextFloat() * (bounds.maxY - bounds.minY),
|
||||
bounds.minZ + this.world.rand.nextFloat() * (bounds.maxZ - bounds.minZ),
|
||||
0F, 0F, 0F, 0x2fd8d3, 2F, 60, 0F, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNBT(NBTTagCompound compound, SaveType type) {
|
||||
super.writeNBT(compound, type);
|
||||
if (type != SaveType.BLOCK) {
|
||||
if (this.currentRecipe != null) {
|
||||
compound.setString("recipe", this.currentRecipe.name.toString());
|
||||
compound.setDouble("spawn_x", this.spawnX);
|
||||
compound.setDouble("spawn_z", this.spawnZ);
|
||||
compound.setInteger("time", this.time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readNBT(NBTTagCompound compound, SaveType type) {
|
||||
super.readNBT(compound, type);
|
||||
if (type != SaveType.BLOCK) {
|
||||
if (compound.hasKey("recipe")) {
|
||||
ResourceLocation name = new ResourceLocation(compound.getString("recipe"));
|
||||
this.currentRecipe = NaturesAuraAPI.ANIMAL_SPAWNER_RECIPES.get(name);
|
||||
this.spawnX = compound.getDouble("spawn_x");
|
||||
this.spawnZ = compound.getDouble("spawn_z");
|
||||
this.time = compound.getInteger("time");
|
||||
} else {
|
||||
this.currentRecipe = null;
|
||||
this.time = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package de.ellpeck.naturesaura.blocks.tiles;
|
||||
|
||||
import de.ellpeck.naturesaura.Helper;
|
||||
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
|
||||
import de.ellpeck.naturesaura.api.recipes.OfferingRecipe;
|
||||
import de.ellpeck.naturesaura.blocks.multi.Multiblocks;
|
||||
|
@ -60,8 +61,9 @@ public class TileEntityOfferingTable extends TileEntityImpl implements ITickable
|
|||
if (!recipe.startItem.apply(itemStack))
|
||||
continue;
|
||||
|
||||
int recipeCount = stack.getCount() / recipe.input.amount;
|
||||
stack.shrink(recipeCount * recipe.input.amount);
|
||||
int amount = Helper.getIngredientAmount(recipe.input);
|
||||
int recipeCount = stack.getCount() / amount;
|
||||
stack.shrink(recipeCount * amount);
|
||||
item.setDead();
|
||||
this.sendToClients();
|
||||
|
||||
|
|
|
@ -42,4 +42,5 @@ public final class ModItems {
|
|||
public static final Item SKY_INGOT = new ItemImpl("sky_ingot");
|
||||
public static final Item CALLING_SPIRIT = new ItemGlowing("calling_spirit");
|
||||
public static final Item EFFECT_POWDER = new ItemEffectPowder();
|
||||
public static final Item BIRTH_SPIRIT = new ItemImpl("birth_spirit");
|
||||
}
|
||||
|
|
|
@ -312,6 +312,15 @@ public class PacketParticles implements IMessage {
|
|||
world.rand.nextGaussian() * 0.01F,
|
||||
color, 1.5F, 80, 0F, true, true);
|
||||
break;
|
||||
case 19: // Animal spawner
|
||||
for (int i = world.rand.nextInt(20) + 10; i >= 0; i--)
|
||||
NaturesAuraAPI.instance().spawnMagicParticle(
|
||||
message.posX, message.posY + 0.5F, message.posZ,
|
||||
world.rand.nextGaussian() * 0.02F,
|
||||
world.rand.nextFloat() * 0.02F,
|
||||
world.rand.nextGaussian() * 0.02F,
|
||||
0x16b7b2, 1.5F, 40, 0F, false, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -4,6 +4,7 @@ import de.ellpeck.naturesaura.Helper;
|
|||
import de.ellpeck.naturesaura.NaturesAura;
|
||||
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
|
||||
import de.ellpeck.naturesaura.api.recipes.AltarRecipe;
|
||||
import de.ellpeck.naturesaura.api.recipes.AnimalSpawnerRecipe;
|
||||
import de.ellpeck.naturesaura.api.recipes.OfferingRecipe;
|
||||
import de.ellpeck.naturesaura.api.recipes.TreeRitualRecipe;
|
||||
import de.ellpeck.naturesaura.api.recipes.ing.AmountIngredient;
|
||||
|
@ -18,8 +19,11 @@ import de.ellpeck.naturesaura.items.ModItems;
|
|||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockFlower;
|
||||
import net.minecraft.block.BlockStoneBrick;
|
||||
import net.minecraft.entity.passive.EntityCow;
|
||||
import net.minecraft.entity.passive.EntitySheep;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.EnumDyeColor;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
@ -131,6 +135,22 @@ public final class ModRecipes {
|
|||
Ingredient.fromItem(ModItems.CALLING_SPIRIT),
|
||||
new ItemStack(ModItems.SKY_INGOT)).register();
|
||||
|
||||
new AnimalSpawnerRecipe(new ResourceLocation(NaturesAura.MOD_ID, "cow"),
|
||||
EntityCow::new, 500, 60,
|
||||
Ingredient.fromItem(ModItems.BIRTH_SPIRIT),
|
||||
Ingredient.fromItem(Items.BEEF),
|
||||
Ingredient.fromItem(Items.LEATHER)).register();
|
||||
for (EnumDyeColor color : EnumDyeColor.values())
|
||||
new AnimalSpawnerRecipe(new ResourceLocation(NaturesAura.MOD_ID, "sheep_" + color.getName()),
|
||||
world -> {
|
||||
EntitySheep sheep = new EntitySheep(world);
|
||||
sheep.setFleeceColor(color);
|
||||
return sheep;
|
||||
}, 500, 60,
|
||||
Ingredient.fromItem(ModItems.BIRTH_SPIRIT),
|
||||
Ingredient.fromItem(Items.MUTTON),
|
||||
Ingredient.fromStacks(new ItemStack(Blocks.WOOL, 1, color.getMetadata()))).register();
|
||||
|
||||
NaturesAuraAPI.BOTANIST_PICKAXE_CONVERSIONS.put(
|
||||
Blocks.COBBLESTONE.getDefaultState(),
|
||||
Blocks.MOSSY_COBBLESTONE.getDefaultState());
|
||||
|
|
Loading…
Reference in a new issue