diff --git a/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java b/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java index 5cb34366..aa981255 100644 --- a/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java +++ b/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java @@ -9,12 +9,14 @@ import de.ellpeck.naturesaura.api.aura.item.IAuraRecharge; import de.ellpeck.naturesaura.api.aura.type.BasicAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.misc.IWorldData; +import de.ellpeck.naturesaura.api.misc.WeatherType; import de.ellpeck.naturesaura.api.misc.WeightedOre; import de.ellpeck.naturesaura.api.multiblock.IMultiblock; import de.ellpeck.naturesaura.api.multiblock.Matcher; import net.minecraft.block.BlockState; import net.minecraft.entity.EntityType; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; import net.minecraft.util.Tuple; import net.minecraft.util.math.AxisAlignedBB; @@ -94,6 +96,11 @@ public final class NaturesAuraAPI { * each generate in the projectile generator */ public static final Map PROJECTILE_GENERATIONS = new HashMap<>(); + /** + * A map of all of the items that cause the {@link WeatherType} to be + * changed using the weather changer + */ + public static final Map WEATHER_CHANGER_CONVERSIONS = new HashMap<>(); /** * The capability for any item or block that stores Aura in the form of an * {@link IAuraContainer} diff --git a/src/main/java/de/ellpeck/naturesaura/api/misc/WeatherType.java b/src/main/java/de/ellpeck/naturesaura/api/misc/WeatherType.java new file mode 100644 index 00000000..bb5f3c74 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/api/misc/WeatherType.java @@ -0,0 +1,7 @@ +package de.ellpeck.naturesaura.api.misc; + +public enum WeatherType { + SUN, + RAIN, + THUNDERSTORM +} diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/BlockWeatherChanger.java b/src/main/java/de/ellpeck/naturesaura/blocks/BlockWeatherChanger.java new file mode 100644 index 00000000..8e8feb0d --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/blocks/BlockWeatherChanger.java @@ -0,0 +1,13 @@ +package de.ellpeck.naturesaura.blocks; + +import de.ellpeck.naturesaura.blocks.tiles.TileEntityWeatherChanger; +import net.minecraft.block.Blocks; +import net.minecraft.tileentity.TileEntity; + +import java.util.function.Supplier; + +public class BlockWeatherChanger extends BlockContainerImpl { + public BlockWeatherChanger() { + super("weather_changer", TileEntityWeatherChanger::new, Properties.from(Blocks.STONE_BRICKS)); + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java b/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java index a0f86f63..e7cfcd21 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java @@ -77,4 +77,5 @@ public final class ModBlocks { public static Block WARPED_AURA_MUSHROOM; public static Block CRIMSON_AURA_MUSHROOM; public static Block AURA_MUSHROOM; + public static Block WEATHER_CHANGER; } diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/ModTileEntities.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/ModTileEntities.java index 3ff88e51..2346b4cc 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/ModTileEntities.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/ModTileEntities.java @@ -41,4 +41,5 @@ public final class ModTileEntities { public static TileEntityType AURA_TIMER; public static TileEntityType SLIME_SPLIT_GENERATOR; public static TileEntityType SPRING; + public static TileEntityType WEATHER_CHANGER; } diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityWeatherChanger.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityWeatherChanger.java new file mode 100644 index 00000000..057e447c --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityWeatherChanger.java @@ -0,0 +1,133 @@ +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.misc.WeatherType; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.EntityPredicates; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.server.ServerWorld; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.List; +import java.util.Map; + +public class TileEntityWeatherChanger extends TileEntityImpl implements ITickableTileEntity { + + private int processTime; + private WeatherType type; + private int itemAmount; + + public TileEntityWeatherChanger() { + super(ModTileEntities.WEATHER_CHANGER); + } + + @Override + public void tick() { + if (this.world.isRemote) { + if (this.world.getGameTime() % 10 != 0) + return; + if (this.processTime <= 0) + return; + int color = this.type == WeatherType.SUN ? 0xf5d742 : this.type == WeatherType.RAIN ? 0x4d5ae3 : 0x373247; + for (int r = 0; r < 360; r += 20) { + double xOff = Math.cos(Math.toRadians(r)) * 3F; + double zOff = Math.sin(Math.toRadians(r)) * 3F; + for (int i = this.world.rand.nextInt(3); i > 0; i--) { + NaturesAuraAPI.instance().spawnMagicParticle( + this.pos.getX() + 0.5F + xOff, + this.pos.getY(), + this.pos.getZ() + 0.5F + zOff, + this.world.rand.nextGaussian() * 0.02F, + this.world.rand.nextFloat() * 0.1F + 0.1F, + this.world.rand.nextGaussian() * 0.02F, + color, this.world.rand.nextFloat() * 2 + 1, this.world.rand.nextInt(80) + 80, 0, false, true); + } + } + return; + } + + if (this.processTime > 0) { + if (this.processTime % 20 == 0) { + BlockPos spot = IAuraChunk.getHighestSpot(this.world, this.pos, 35, this.pos); + IAuraChunk.getAuraChunk(this.world, spot).drainAura(spot, 30000); + } + + this.processTime--; + if (this.processTime <= 0) { + this.sendToClients(); + int time = 6000 * this.itemAmount; + ServerWorld server = (ServerWorld) this.world; + switch (this.type) { + case SUN: + server.func_241113_a_(time, 0, false, false); + break; + case RAIN: + server.func_241113_a_(0, time, true, false); + break; + case THUNDERSTORM: + server.func_241113_a_(0, time, true, true); + break; + } + } + } else { + if (this.world.getGameTime() % 20 != 0) + return; + Pair type = this.getNextWeatherType(); + if (type == null) + return; + this.type = type.getLeft(); + this.itemAmount = type.getRight(); + this.processTime = 100; + this.sendToClients(); + } + } + + @Override + public void writeNBT(CompoundNBT compound, SaveType type) { + super.writeNBT(compound, type); + if (type != SaveType.BLOCK) { + compound.putInt("time", this.processTime); + if (this.type != null) + compound.putInt("weather", this.type.ordinal()); + compound.putInt("amount", this.itemAmount); + } + } + + @Override + public void readNBT(CompoundNBT compound, SaveType type) { + super.readNBT(compound, type); + if (type != SaveType.BLOCK) { + this.processTime = compound.getInt("time"); + this.type = WeatherType.values()[compound.getInt("weather")]; + this.itemAmount = compound.getInt("amount"); + } + } + + private Pair getNextWeatherType() { + AxisAlignedBB area = new AxisAlignedBB(this.pos).grow(2); + List items = this.world.getEntitiesWithinAABB(ItemEntity.class, area, EntityPredicates.IS_ALIVE); + for (ItemEntity entity : items) { + if (entity.cannotPickup()) + continue; + ItemStack stack = entity.getItem(); + for (Map.Entry entry : NaturesAuraAPI.WEATHER_CHANGER_CONVERSIONS.entrySet()) { + if (!Helper.areItemsEqual(stack, entry.getKey(), true)) + continue; + entity.setItem(ItemStack.EMPTY); + entity.remove(); + return Pair.of(entry.getValue(), stack.getCount()); + } + } + return null; + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/recipes/ModRecipes.java b/src/main/java/de/ellpeck/naturesaura/recipes/ModRecipes.java index d1f38196..903e8ea4 100644 --- a/src/main/java/de/ellpeck/naturesaura/recipes/ModRecipes.java +++ b/src/main/java/de/ellpeck/naturesaura/recipes/ModRecipes.java @@ -5,11 +5,13 @@ import com.mojang.serialization.Dynamic; import com.mojang.serialization.JsonOps; import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.api.NaturesAuraAPI; +import de.ellpeck.naturesaura.api.misc.WeatherType; import de.ellpeck.naturesaura.api.misc.WeightedOre; import net.minecraft.block.Blocks; import net.minecraft.client.resources.ReloadListener; import net.minecraft.entity.EntityType; import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.IRecipeSerializer; import net.minecraft.item.crafting.IRecipeType; @@ -114,6 +116,10 @@ public final class ModRecipes { NaturesAuraAPI.PROJECTILE_GENERATIONS.put(EntityType.SHULKER_BULLET, 300000); NaturesAuraAPI.PROJECTILE_GENERATIONS.put(EntityType.LLAMA_SPIT, 100000); NaturesAuraAPI.PROJECTILE_GENERATIONS.put(EntityType.TRIDENT, 3000000); + + NaturesAuraAPI.WEATHER_CHANGER_CONVERSIONS.put(new ItemStack(Blocks.SUNFLOWER), WeatherType.SUN); + NaturesAuraAPI.WEATHER_CHANGER_CONVERSIONS.put(new ItemStack(Items.DARK_PRISMARINE), WeatherType.RAIN); + NaturesAuraAPI.WEATHER_CHANGER_CONVERSIONS.put(new ItemStack(Items.FIRE_CHARGE), WeatherType.THUNDERSTORM); } private static void ore(List list, String name, int weight) { diff --git a/src/main/java/de/ellpeck/naturesaura/reg/ModRegistry.java b/src/main/java/de/ellpeck/naturesaura/reg/ModRegistry.java index 5bccab69..3b56f76b 100644 --- a/src/main/java/de/ellpeck/naturesaura/reg/ModRegistry.java +++ b/src/main/java/de/ellpeck/naturesaura/reg/ModRegistry.java @@ -142,7 +142,8 @@ public final class ModRegistry { new BlockChorusGenerator(), new BlockAuraTimer(), new BlockSlimeSplitGenerator(), - new BlockSpring() + new BlockSpring(), + new BlockWeatherChanger() ); if (ModConfig.instance.rfConverter.get())