From fdd4c295a4a515a8a843e0c69386fe7db0fd466d Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 22 Jul 2016 20:23:51 +0200 Subject: [PATCH] WORMS! --- .../mod/ActuallyAdditions.java | 2 + .../mod/creative/CreativeTab.java | 2 + .../mod/entity/EntityWorm.java | 111 ++++++++++++++++++ .../mod/entity/InitEntities.java | 32 +++++ .../mod/entity/RenderWorm.java | 57 +++++++++ .../mod/items/InitItems.java | 2 + .../actuallyadditions/mod/items/ItemWorm.java | 84 +++++++++++++ .../mod/proxy/ClientProxy.java | 3 + .../mod/tile/TileEntityBase.java | 2 + .../assets/actuallyadditions/lang/en_US.lang | 1 + .../models/item/itemWorm.json | 6 + .../textures/items/itemWorm.png | Bin 0 -> 3380 bytes .../textures/items/itemWorm.png.mcmeta | 6 + 13 files changed, 308 insertions(+) create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/entity/EntityWorm.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/entity/InitEntities.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/entity/RenderWorm.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemWorm.java create mode 100644 src/main/resources/assets/actuallyadditions/models/item/itemWorm.json create mode 100644 src/main/resources/assets/actuallyadditions/textures/items/itemWorm.png create mode 100644 src/main/resources/assets/actuallyadditions/textures/items/itemWorm.png.mcmeta diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java b/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java index 856379623..5c23a7eac 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java @@ -18,6 +18,7 @@ import de.ellpeck.actuallyadditions.mod.config.ConfigurationHandler; import de.ellpeck.actuallyadditions.mod.crafting.CrusherCrafting; import de.ellpeck.actuallyadditions.mod.crafting.InitCrafting; import de.ellpeck.actuallyadditions.mod.crafting.ItemCrafting; +import de.ellpeck.actuallyadditions.mod.entity.InitEntities; import de.ellpeck.actuallyadditions.mod.event.CommonEvents; import de.ellpeck.actuallyadditions.mod.fluids.InitFluids; import de.ellpeck.actuallyadditions.mod.gen.InitVillager; @@ -106,6 +107,7 @@ public class ActuallyAdditions{ new CommonEvents(); InitCrafting.init(); DungeonLoot.init(); + InitEntities.init(); proxy.init(event); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/creative/CreativeTab.java b/src/main/java/de/ellpeck/actuallyadditions/mod/creative/CreativeTab.java index cbad6eb77..863027f1f 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/creative/CreativeTab.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/creative/CreativeTab.java @@ -52,6 +52,7 @@ public class CreativeTab extends CreativeTabs{ this.add(InitItems.itemBooklet); this.add(InitBlocks.blockSmileyCloud); + this.add(InitBlocks.blockTinyTorch); this.add(InitBlocks.blockFireworkBox); this.add(InitBlocks.blockLaserRelay); @@ -138,6 +139,7 @@ public class CreativeTab extends CreativeTabs{ this.add(InitBlocks.blockBlackLotus); this.add(InitBlocks.blockBookletStand); + this.add(InitItems.itemWorm); this.add(InitItems.itemPlayerProbe); this.add(InitItems.itemColorLens); this.add(InitItems.itemExplosionLens); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/entity/EntityWorm.java b/src/main/java/de/ellpeck/actuallyadditions/mod/entity/EntityWorm.java new file mode 100644 index 000000000..25a269699 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/entity/EntityWorm.java @@ -0,0 +1,111 @@ +/* + * This file ("EntityWorm.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.entity; + +import de.ellpeck.actuallyadditions.mod.util.Util; +import net.minecraft.block.Block; +import net.minecraft.block.BlockDirt; +import net.minecraft.block.BlockFarmland; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.init.Blocks; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class EntityWorm extends Entity{ + + public int timer; + + public EntityWorm(World world){ + super(world); + } + + @Override + protected void entityInit(){ + + } + + @Override + protected void readEntityFromNBT(NBTTagCompound compound){ + this.timer = compound.getInteger("Timer"); + } + + @Override + protected void writeEntityToNBT(NBTTagCompound compound){ + compound.setInteger("Timer", this.timer); + } + + @Override + public void onUpdate(){ + this.onEntityUpdate(); + } + + @Override + public void onEntityUpdate(){ + this.timer++; + + if(!this.worldObj.isRemote){ + if(this.timer%50 == 0){ + for(int x = -1; x <= 1; x++){ + for(int z = -1; z <= 1; z++){ + BlockPos pos = new BlockPos(this.posX+x, this.posY, this.posZ+z); + IBlockState state = this.worldObj.getBlockState(pos); + Block block = state.getBlock(); + boolean isMiddlePose = x == 0 && z == 0; + + if(canWormify(this.worldObj, pos, state)){ + boolean isFarmland = block instanceof BlockFarmland; + + if(!isFarmland || state.getValue(BlockFarmland.MOISTURE) < 7){ + if(isMiddlePose || this.worldObj.rand.nextFloat() >= 0.45F){ + IBlockState stateToModify = isFarmland ? state : Blocks.FARMLAND.getDefaultState(); + this.worldObj.setBlockState(pos, stateToModify.withProperty(BlockFarmland.MOISTURE, 7), 2); + + if(!isFarmland){ + this.worldObj.setBlockToAir(pos.up()); + } + } + } + + if(isFarmland && this.worldObj.rand.nextFloat() >= 0.95F){ + BlockPos plant = pos.up(); + if(!this.worldObj.isAirBlock(plant)){ + IBlockState plantState = this.worldObj.getBlockState(plant); + Block plantBlock = plantState.getBlock(); + + plantBlock.updateTick(this.worldObj, plant, plantState, Util.RANDOM); + this.worldObj.playEvent(2005, plant, 0); + } + } + } + else if(isMiddlePose){ + this.setDead(); + } + } + } + } + } + } + + public static boolean canWormify(World world, BlockPos pos, IBlockState state){ + Block block = state.getBlock(); + boolean rightBlock = block instanceof BlockFarmland || block == Blocks.GRASS || block == Blocks.GRASS_PATH || (block == Blocks.DIRT && state.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.DIRT); + if(rightBlock){ + BlockPos posUp = pos.up(); + IBlockState stateUp = world.getBlockState(posUp); + return stateUp.getBlock().isReplaceable(world, posUp); + } + else{ + return false; + } + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/entity/InitEntities.java b/src/main/java/de/ellpeck/actuallyadditions/mod/entity/InitEntities.java new file mode 100644 index 000000000..77f73bb5f --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/entity/InitEntities.java @@ -0,0 +1,32 @@ +/* + * This file ("InitEntities.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.entity; + +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import de.ellpeck.actuallyadditions.mod.util.ModUtil; +import net.minecraftforge.fml.client.registry.RenderingRegistry; +import net.minecraftforge.fml.common.registry.EntityRegistry; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public final class InitEntities{ + + public static void init(){ + ModUtil.LOGGER.info("Initializing Entities..."); + + EntityRegistry.registerModEntity(EntityWorm.class, ModUtil.MOD_ID+".worm", 0, ActuallyAdditions.instance, 64, 1, false); + } + + @SideOnly(Side.CLIENT) + public static void initClient(){ + RenderingRegistry.registerEntityRenderingHandler(EntityWorm.class, RenderWorm.FACTORY); + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/entity/RenderWorm.java b/src/main/java/de/ellpeck/actuallyadditions/mod/entity/RenderWorm.java new file mode 100644 index 000000000..5ce2f143c --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/entity/RenderWorm.java @@ -0,0 +1,57 @@ +/* + * This file ("RenderWorm.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.entity; + +import de.ellpeck.actuallyadditions.mod.items.InitItems; +import de.ellpeck.actuallyadditions.mod.util.AssetUtil; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.client.registry.IRenderFactory; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class RenderWorm extends Render{ + + private static final ItemStack STACK = new ItemStack(InitItems.itemWorm); + + public static final IRenderFactory FACTORY = new IRenderFactory(){ + @Override + public Render createRenderFor(RenderManager manager){ + return new RenderWorm(manager); + } + }; + + protected RenderWorm(RenderManager renderManager){ + super(renderManager); + } + + @Override + protected ResourceLocation getEntityTexture(EntityWorm entity){ + return TextureMap.LOCATION_BLOCKS_TEXTURE; + } + + @Override + public void doRender(EntityWorm entity, double x, double y, double z, float entityYaw, float partialTicks){ + GlStateManager.pushMatrix(); + GlStateManager.translate(x, y+0.7F, z); + GlStateManager.rotate((float)(((entity.timer)%360)), 0, 1, 0); + GlStateManager.translate(0, 0, 0.4); + AssetUtil.renderItemInWorld(STACK); + GlStateManager.popMatrix(); + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/items/InitItems.java b/src/main/java/de/ellpeck/actuallyadditions/mod/items/InitItems.java index 0d3bc7188..b30eb8262 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/items/InitItems.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/items/InitItems.java @@ -209,10 +209,12 @@ public final class InitItems{ public static Item itemWaterBowl; public static Item itemFilter; public static Item itemPlayerProbe; + public static Item itemWorm; public static void init(){ ModUtil.LOGGER.info("Initializing Items..."); + itemWorm = new ItemWorm("itemWorm"); itemPlayerProbe = new ItemPlayerProbe("itemPlayerProbe"); itemFilter = new ItemFilter("itemFilter"); itemWaterBowl = new ItemWaterBowl("itemWaterBowl"); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemWorm.java b/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemWorm.java new file mode 100644 index 000000000..a19839f06 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemWorm.java @@ -0,0 +1,84 @@ +/* + * This file ("ItemWorm.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.items; + +import de.ellpeck.actuallyadditions.mod.data.WorldData; +import de.ellpeck.actuallyadditions.mod.entity.EntityWorm; +import de.ellpeck.actuallyadditions.mod.items.base.ItemBase; +import de.ellpeck.actuallyadditions.mod.util.Util; +import io.netty.util.internal.ConcurrentSet; +import net.minecraft.block.Block; +import net.minecraft.block.BlockFarmland; +import net.minecraft.block.BlockGrass; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.particle.ParticleDigging; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.UseHoeEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import java.util.List; + +public class ItemWorm extends ItemBase{ + + public ItemWorm(String name){ + super(name); + + MinecraftForge.EVENT_BUS.register(this); + } + + @Override + public EnumActionResult onItemUse(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side, float par8, float par9, float par10){ + IBlockState state = world.getBlockState(pos); + if(EntityWorm.canWormify(world, pos, state)){ + List worms = world.getEntitiesWithinAABB(EntityWorm.class, new AxisAlignedBB(pos.getX()-1, pos.getY(), pos.getZ()-1, pos.getX()+2, pos.getY()+1, pos.getZ()+2)); + if(worms == null || worms.isEmpty()){ + if(!world.isRemote){ + EntityWorm worm = new EntityWorm(world); + worm.setPosition(pos.getX()+0.5, pos.getY()+0.5, pos.getZ()+0.5); + world.spawnEntityInWorld(worm); + + stack.stackSize--; + } + return EnumActionResult.SUCCESS; + } + } + return super.onItemUse(stack, player, world, pos, hand, side, par8, par9, par10); + } + + @SubscribeEvent + public void onHoe(UseHoeEvent event){ + World world = event.getWorld(); + if(!world.isRemote){ + BlockPos pos = event.getPos(); + IBlockState state = world.getBlockState(pos); + if(state.getBlock() instanceof BlockGrass && world.rand.nextFloat() > 0.7F){ + ItemStack stack = new ItemStack(InitItems.itemWorm, world.rand.nextInt(2)+1); + EntityItem item = new EntityItem(event.getWorld(), pos.getX()+0.5, pos.getY()+1, pos.getZ()+0.5, stack); + world.spawnEntityInWorld(item); + } + } + } + + @Override + public EnumRarity getRarity(ItemStack stack){ + return EnumRarity.UNCOMMON; + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/ClientProxy.java b/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/ClientProxy.java index 0df33228c..ba69e4ea8 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/ClientProxy.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/ClientProxy.java @@ -20,6 +20,7 @@ import de.ellpeck.actuallyadditions.mod.blocks.render.RenderDisplayStand; import de.ellpeck.actuallyadditions.mod.blocks.render.RenderReconstructorLens; import de.ellpeck.actuallyadditions.mod.blocks.render.RenderSmileyCloud; import de.ellpeck.actuallyadditions.mod.config.values.ConfigBoolValues; +import de.ellpeck.actuallyadditions.mod.entity.InitEntities; import de.ellpeck.actuallyadditions.mod.event.ClientEvents; import de.ellpeck.actuallyadditions.mod.fluids.InitFluids; import de.ellpeck.actuallyadditions.mod.misc.special.SpecialRenderInit; @@ -137,6 +138,8 @@ public class ClientProxy implements IProxy{ } }); } + + InitEntities.initClient(); } /** diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBase.java b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBase.java index 45241bb3b..c98c8c7c5 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBase.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBase.java @@ -194,6 +194,7 @@ public abstract class TileEntityBase extends TileEntity implements ITickable{ public void writeSyncableNBT(NBTTagCompound compound, NBTType type){ if(type == NBTType.SAVE_TILE){ compound.setBoolean("Redstone", this.isRedstonePowered); + compound.setInteger("TicksElapsed", this.ticksElapsed); } if(this.isRedstoneToggle() && (type != NBTType.SAVE_BLOCK || this.isPulseMode)){ compound.setBoolean("IsPulseMode", this.isPulseMode); @@ -208,6 +209,7 @@ public abstract class TileEntityBase extends TileEntity implements ITickable{ public void readSyncableNBT(NBTTagCompound compound, NBTType type){ if(type == NBTType.SAVE_TILE){ this.isRedstonePowered = compound.getBoolean("Redstone"); + this.ticksElapsed = compound.getInteger("TicksElapsed"); } if(this.isRedstoneToggle()){ this.isPulseMode = compound.getBoolean("IsPulseMode"); diff --git a/src/main/resources/assets/actuallyadditions/lang/en_US.lang b/src/main/resources/assets/actuallyadditions/lang/en_US.lang index 77e464663..91756d276 100644 --- a/src/main/resources/assets/actuallyadditions/lang/en_US.lang +++ b/src/main/resources/assets/actuallyadditions/lang/en_US.lang @@ -501,6 +501,7 @@ item.actuallyadditions.itemFilter.name=Item Filter item.actuallyadditions.itemMiscBiomass.name=Biomass item.actuallyadditions.itemMiscBiocoal.name=Bio Coal item.actuallyadditions.itemPlayerProbe.name=Player Probe +item.actuallyadditions.itemWorm.name=Worm #Tooltips tooltip.actuallyadditions.onSuffix.desc=On diff --git a/src/main/resources/assets/actuallyadditions/models/item/itemWorm.json b/src/main/resources/assets/actuallyadditions/models/item/itemWorm.json new file mode 100644 index 000000000..0199a3f17 --- /dev/null +++ b/src/main/resources/assets/actuallyadditions/models/item/itemWorm.json @@ -0,0 +1,6 @@ +{ + "parent": "actuallyadditions:item/standardItem", + "textures": { + "layer0": "actuallyadditions:items/itemWorm" + } +} diff --git a/src/main/resources/assets/actuallyadditions/textures/items/itemWorm.png b/src/main/resources/assets/actuallyadditions/textures/items/itemWorm.png new file mode 100644 index 0000000000000000000000000000000000000000..df4918cffe8cd0851f6b386a0f40ea444f33b176 GIT binary patch literal 3380 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