Browse Source

Hats(Cylinder, Straw hat), Suit, Honey-, Poison Buckets, Spikes, Silver, Hay(as Item, Block and Bed), Door-Handler for SnuviScript, Ore-Generation, Bugfixes

Kajetan Johannes Hammerle 7 years ago
parent
commit
fb7270e967
71 changed files with 1618 additions and 67 deletions
  1. 30 2
      src/main/java/me/km/ClientProxy.java
  2. 16 1
      src/main/java/me/km/CommonProxy.java
  3. 14 1
      src/main/java/me/km/KajetansMod.java
  4. 1 2
      src/main/java/me/km/api/Location.java
  5. 1 1
      src/main/java/me/km/api/Utils.java
  6. 15 0
      src/main/java/me/km/blocks/BlockBase.java
  7. 110 22
      src/main/java/me/km/blocks/BlockBed.java
  8. 234 0
      src/main/java/me/km/blocks/BlockEvents.java
  9. 2 1
      src/main/java/me/km/blocks/BlockHay.java
  10. 31 0
      src/main/java/me/km/blocks/BlockHayBed.java
  11. 116 0
      src/main/java/me/km/blocks/BlockSpikeTrap.java
  12. 47 0
      src/main/java/me/km/blocks/BlockTallGrass.java
  13. 82 0
      src/main/java/me/km/blocks/BlockTrap.java
  14. 80 0
      src/main/java/me/km/blocks/EnumMetals.java
  15. 55 9
      src/main/java/me/km/blocks/ModBlocks.java
  16. 1 1
      src/main/java/me/km/commands/CommandCoords.java
  17. 53 0
      src/main/java/me/km/dimensions/ModWorldGeneration.java
  18. 1 1
      src/main/java/me/km/fluids/BlockFluidHoney.java
  19. 1 0
      src/main/java/me/km/fluids/ModFluids.java
  20. 28 0
      src/main/java/me/km/items/ItemCylinder.java
  21. 28 0
      src/main/java/me/km/items/ItemHat.java
  22. 29 0
      src/main/java/me/km/items/ItemMetal.java
  23. 32 0
      src/main/java/me/km/items/ModItems.java
  24. 28 4
      src/main/java/me/km/items/ModRecipes.java
  25. 78 0
      src/main/java/me/km/items/ModelCylinder.java
  26. 78 0
      src/main/java/me/km/items/ModelHat.java
  27. 1 5
      src/main/java/me/km/scoreboard/ScoreBoardLeave.java
  28. 3 3
      src/main/java/me/km/scoreboard/ScoreboardAPI.java
  29. 16 3
      src/main/java/me/km/snuviscript/ScriptUtils.java
  30. 2 1
      src/main/java/me/km/snuviscript/ScriptVars.java
  31. 42 6
      src/main/java/me/km/snuviscript/SnuviParser.java
  32. 56 0
      src/main/java/me/km/utils/ReflectionUtils.java
  33. BIN
      src/main/resources/assets/forge/models/textures/items/honey_bucket.png
  34. BIN
      src/main/resources/assets/forge/models/textures/items/poison_bucket.png
  35. 5 0
      src/main/resources/assets/km/blockstates/artefact.json
  36. 5 0
      src/main/resources/assets/km/blockstates/silver_block.json
  37. 5 0
      src/main/resources/assets/km/blockstates/silver_ore.json
  38. 18 0
      src/main/resources/assets/km/blockstates/spikes.json
  39. 29 4
      src/main/resources/assets/km/lang/en_US.lang
  40. 21 0
      src/main/resources/assets/km/models/block/artefact.json
  41. 6 0
      src/main/resources/assets/km/models/block/silver_block.json
  42. 6 0
      src/main/resources/assets/km/models/block/silver_ore.json
  43. 164 0
      src/main/resources/assets/km/models/block/spikes.json
  44. 6 0
      src/main/resources/assets/km/models/item/cylinder.json
  45. 6 0
      src/main/resources/assets/km/models/item/hay_bundle.json
  46. 6 0
      src/main/resources/assets/km/models/item/silver_ingot.json
  47. 6 0
      src/main/resources/assets/km/models/item/silver_nugget.json
  48. 6 0
      src/main/resources/assets/km/models/item/straw_hat.json
  49. 6 0
      src/main/resources/assets/km/models/item/suit_boots.json
  50. 6 0
      src/main/resources/assets/km/models/item/suit_chestplate.json
  51. 6 0
      src/main/resources/assets/km/models/item/suit_leggings.json
  52. BIN
      src/main/resources/assets/km/textures/blocks/artefact/artefact_bottom.png
  53. BIN
      src/main/resources/assets/km/textures/blocks/artefact/artefact_sides.png
  54. BIN
      src/main/resources/assets/km/textures/blocks/artefact/artefact_top.png
  55. BIN
      src/main/resources/assets/km/textures/blocks/silver_block.png
  56. BIN
      src/main/resources/assets/km/textures/blocks/silver_ore.png
  57. BIN
      src/main/resources/assets/km/textures/items/cylinder.png
  58. BIN
      src/main/resources/assets/km/textures/items/hay_bundle.png
  59. BIN
      src/main/resources/assets/km/textures/items/real_hay_bed.png
  60. BIN
      src/main/resources/assets/km/textures/items/silver/silver_ingot.png
  61. BIN
      src/main/resources/assets/km/textures/items/silver/silver_nugget.png
  62. BIN
      src/main/resources/assets/km/textures/items/straw_hat.png
  63. BIN
      src/main/resources/assets/km/textures/items/suit_boots.png
  64. BIN
      src/main/resources/assets/km/textures/items/suit_chestplate.png
  65. BIN
      src/main/resources/assets/km/textures/items/suit_leggings.png
  66. BIN
      src/main/resources/assets/km/textures/models/armor/cylinder_layer_1.png
  67. BIN
      src/main/resources/assets/km/textures/models/armor/cylinder_layer_2.png
  68. BIN
      src/main/resources/assets/km/textures/models/armor/straw_layer_1.png
  69. BIN
      src/main/resources/assets/km/textures/models/armor/straw_layer_2.png
  70. BIN
      src/main/resources/assets/km/textures/models/armor/suit_layer_1.png
  71. BIN
      src/main/resources/assets/km/textures/models/armor/suit_layer_2.png

+ 30 - 2
src/main/java/me/km/ClientProxy.java

@@ -1,8 +1,11 @@
 package me.km;
 
 import me.km.entities.ModEntities;
+import me.km.items.ModelCylinder;
+import me.km.items.ModelHat;
 import net.minecraft.block.Block;
 import net.minecraft.block.state.IBlockState;
+import net.minecraft.client.model.ModelBiped;
 import net.minecraft.client.renderer.block.model.ModelBakery;
 import net.minecraft.client.renderer.block.model.ModelResourceLocation;
 import net.minecraft.client.renderer.block.statemap.StateMapperBase;
@@ -13,15 +16,23 @@ import net.minecraft.server.MinecraftServer;
 import net.minecraftforge.client.model.ModelLoader;
 import net.minecraftforge.fluids.IFluidBlock;
 import net.minecraftforge.fml.client.registry.RenderingRegistry;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
 
 public class ClientProxy extends CommonProxy 
 {
     @Override
-    public void registerItemRenderer(Item item, int meta, String id) 
+    public void registerItemRenderer(Item item, int meta, String id, String variant) 
     {
-        ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(KajetansMod.MODID + ":" + id, null));
+        ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(KajetansMod.MODID + ":" + id, variant));
     }
     
+    @Override
+    public void registerItemRenderer(Item item, int meta, String id) 
+    {
+        registerItemRenderer(item, meta, id, null);
+    }
+
     @Override
     public void registerFluidModel(IFluidBlock fluidBlock) 
     {
@@ -56,4 +67,21 @@ public class ClientProxy extends CommonProxy
     public void overloadPlayerList(MinecraftServer server) 
     {
     }
+
+    @SideOnly(Side.CLIENT)
+    private final static ModelHat STRAW_HAT = new ModelHat(1);
+    @SideOnly(Side.CLIENT)
+    private final static ModelCylinder CYLINDER = new ModelCylinder(1);
+    
+    @Override
+    public ModelBiped getCylinderModel() 
+    {
+        return CYLINDER;
+    }
+
+    @Override
+    public ModelBiped getStrawHatModel() 
+    {
+        return STRAW_HAT;
+    }
 }

+ 16 - 1
src/main/java/me/km/CommonProxy.java

@@ -2,6 +2,7 @@ package me.km;
 
 import me.km.entities.ModEntities;
 import me.km.playerbank.ModDedicatedPlayerList;
+import net.minecraft.client.model.ModelBiped;
 import net.minecraft.client.renderer.entity.Render;
 import net.minecraft.entity.Entity;
 import net.minecraft.item.Item;
@@ -13,10 +14,14 @@ import net.minecraftforge.fml.relauncher.SideOnly;
 
 public class CommonProxy 
 {
-    public void registerItemRenderer(Item item, int meta, String id) 
+    public void registerItemRenderer(Item item, int meta, String id, String variant) 
     {
     }
     
+    public void registerItemRenderer(Item item, int meta, String id) 
+    {
+    }
+
     public void registerFluidModel(IFluidBlock fluidBlock) 
     {
     }
@@ -45,4 +50,14 @@ public class CommonProxy
             dedi.setPlayerList(new ModDedicatedPlayerList(dedi));
         }
     }
+    
+    public ModelBiped getCylinderModel()
+    {
+        return null;
+    }
+    
+    public ModelBiped getStrawHatModel()
+    {
+        return null;
+    }
 }

+ 14 - 1
src/main/java/me/km/KajetansMod.java

@@ -4,9 +4,11 @@ import me.km.api.Module;
 import me.km.api.SimpleConfig;
 import me.km.api.CommandOverloader;
 import me.km.blockprotections.BlockProtectionBank;
+import me.km.blocks.BlockEvents;
 import me.km.blocks.ModBlocks;
 import me.km.chatmanager.ChatManager;
 import me.km.databank.DataBank;
+import me.km.dimensions.ModWorldGeneration;
 import me.km.dimensions.WorldData;
 import me.km.effects.EffectUtils;
 import me.km.fluids.ModFluids;
@@ -25,6 +27,7 @@ import me.km.snuviscript.ScriptBank;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.util.text.TextFormatting;
 import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.fluids.FluidRegistry;
 import net.minecraftforge.fml.common.Mod;
 import net.minecraftforge.fml.common.SidedProxy;
 import net.minecraftforge.fml.common.event.FMLInitializationEvent;
@@ -33,6 +36,7 @@ import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
 import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent;
 import net.minecraftforge.fml.common.event.FMLServerStoppingEvent;
 import net.minecraftforge.fml.common.event.FMLServerStartedEvent;
+import net.minecraftforge.fml.common.registry.GameRegistry;
 
 @Mod(modid = KajetansMod.MODID, version = KajetansMod.VERSION, name = KajetansMod.NAME)
 public class KajetansMod
@@ -64,7 +68,7 @@ public class KajetansMod
 
     public static final String MODID = "km";
     public static final String NAME = "Kajetans Mod";
-    public static final String VERSION = "0.0.2";
+    public static final String VERSION = "0.0.6";
 
     @Mod.Instance(MODID)
     public static KajetansMod instance;
@@ -74,6 +78,11 @@ public class KajetansMod
     public static boolean debugMode;
     public static boolean singlePlayer;
 
+    static
+    {
+        FluidRegistry.enableUniversalBucket();
+    }
+    
     @Mod.EventHandler
     public void preInit(FMLPreInitializationEvent event) 
     {
@@ -81,6 +90,8 @@ public class KajetansMod
         ModFluids.init();
         ModItems.init();
         ModBlocks.init();
+        ModBlocks.lateInit();
+        GameRegistry.registerWorldGenerator(new ModWorldGeneration(), 3);
     }
     
     @Mod.EventHandler
@@ -88,6 +99,7 @@ public class KajetansMod
     {
         proxy.initEntities();
         MinecraftForge.EVENT_BUS.register(new ClientEvents());
+        MinecraftForge.EVENT_BUS.register(new BlockEvents());
         ModRecipes.init();
     }
     
@@ -253,6 +265,7 @@ public class KajetansMod
         {
             return;
         }
+        scripts.startScript(server, "endscript");
         databank.closeDataBankConnection();
     }
 

+ 1 - 2
src/main/java/me/km/api/Location.java

@@ -73,8 +73,7 @@ public class Location
     
     public Location add(double x, double y, double z)
     {
-        pos = pos.addVector(x, y, z);
-        return this;
+        return new Location(w, pos.addVector(x, y, z));
     }
 
     public World getWorld() 

+ 1 - 1
src/main/java/me/km/api/Utils.java

@@ -396,7 +396,7 @@ public class Utils
             {
                 KajetansMod.server.getPlayerList().transferPlayerToDimension(p, dim, new ModTeleporter(KajetansMod.server.worldServerForDimension(dim)));
             }
-            if(l.getYaw() != 0 && l.getPitch() != 0)
+            if(l.getYaw() != 0 || l.getPitch() != 0)
             {
                 p.connection.setPlayerLocation(pos.xCoord, pos.yCoord, pos.zCoord, l.getYaw(), l.getPitch());
             }

+ 15 - 0
src/main/java/me/km/blocks/BlockBase.java

@@ -2,6 +2,7 @@ package me.km.blocks;
 
 import me.km.KajetansMod;
 import net.minecraft.block.*;
+import net.minecraft.block.material.MapColor;
 import net.minecraft.block.material.Material;
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.creativetab.CreativeTabs;
@@ -14,6 +15,7 @@ public class BlockBase extends Block implements IBlockBase
 {
     protected String name;
     private SoundType type;
+    private MapColor mapColor;
 
     public BlockBase(Material material, String name, String local) 
     {
@@ -23,8 +25,21 @@ public class BlockBase extends Block implements IBlockBase
         super.setUnlocalizedName(local);
         super.setCreativeTab(CreativeTabs.BUILDING_BLOCKS);
         this.type = super.getSoundType();
+        this.mapColor = blockMapColor;
     }
 
+    public BlockBase setMapColor(MapColor mapColor)
+    {
+        this.mapColor = mapColor;
+        return this;
+    }
+    
+    @Override
+    public MapColor getMapColor(IBlockState state)
+    {
+        return this.mapColor;
+    }
+    
     @Override
     public void registerItemModel(ItemBlock itemBlock) 
     {

+ 110 - 22
src/main/java/me/km/blocks/BlockBed.java

@@ -1,17 +1,20 @@
 package me.km.blocks;
 
-import java.util.List;
 import java.util.Random;
 import javax.annotation.Nullable;
-import static net.minecraft.block.BlockBed.PART;
 import net.minecraft.block.SoundType;
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.init.Biomes;
 import net.minecraft.init.Items;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
-import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
 import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.text.TextComponentTranslation;
 import net.minecraft.world.IBlockAccess;
 import net.minecraft.world.World;
 
@@ -20,8 +23,6 @@ public class BlockBed extends net.minecraft.block.BlockBed
     protected String name;
     private SoundType type;
     private final Item drop;
-    private static final AxisAlignedBB BOX = new AxisAlignedBB(0, 0, 0, 1, 0.125d, 1);
-    private static final AxisAlignedBB BOX_2 = new AxisAlignedBB(0, 0, 0.625d, 1, 0.25d, 1);
     
     public BlockBed(String name, String local, Item drop)
     {
@@ -34,19 +35,6 @@ public class BlockBed extends net.minecraft.block.BlockBed
         super.disableStats();
     }
     
-    @Override
-    public void addCollisionBoxToList(IBlockState state, World worldIn, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, @Nullable Entity entityIn, boolean p_185477_7_)
-    {
-        addCollisionBoxToList(pos, entityBox, collidingBoxes, BOX);
-        addCollisionBoxToList(pos, entityBox, collidingBoxes, BOX_2);
-    }
-
-    @Override
-    public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
-    {
-        return state.getValue(PART) == BlockBed.EnumPartType.HEAD ? FULL_BLOCK_AABB : BOX;
-    }
-    
     @Override
     public final Item getItemDropped(IBlockState state, Random rand, int fortune)
     {
@@ -54,27 +42,127 @@ public class BlockBed extends net.minecraft.block.BlockBed
     }
 
     @Override
-    public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) 
+    public final ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) 
     {
         return new ItemStack(drop);
     }
 
     @Override
-    public BlockBed setSoundType(SoundType sound) 
+    public final BlockBed setSoundType(SoundType sound) 
     {
         this.type = sound;
         return this;
     }
 
     @Override
-    public SoundType getSoundType(IBlockState state, World w, BlockPos pos, Entity entity) 
+    public final SoundType getSoundType(IBlockState state, World w, BlockPos pos, Entity entity) 
     {
         return type;
     }     
 
     @Override
-    public boolean isBed(IBlockState state, IBlockAccess world, BlockPos pos, Entity player) 
+    public final boolean isBed(IBlockState state, IBlockAccess world, BlockPos pos, Entity player) 
     {
         return true;
     }
+    
+    // copied from net.minecraft.block.BlockBed
+    @Override
+    public final boolean onBlockActivated(World w, BlockPos pos, IBlockState state, EntityPlayer p, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
+    {
+        if(w.isRemote)
+        {
+            return true;
+        }
+        else
+        {
+            if(state.getValue(PART) != EnumPartType.HEAD)
+            {
+                pos = pos.offset((EnumFacing)state.getValue(FACING));
+                state = w.getBlockState(pos);
+                if (state.getBlock() != this)
+                {
+                    return true;
+                }
+            }
+            if(w.provider.canRespawnHere() && w.getBiome(pos) != Biomes.HELL)
+            {
+                if(state.getValue(OCCUPIED))
+                {
+                    EntityPlayer anotherPlayer = this.getPlayerInBed(w, pos);
+                    if (anotherPlayer != null)
+                    {
+                        p.sendStatusMessage(new TextComponentTranslation("tile.bed.occupied", new Object[0]), true);
+                        return true;
+                    }
+                    state = state.withProperty(OCCUPIED, false);
+                    w.setBlockState(pos, state, 4);
+                }
+
+                EntityPlayer.SleepResult result = p.trySleep(pos);
+
+                if(result == EntityPlayer.SleepResult.OK)
+                {
+                    state = state.withProperty(OCCUPIED, true);
+                    // set players real position
+                    // subtracting normal bedsize, adding custom
+                    p.setPosition(p.posX, p.posY - 0.6875f + getLayingHigh(), p.posZ);
+                    // this is for evil servers which render the position wrong
+                    if(p instanceof EntityPlayerMP)
+                    {
+                        ((EntityPlayerMP) p).connection.setPlayerLocation(p.posX, p.posY, p.posZ, p.rotationYaw, p.rotationPitch);
+                    }
+                    // end
+                    w.setBlockState(pos, state, 4);
+                    return true;
+                }
+                else
+                {
+                    switch (result) 
+                    {
+                        case NOT_POSSIBLE_NOW:
+                            p.sendStatusMessage(new TextComponentTranslation("tile.bed.noSleep", new Object[0]), true);
+                            break;
+                        case NOT_SAFE:
+                            p.sendStatusMessage(new TextComponentTranslation("tile.bed.notSafe", new Object[0]), true);
+                            break;
+                        case TOO_FAR_AWAY:
+                            p.sendStatusMessage(new TextComponentTranslation("tile.bed.tooFarAway", new Object[0]), true);
+                            break;
+                    }
+                    return true;
+                }
+            }
+            else
+            {
+                w.setBlockToAir(pos);
+                BlockPos blockpos = pos.offset(state.getValue(FACING).getOpposite());
+                if(w.getBlockState(blockpos).getBlock() == this)
+                {
+                    w.setBlockToAir(blockpos);
+                }
+                w.newExplosion(null, pos.getX() + 0.5d, pos.getY() + 0.5d, pos.getZ() + 0.5d, 5, true, true);
+                return true;
+            }
+        }
+    }
+    
+    public float getLayingHigh()
+    {
+        return 0.6875f;
+    }
+    
+    // copied from net.minecraft.block.BlockBed
+    @Nullable
+    private EntityPlayer getPlayerInBed(World w, BlockPos pos)
+    {
+        for(EntityPlayer entityplayer : w.playerEntities)
+        {
+            if(entityplayer.isPlayerSleeping() && entityplayer.bedLocation.equals(pos))
+            {
+                return entityplayer;
+            }
+        }
+        return null;
+    }
 }

+ 234 - 0
src/main/java/me/km/blocks/BlockEvents.java

@@ -0,0 +1,234 @@
+package me.km.blocks;
+
+import com.google.common.collect.Sets;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import me.km.utils.ReflectionUtils;
+import net.minecraft.block.Block;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.enchantment.EnchantmentProtection;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.item.EntityTNTPrimed;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.Blocks;
+import net.minecraft.init.SoundEvents;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.EnumParticleTypes;
+import net.minecraft.util.SoundCategory;
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.math.Vec3d;
+import net.minecraft.world.Explosion;
+import net.minecraft.world.World;
+import net.minecraftforge.event.world.ExplosionEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class BlockEvents 
+{
+    @SubscribeEvent(receiveCanceled = false, priority = EventPriority.LOWEST)
+    public void onExplosion(ExplosionEvent.Start e)
+    {
+        Explosion ex = e.getExplosion();
+        Entity ent = ReflectionUtils.getExploder(ex);
+        if(ReflectionUtils.getSize(ex) > 10)
+        {
+            ReflectionUtils.setSize(ex, 10);
+        }
+        e.setCanceled(true);
+        doExplosionA(ex, e.getWorld(), ent instanceof EntityTNTPrimed);
+        doExplosionB(ex, e.getWorld(), true);
+    }
+    
+    public void doExplosionA(Explosion ex, World w, boolean tnt)
+    {
+        Set<BlockPos> set = Sets.<BlockPos>newHashSet();
+        int i = 16;
+
+        Vec3d v = ex.getPosition();
+        float explosionSize = ReflectionUtils.getSize(ex);
+        Entity exploder = ReflectionUtils.getExploder(ex);
+        for(int j = 0; j < 16; ++j)
+        {
+            for(int k = 0; k < 16; ++k)
+            {
+                for(int l = 0; l < 16; ++l)
+                {
+                    if(j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15)
+                    {
+                        double d0 = j / 15f * 2 - 1;
+                        double d1 = k / 15f * 2 - 1;
+                        double d2 = l / 15f * 2 - 1;
+                        double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
+                        d0 = d0 / d3;
+                        d1 = d1 / d3;
+                        d2 = d2 / d3;
+                        float f = explosionSize * (0.7f + w.rand.nextFloat() * 0.6f);
+                        double d4 = v.xCoord;
+                        double d6 = v.yCoord;
+                        double d8 = v.zCoord;
+
+                        for(float f1 = 0.3F; f > 0.0F; f -= 0.22500001F)
+                        {
+                            BlockPos blockpos = new BlockPos(d4, d6, d8);
+                            IBlockState iblockstate = w.getBlockState(blockpos);
+
+                            if (iblockstate.getMaterial() != Material.AIR)
+                            {
+                                float f2 = exploder != null ? exploder.getExplosionResistance(ex, w, blockpos, iblockstate) : iblockstate.getBlock().getExplosionResistance(w, blockpos, null, ex);
+                                // TNT hook
+                                if(tnt && f2 <= 10)
+                                {
+                                    f2 = Math.min(f2, 1);
+                                }
+                                // end
+                                f -= (f2 + 0.3F) * 0.3F;
+                            }
+
+                            if (f > 0.0F && (exploder == null || exploder.verifyExplosion(ex, w, blockpos, iblockstate, f)))
+                            {
+                                set.add(blockpos);
+                            }
+
+                            d4 += d0 * 0.3d;
+                            d6 += d1 * 0.3d;
+                            d8 += d2 * 0.3d;
+                        }
+                    }
+                }
+            }
+        }
+
+        ex.getAffectedBlockPositions().addAll(set);
+        float f3 = explosionSize * 2;
+        int k1 = MathHelper.floor(v.xCoord - f3 - 1);
+        int l1 = MathHelper.floor(v.xCoord + f3 + 1);
+        int i2 = MathHelper.floor(v.yCoord - f3 - 1);
+        int i1 = MathHelper.floor(v.yCoord + f3 + 1);
+        int j2 = MathHelper.floor(v.zCoord - f3 - 1);
+        int j1 = MathHelper.floor(v.zCoord + f3 + 1);
+        List<Entity> list = w.getEntitiesWithinAABBExcludingEntity(exploder, new AxisAlignedBB(k1, i2, j2, l1, i1, j1));
+        net.minecraftforge.event.ForgeEventFactory.onExplosionDetonate(w, ex, list, f3);
+        Vec3d vec3d = new Vec3d(v.xCoord, v.yCoord, v.zCoord);
+
+        for(int k2 = 0; k2 < list.size(); k2++)
+        {
+            Entity entity = list.get(k2);
+
+            if(!entity.isImmuneToExplosions())
+            {
+                double d12 = entity.getDistance(v.xCoord, v.yCoord, v.zCoord) / f3;
+
+                if(d12 <= 1.0D)
+                {
+                    double d5 = entity.posX - v.xCoord;
+                    double d7 = entity.posY + (double)entity.getEyeHeight() - v.yCoord;
+                    double d9 = entity.posZ - v.zCoord;
+                    double d13 = MathHelper.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
+
+                    if(d13 != 0.0D)
+                    {
+                        d5 = d5 / d13;
+                        d7 = d7 / d13;
+                        d9 = d9 / d13;
+                        double d14 = w.getBlockDensity(vec3d, entity.getEntityBoundingBox());
+                        double d10 = (1.0D - d12) * d14;
+                        entity.attackEntityFrom(DamageSource.causeExplosionDamage(ex), (float)((int)((d10 * d10 + d10) / 2 * 7 * f3 + 1)));
+                        double d11 = d10;
+
+                        if(entity instanceof EntityLivingBase)
+                        {
+                            d11 = EnchantmentProtection.getBlastDamageReduction((EntityLivingBase) entity, d10);
+                        }
+
+                        entity.motionX += d5 * d11;
+                        entity.motionY += d7 * d11;
+                        entity.motionZ += d9 * d11;
+
+                        if (entity instanceof EntityPlayer)
+                        {
+                            EntityPlayer entityplayer = (EntityPlayer)entity;
+
+                            if (!entityplayer.isSpectator() && (!entityplayer.isCreative() || !entityplayer.capabilities.isFlying))
+                            {
+                                ex.getPlayerKnockbackMap().put(entityplayer, new Vec3d(d5 * d10, d7 * d10, d9 * d10));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    private void doExplosionB(Explosion ex, World w, boolean spawnParticles)
+    {
+        Vec3d v = ex.getPosition();
+        double x = v.xCoord;
+        double y = v.yCoord;
+        double z = v.zCoord;
+        w.playSound(null, x, y, z, SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.BLOCKS, 4, (1 + (w.rand.nextFloat() - w.rand.nextFloat()) * 0.2f) * 0.7f);
+
+        if(ReflectionUtils.getSize(ex) >= 2 && ReflectionUtils.isSmoking(ex))
+        {
+            w.spawnParticle(EnumParticleTypes.EXPLOSION_HUGE, x, y, z, 1, 0, 0, new int[0]);
+        }
+        else
+        {
+            w.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, x, y, z, 1, 0, 0, new int[0]);
+        }
+
+        if(ReflectionUtils.isSmoking(ex))
+        {
+            float explosionSize = ReflectionUtils.getSize(ex);
+            ex.getAffectedBlockPositions().stream().forEach(blockpos -> 
+            {
+                IBlockState iblockstate = w.getBlockState(blockpos);
+                Block block = iblockstate.getBlock();
+
+                if(spawnParticles)
+                {
+                    double d0 = blockpos.getX() + w.rand.nextFloat();
+                    double d1 = blockpos.getY() + w.rand.nextFloat();
+                    double d2 = blockpos.getZ() + w.rand.nextFloat();
+                    double d3 = d0 - x;
+                    double d4 = d1 - y;
+                    double d5 = d2 - z;
+                    double d6 = MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
+                    d3 = d3 / d6;
+                    d4 = d4 / d6;
+                    d5 = d5 / d6;
+                    double d7 = 0.5D / (d6 / explosionSize + 0.1D);
+                    d7 = d7 * (w.rand.nextFloat() * w.rand.nextFloat() + 0.3F);
+                    d3 = d3 * d7;
+                    d4 = d4 * d7;
+                    d5 = d5 * d7;
+                    w.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, (d0 + x) / 2, (d1 + y) / 2, (d2 + z) / 2, d3, d4, d5, new int[0]);
+                    w.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, d0, d1, d2, d3, d4, d5, new int[0]);
+                }
+
+                if(iblockstate.getMaterial() != Material.AIR)
+                {
+                    if(block.canDropFromExplosion(ex))
+                    {
+                        block.dropBlockAsItem(w, blockpos, w.getBlockState(blockpos), 0);
+                    }
+                    block.onBlockExploded(w, blockpos, ex);
+                }
+            });
+        }
+
+        if(ReflectionUtils.isFlaming(ex))
+        {
+            Random rand = ReflectionUtils.getRandom(ex);
+            ex.getAffectedBlockPositions().stream()
+                    .filter(pos -> (w.getBlockState(pos).getMaterial() == Material.AIR && 
+                                    w.getBlockState(pos.down()).isFullBlock() && 
+                                    rand.nextInt(3) == 0))
+                    .forEach(pos -> w.setBlockState(pos, Blocks.FIRE.getDefaultState()));
+        }
+    }
+}

+ 2 - 1
src/main/java/me/km/blocks/BlockHay.java

@@ -24,7 +24,8 @@ public class BlockHay extends BlockRotatedPillar implements IBlockBase
         this.setRegistryName(name);
         super.setUnlocalizedName(local);
         super.setCreativeTab(CreativeTabs.BUILDING_BLOCKS);
-        this.type = super.getSoundType();
+        super.setHardness(0.5F);
+        this.type = SoundType.PLANT;
         this.setDefaultState(this.blockState.getBaseState().withProperty(AXIS, EnumFacing.Axis.Y));
     }
 

+ 31 - 0
src/main/java/me/km/blocks/BlockHayBed.java

@@ -0,0 +1,31 @@
+package me.km.blocks;
+
+import me.km.items.ModItems;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockAccess;
+
+public class BlockHayBed extends BlockBed
+{ 
+    private static final AxisAlignedBB BOX = new AxisAlignedBB(0, 0, 0, 1, 0.125d, 1);
+    
+    public BlockHayBed(String name, String local) 
+    {
+        super(name, local, ModItems.realHayBed);
+        super.setSoundType(SoundType.PLANT);
+    }
+    
+    @Override
+    public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
+    {
+        return BOX;
+    }
+
+    @Override
+    public float getLayingHigh() 
+    {
+        return 0;
+    }
+}

+ 116 - 0
src/main/java/me/km/blocks/BlockSpikeTrap.java

@@ -0,0 +1,116 @@
+package me.km.blocks;
+
+import java.util.Random;
+import me.km.KajetansMod;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.MapColor;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.properties.IProperty;
+import net.minecraft.block.properties.PropertyEnum;
+import net.minecraft.block.state.BlockStateContainer;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.NonNullList;
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.World;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+public class BlockSpikeTrap extends BlockTrap
+{
+    // everything inspired by BlockWoodSlab
+    public static final PropertyEnum<EnumMetals> VARIANT = PropertyEnum.<EnumMetals>create("variant", EnumMetals.class);
+       
+    public BlockSpikeTrap(Material material, String name, String local) 
+    {
+        super(material, name, local);
+        super.setSoundType(SoundType.METAL);
+        super.setHardness(5);
+        super.setResistance(10);
+        super.setDefaultState(this.blockState.getBaseState().withProperty(VARIANT, EnumMetals.COPPER));
+    }
+    
+    @Override
+    public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, IBlockAccess worldIn, BlockPos pos) 
+    {
+        return BOX;
+    }
+
+    @Override
+    public void onEntityCollidedWithBlock(World w, BlockPos pos, IBlockState state, Entity ent) 
+    {
+        if(ent instanceof EntityLivingBase)
+        {
+            ent.attackEntityFrom(DamageSource.CACTUS, 1);
+        }
+    }
+
+    @Override
+    public void registerItemModel(ItemBlock itemBlock) 
+    {
+        for(EnumMetals metal : EnumMetals.values())
+        {
+            KajetansMod.proxy.registerItemRenderer(itemBlock, metal.getMetadata(), name, "variant=" + metal.getName());
+        }
+    }
+    
+    @Override
+    public MapColor getMapColor(IBlockState state)
+    {
+        return state.getValue(VARIANT).getMapColor();
+    }
+    
+    @Override
+    public Item getItemDropped(IBlockState state, Random rand, int fortune)
+    {
+        return Item.getItemFromBlock(ModBlocks.spikes);
+    }
+
+    @Override
+    public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state)
+    {
+        return new ItemStack(ModBlocks.spikes, 1, state.getValue(VARIANT).getMetadata());
+    }
+
+    @SideOnly(Side.CLIENT)
+    @Override
+    public void getSubBlocks(Item item, CreativeTabs tab, NonNullList<ItemStack> list)
+    {
+        for(EnumMetals metal : EnumMetals.values())
+        {
+            list.add(new ItemStack(item, 1, metal.getMetadata()));
+        }
+    }
+
+    @Override
+    public IBlockState getStateFromMeta(int meta)
+    {
+        return this.getDefaultState().withProperty(VARIANT, EnumMetals.byMetadata(meta));
+    }
+
+    @Override
+    public int getMetaFromState(IBlockState state)
+    {
+        return state.getValue(VARIANT).getMetadata();
+    }
+
+    @Override
+    protected BlockStateContainer createBlockState()
+    {
+        return new BlockStateContainer(this, new IProperty[] {VARIANT});
+    }
+
+    @Override
+    public int damageDropped(IBlockState state)
+    {
+        return state.getValue(VARIANT).getMetadata();
+    }
+}

+ 47 - 0
src/main/java/me/km/blocks/BlockTallGrass.java

@@ -0,0 +1,47 @@
+package me.km.blocks;
+
+import me.km.items.ModItems;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.entity.Entity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.NonNullList;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.World;
+
+public class BlockTallGrass extends net.minecraft.block.BlockTallGrass
+{
+    private final SoundType type;
+    
+    public BlockTallGrass()
+    {
+        super.setHardness(0);
+        type = SoundType.PLANT;
+    }
+
+    @Override
+    public SoundType getSoundType(IBlockState state, World world, BlockPos pos, Entity entity) 
+    {
+        return type;
+    }
+    
+    @Override
+    public NonNullList<ItemStack> getDrops(IBlockAccess w, BlockPos pos, IBlockState state, int fortune)
+    {
+        int rand = RANDOM.nextInt(8);
+        if(rand <= 3)
+        {
+            return NonNullList.withSize(1, new ItemStack(ModItems.hayBundle));
+        }
+        else if(RANDOM.nextInt(8) == 4) 
+        {
+            ItemStack seed = net.minecraftforge.common.ForgeHooks.getGrassSeed(RANDOM, fortune);
+            if(!seed.isEmpty())
+            {
+                return NonNullList.withSize(1, seed);
+            }
+        }
+        return NonNullList.create();
+    }
+}

+ 82 - 0
src/main/java/me/km/blocks/BlockTrap.java

@@ -0,0 +1,82 @@
+package me.km.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.util.BlockRenderLayer;
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.World;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+public class BlockTrap extends BlockBase
+{
+    protected static final AxisAlignedBB BOX = new AxisAlignedBB(0, 0, 0, 1, 0.0625d, 1);
+    
+    public BlockTrap(Material material, String name, String local) 
+    {
+        super(material, name, local);
+    }  
+    
+    @Override
+    public void neighborChanged(IBlockState state, World w, BlockPos pos, Block b, BlockPos fromPos)
+    {
+        if(!w.getBlockState(pos.down()).getMaterial().isSolid())
+        {
+            this.dropBlockAsItem(w, pos, state, 0);
+            w.setBlockToAir(pos);
+        }
+        super.neighborChanged(state, w, pos, b, fromPos);
+    }
+    
+    @Override
+    public boolean canPlaceBlockAt(World w, BlockPos pos)
+    {
+        return w.getBlockState(pos.down()).getMaterial().isSolid() && super.canPlaceBlockAt(w, pos);
+    }
+
+    @Override
+    public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) 
+    {
+        return BOX;
+    }
+
+    @Override
+    public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, IBlockAccess worldIn, BlockPos pos) 
+    {
+        return NULL_AABB;
+    }
+    
+    @Override
+    public boolean isOpaqueCube(IBlockState state)
+    {
+        return false;
+    }
+
+    @Override
+    public boolean isFullCube(IBlockState state)
+    {
+        return false;
+    }
+    
+    @Override
+    public boolean canSpawnInBlock()
+    {
+        return false;
+    }
+    
+    @SideOnly(Side.CLIENT)
+    @Override
+    public BlockRenderLayer getBlockLayer()
+    {
+        return BlockRenderLayer.CUTOUT;
+    }
+    
+    @Override
+    public boolean blocksMovement(IBlockAccess worldIn, BlockPos pos)
+    {
+        return false;
+    }
+}

+ 80 - 0
src/main/java/me/km/blocks/EnumMetals.java

@@ -0,0 +1,80 @@
+package me.km.blocks;
+
+import me.km.items.ModItems;
+import net.minecraft.block.material.MapColor;
+import net.minecraft.init.Items;
+import net.minecraft.item.Item;
+import net.minecraft.util.IStringSerializable;
+
+public enum EnumMetals implements IStringSerializable
+{
+    COPPER(0, "copper", MapColor.BROWN, ModItems.copperIngot),
+    TIN(1, "tin", MapColor.SILVER, ModItems.tinIngot),
+    BRONZE(2, "bronze", MapColor.YELLOW, ModItems.bronzeIngot),
+    GOLD(3, "gold", MapColor.GOLD, Items.GOLD_INGOT),
+    IRON(4, "iron", MapColor.IRON, Items.IRON_INGOT),
+    SILVER(5, "silver", MapColor.IRON, ModItems.silverIngot);
+
+    private static final EnumMetals[] META_LOOKUP = new EnumMetals[values().length];
+    private final int meta;
+    private final String name;
+    private final MapColor mapColor;
+    private final Item item;
+
+    private EnumMetals(int meta, String name, MapColor mapColor, Item item)
+    {
+        this.meta = meta;
+        this.name = name;
+        this.mapColor = mapColor;
+        this.item = item;
+    }
+
+    public Item getMetalIngot() 
+    {
+        return item;
+    }
+    
+    public int getMetadata()
+    {
+        return this.meta;
+    }
+
+    public MapColor getMapColor()
+    {
+        return this.mapColor;
+    }
+
+    @Override
+    public String toString()
+    {
+        return this.name;
+    }
+
+    public static EnumMetals byMetadata(int meta)
+    {
+        if (meta < 0 || meta >= META_LOOKUP.length)
+        {
+            meta = 0;
+        }
+        return META_LOOKUP[meta];
+    }
+
+    @Override
+    public String getName()
+    {
+        return this.name;
+    }
+
+    public String getUnlocalizedName()
+    {
+        return this.name;
+    }
+
+    static
+    {
+        for(EnumMetals metal : values())
+        {
+            META_LOOKUP[metal.getMetadata()] = metal;
+        }
+    }
+}

+ 55 - 9
src/main/java/me/km/blocks/ModBlocks.java

@@ -4,11 +4,13 @@ import me.km.fluids.BlockFluidBase;
 import me.km.fluids.BlockFluidHoney;
 import me.km.fluids.BlockFluidPoison;
 import me.km.fluids.ModFluids;
-import me.km.items.ModItems;
+import me.km.items.ItemMetal;
 import net.minecraft.block.Block;
-import net.minecraft.block.SoundType;
+import net.minecraft.block.material.MapColor;
 import net.minecraft.block.material.Material;
+import net.minecraft.init.Blocks;
 import net.minecraft.item.ItemBlock;
+import net.minecraftforge.fml.common.registry.ExistingSubstitutionException;
 import net.minecraftforge.fml.common.registry.GameRegistry;
 
 public class ModBlocks 
@@ -22,10 +24,17 @@ public class ModBlocks
     
     public static BlockBase bronzeBlock;
     
+    public static BlockOre silverOre;
+    public static BlockBase silverBlock;
+    
     // misc
     public static BlockBase guildblock;
+    public static BlockBase artefact;
     public static BlockHay realHayBlock;
-    public static BlockBed realHayBed;
+    public static BlockHayBed realHayBed;
+    
+    // traps
+    public static BlockSpikeTrap spikes;
     
     // fluids
     public static BlockFluidPoison poison;
@@ -36,24 +45,54 @@ public class ModBlocks
         // ores + blocks
         copperOre = register(new BlockOre("copper_ore", "oreCopper"));      
         copperBlock = register((BlockBase) new BlockBase(Material.IRON, "copper_block", "blockCopper")
-                .setHardness(3).setResistance(10));
+                .setMapColor(MapColor.BROWN).setHardness(3).setResistance(10));
         tinOre = register(new BlockOre("tin_ore", "oreTin"));      
         tinBlock = register((BlockBase) new BlockBase(Material.IRON, "tin_block", "blockTin")
-                .setHardness(3).setResistance(5));
+                .setMapColor(MapColor.IRON).setHardness(3).setResistance(5));
         bronzeBlock = register((BlockBase) new BlockBase(Material.IRON, "bronze_block", "blockBronze")
-                .setHardness(5).setResistance(10));
+                .setMapColor(MapColor.YELLOW).setHardness(5).setResistance(10));
+        silverOre = register(new BlockOre("silver_ore", "oreSilver"));      
+        silverBlock = register((BlockBase) new BlockBase(Material.IRON, "silver_block", "blockSilver")
+                .setMapColor(MapColor.IRON).setHardness(5).setResistance(10));
         
         // misc
         guildblock = register((BlockBase) new BlockBase(Material.IRON, "guild_block", "blockGuild")
                 .setHardness(50.0F).setResistance(2000.0F));
-        realHayBlock = register((BlockHay) new BlockHay("real_hay_block", "realHayBlock")
-                .setSoundType(SoundType.PLANT).setHardness(0.5F));
-        realHayBed = registerBlock(new BlockBed("real_hay_bed", "realHayBlock", ModItems.realHayBed));
+        artefact = register((BlockBase) new BlockBase(Material.IRON, "artefact", "artefact")
+                .setHardness(50.0F).setResistance(2000.0F));
+        realHayBlock = register(new BlockHay("real_hay_block", "realHayBlock"));
+        realHayBed = registerBlock(new BlockHayBed("real_hay_bed", "realHayBlock"));
+        
+        // traps
+        spikes = registerMetal(new BlockSpikeTrap(Material.IRON, "spikes", "spikes"));
     
         // fluids
         poison = register(new BlockFluidPoison(ModFluids.poison, Material.WATER));
         honey = register(new BlockFluidHoney(ModFluids.honey, Material.WATER));
     }
+    
+    // THIS IS ONLY FOR REPLACING VANILLA BLOCKS
+    public static void lateInit() 
+    {
+        BlockTallGrass grass = new BlockTallGrass();
+        overwriteBlock(Blocks.TALLGRASS, grass);
+    }
+    
+    @SuppressWarnings("")
+    private static void overwriteBlock(Block old, Block block)
+    {
+        try
+        {
+            GameRegistry.addSubstitutionAlias(old.getRegistryName().toString(), 
+                    GameRegistry.Type.BLOCK, 
+                    block.setRegistryName(old.getRegistryName().getResourcePath()).setUnlocalizedName(old.getUnlocalizedName().substring(5)));
+        }
+        catch(ExistingSubstitutionException | NullPointerException ex)
+        {
+            System.out.println(ex);
+        }
+    }
+    //END OF REPLACING VANILLA BLOCKS
 
     private static <T extends Block> T register(T block, ItemBlock itemBlock) 
     {
@@ -82,4 +121,11 @@ public class ModBlocks
         itemBlock.setRegistryName(block.getRegistryName());
         return register(block, itemBlock);
     }
+    
+    private static <T extends Block> T registerMetal(T block) 
+    {
+        ItemMetal itemBlock = new ItemMetal(block);
+        itemBlock.setRegistryName(block.getRegistryName());
+        return register(block, itemBlock);
+    }
 }

+ 1 - 1
src/main/java/me/km/commands/CommandCoords.java

@@ -33,7 +33,7 @@ public class CommandCoords extends ModuleCommand
         }
         EntityPlayer p = (EntityPlayer) cs;
         World w = cs.getEntityWorld();
-        BlockPos pos = Utils.getPlayerTarget(p);
+        BlockPos pos = Utils.getPlayerTarget(p, 8, true);
         if(w.isAirBlock(pos))
         {
             this.getModule().send(cs, "Du musst auf einen Block gerichtet sein.");

+ 53 - 0
src/main/java/me/km/dimensions/ModWorldGeneration.java

@@ -0,0 +1,53 @@
+package me.km.dimensions;
+
+import java.util.Random;
+import me.km.blocks.ModBlocks;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.init.Biomes;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+import net.minecraft.world.biome.Biome;
+import net.minecraft.world.chunk.IChunkGenerator;
+import net.minecraft.world.chunk.IChunkProvider;
+import net.minecraft.world.gen.feature.WorldGenMinable;
+import net.minecraftforge.fml.common.IWorldGenerator;
+
+public class ModWorldGeneration implements IWorldGenerator
+{
+    @Override
+    public void generate(Random random, int chunkX, int chunkZ, World w, 
+            IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) 
+    {
+        Biome biome = w.getBiome(BlockPos.ORIGIN);
+        if(biome != Biomes.HELL && biome != Biomes.SKY) 
+        {
+            generateOverworld(random, chunkX, chunkZ, w, chunkGenerator, chunkProvider);
+	}
+    }
+	
+    private void generateOverworld(Random random, int chunkX, int chunkZ, World w, 
+            IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) 
+    {
+        generateOre(ModBlocks.copperOre.getDefaultState(), w, random, 
+                chunkX << 4, chunkZ << 4, 0, 128, 20, 5);
+        generateOre(ModBlocks.tinOre.getDefaultState(), w, random, 
+                chunkX << 4, chunkZ << 4, 0, 96, 8, 3);
+        generateOre(ModBlocks.tinOre.getDefaultState(), w, random, 
+                chunkX << 4, chunkZ << 4, 0, 128, 16, 1);
+    } 
+    
+    private void generateOre(IBlockState ore, World world, Random random, int x, int z, 
+            int minY, int maxY, int size, int chances) 
+    {
+        int deltaY = maxY - minY;
+        BlockPos pos;
+        WorldGenMinable generator;
+        for (int i = 0; i < chances; i++) 
+        {
+            // generates position in chunk
+            pos = new BlockPos(x + random.nextInt(16), minY + random.nextInt(deltaY), z + random.nextInt(16));
+            generator = new WorldGenMinable(ore, size);
+            generator.generate(world, random, pos);
+        }
+    }
+}

+ 1 - 1
src/main/java/me/km/fluids/BlockFluidHoney.java

@@ -20,7 +20,7 @@ public class BlockFluidHoney extends BlockFluidBase
     {
         super(fluid, material);
     }
-
+    
     @Override
     public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, IBlockState state, Entity entityIn) 
     {

+ 1 - 0
src/main/java/me/km/fluids/ModFluids.java

@@ -22,6 +22,7 @@ public class ModFluids
                 new ResourceLocation(KajetansMod.MODID + ":blocks/" + name + "_still"), 
                 new ResourceLocation(KajetansMod.MODID + ":blocks/" + name + "_flow"));
         FluidRegistry.registerFluid(f);
+        FluidRegistry.addBucketForFluid(f);
         return f;
     }
 }

+ 28 - 0
src/main/java/me/km/items/ItemCylinder.java

@@ -0,0 +1,28 @@
+package me.km.items;
+
+import me.km.KajetansMod;
+import net.minecraft.client.model.ModelBiped;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.inventory.EntityEquipmentSlot;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+public class ItemCylinder extends ItemArmor
+{
+    public ItemCylinder(ArmorMaterial m, String name, String local) 
+    {
+        super(m, EntityEquipmentSlot.HEAD, name, local);
+    }
+    
+    @SideOnly(Side.CLIENT)
+    @Override
+    public ModelBiped getArmorModel(EntityLivingBase liv, ItemStack stack, EntityEquipmentSlot slot, ModelBiped normal) 
+    {
+        if(slot != EntityEquipmentSlot.HEAD)
+        {
+            return normal;
+        }
+        return KajetansMod.proxy.getCylinderModel();
+    }
+}

+ 28 - 0
src/main/java/me/km/items/ItemHat.java

@@ -0,0 +1,28 @@
+package me.km.items;
+
+import me.km.KajetansMod;
+import net.minecraft.client.model.ModelBiped;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.inventory.EntityEquipmentSlot;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+public class ItemHat extends ItemArmor
+{
+    public ItemHat(ArmorMaterial m, String name, String local) 
+    {
+        super(m, EntityEquipmentSlot.HEAD, name, local);
+    }
+    
+    @SideOnly(Side.CLIENT)
+    @Override
+    public ModelBiped getArmorModel(EntityLivingBase liv, ItemStack stack, EntityEquipmentSlot slot, ModelBiped normal) 
+    {
+        if(slot != EntityEquipmentSlot.HEAD)
+        {
+            return normal;
+        }
+        return KajetansMod.proxy.getStrawHatModel();
+    }
+}

+ 29 - 0
src/main/java/me/km/items/ItemMetal.java

@@ -0,0 +1,29 @@
+package me.km.items;
+
+import me.km.blocks.EnumMetals;
+import net.minecraft.block.Block;
+import net.minecraft.item.ItemBlock;
+import net.minecraft.item.ItemStack;
+
+public class ItemMetal extends ItemBlock
+{
+    // everything inspired by net.minecraft.item.ItemCloth
+    public ItemMetal(Block block)
+    {
+        super(block);
+        super.setMaxDamage(0);
+        super.setHasSubtypes(true);
+    }
+    
+    @Override
+    public int getMetadata(int damage)
+    {
+        return damage;
+    }
+
+    @Override
+    public String getUnlocalizedName(ItemStack stack)
+    {
+        return super.getUnlocalizedName() + "." + EnumMetals.byMetadata(stack.getMetadata()).getUnlocalizedName();
+    }
+}

+ 32 - 0
src/main/java/me/km/items/ModItems.java

@@ -1,6 +1,7 @@
 package me.km.items;
 
 import me.km.KajetansMod;
+import me.km.blocks.ModBlocks;
 import net.minecraft.creativetab.CreativeTabs;
 import net.minecraft.init.SoundEvents;
 import net.minecraft.inventory.EntityEquipmentSlot;
@@ -44,6 +45,15 @@ public class ModItems
     public static final ArmorMaterial ARMOR_BRONZE = 
             EnumHelper.addArmorMaterial("BRONZE", KajetansMod.MODID + ":bronze", 13, 
                     new int[]{2, 5, 6, 2}, 20, SoundEvents.ITEM_ARMOR_EQUIP_CHAIN, 0);
+    public static final ArmorMaterial ARMOR_STRAW = 
+            EnumHelper.addArmorMaterial("STRAW", KajetansMod.MODID + ":straw", 3, 
+                    new int[]{1, 1, 1, 1}, 3, SoundEvents.ITEM_ARMOR_EQUIP_LEATHER, 0);
+    public static final ArmorMaterial ARMOR_CYLINDER = 
+            EnumHelper.addArmorMaterial("CYLINDER", KajetansMod.MODID + ":CYLINDER", 3, 
+                    new int[]{1, 1, 1, 1}, 3, SoundEvents.ITEM_ARMOR_EQUIP_LEATHER, 0);
+    public static final ArmorMaterial ARMOR_SUIT = 
+            EnumHelper.addArmorMaterial("SUIT", KajetansMod.MODID + ":suit", 3, 
+                    new int[]{1, 1, 1, 1}, 3, SoundEvents.ITEM_ARMOR_EQUIP_LEATHER, 0);
     
     // nuggets and ingots
     public static ItemBase copperIngot;
@@ -55,6 +65,9 @@ public class ModItems
     public static ItemBase bronzeIngot;
     public static ItemBase bronzeNugget;
     
+    public static ItemBase silverIngot;
+    public static ItemBase silverNugget;
+    
     // tools and swords
     public static ItemSword copperSword;
     public static ItemSpade copperShovel;
@@ -79,6 +92,13 @@ public class ModItems
     public static ItemArmor bronzeLeggings;
     public static ItemArmor bronzeBoots;
     
+    public static ItemArmor cylinder;
+    public static ItemArmor suitChestplate;
+    public static ItemArmor suitLeggings;
+    public static ItemArmor suitBoots;
+    
+    public static ItemArmor strawHat;
+    
     // wands
     public static ItemWand woodenWand;
     
@@ -90,6 +110,7 @@ public class ModItems
     // misc
     public static ItemScroll scroll;
     public static ItemBed realHayBed; 
+    public static ItemBase hayBundle; 
     
     public static void init() 
     {
@@ -103,6 +124,9 @@ public class ModItems
         bronzeIngot = register(new ItemBase("bronze_ingot", "ingotBronze").setCreativeTab(CreativeTabs.MATERIALS));
         bronzeNugget = register(new ItemBase("bronze_nugget", "bronzeNugget").setCreativeTab(CreativeTabs.MATERIALS));
         
+        silverIngot = register(new ItemBase("silver_ingot", "ingotSilver").setCreativeTab(CreativeTabs.MATERIALS));
+        silverNugget = register(new ItemBase("silver_nugget", "silverNugget").setCreativeTab(CreativeTabs.MATERIALS));
+        
         // repair items
         TOOL_COPPER.setRepairItem(new ItemStack(copperIngot));
         ARMOR_COPPER.setRepairItem(new ItemStack(copperIngot));
@@ -133,6 +157,13 @@ public class ModItems
         bronzeLeggings = register(new ItemArmor(ARMOR_BRONZE, EntityEquipmentSlot.LEGS, "bronze_leggings", "leggingsBronze"));
         bronzeBoots = register(new ItemArmor(ARMOR_BRONZE, EntityEquipmentSlot.FEET, "bronze_boots", "bootsBronze"));
         
+        cylinder = register(new ItemCylinder(ARMOR_CYLINDER, "cylinder", "cylinder"));
+        suitChestplate = register(new ItemArmor(ARMOR_SUIT, EntityEquipmentSlot.CHEST, "suit_chestplate", "chestplateSuit"));
+        suitLeggings = register(new ItemArmor(ARMOR_SUIT, EntityEquipmentSlot.LEGS, "suit_leggings", "leggingsSuit"));
+        suitBoots = register(new ItemArmor(ARMOR_SUIT, EntityEquipmentSlot.FEET, "suit_boots", "bootsSuit"));
+        
+        strawHat = register(new ItemHat(ARMOR_STRAW, "straw_hat", "hatStraw"));
+        
         // wands
         woodenWand = register(new ItemWand("wood_wand", "wandWood", Item.ToolMaterial.WOOD, 1));
         
@@ -144,6 +175,7 @@ public class ModItems
         // misc
         scroll = register((ItemScroll) new ItemScroll("scroll", "scroll").setCreativeTab(CreativeTabs.MISC));
         realHayBed = register(new ItemBed("real_hay_bed", "realHayBed"));
+        hayBundle = register(new ItemBase("hay_bundle", "bundleHay").setCreativeTab(CreativeTabs.MATERIALS));
     }
 	
     private static <T extends Item> T register(T item) 

+ 28 - 4
src/main/java/me/km/items/ModRecipes.java

@@ -1,5 +1,6 @@
 package me.km.items;
 
+import me.km.blocks.EnumMetals;
 import me.km.blocks.ModBlocks;
 import net.minecraft.block.Block;
 import net.minecraft.init.Items;
@@ -22,10 +23,16 @@ public class ModRecipes
             ModItems.copperIngot, ModItems.copperIngot, ModItems.copperIngot,
             ModItems.copperIngot, ModItems.copperIngot, ModItems.tinIngot
         });
+        cm.addRecipe(new ItemStack(ModItems.realHayBed, 3), new Object[] {"XXX", 'X', ModBlocks.realHayBlock});
+        cm.addRecipe(new ItemStack(ModItems.strawHat, 1), new Object[] {" X ", "XXX", 'X', Items.WHEAT});
+        
+        // traps
+        addMetalRecipes(cm, new String[] {" X ", "XXX"}, ModBlocks.spikes, 3);
         
         // furnace recipes
         fr.addSmeltingRecipeForBlock(ModBlocks.copperOre, new ItemStack(ModItems.copperIngot), 0.5f);
         fr.addSmeltingRecipeForBlock(ModBlocks.tinOre, new ItemStack(ModItems.tinIngot), 1);
+        fr.addSmeltingRecipeForBlock(ModBlocks.silverOre, new ItemStack(ModItems.silverIngot), 1);
         
         // armor recipes
         String[][] armorPatterns = new String[][] {{"XXX", "X X"}, {"X X", "XXX", "XXX"}, {"XXX", "X X", "X X"}, {"X X", "X X"}};
@@ -69,6 +76,9 @@ public class ModRecipes
             {ModItems.tinIngot, new ItemStack(ModItems.tinNugget, 9)}, 
             {ModBlocks.bronzeBlock, new ItemStack(ModItems.bronzeIngot, 9)}, 
             {ModItems.bronzeIngot, new ItemStack(ModItems.bronzeNugget, 9)}, 
+            {ModBlocks.silverBlock, new ItemStack(ModItems.silverIngot, 9)}, 
+            {ModItems.silverIngot, new ItemStack(ModItems.silverNugget, 9)}, 
+            {ModBlocks.realHayBlock, new ItemStack(ModItems.hayBundle, 9)}, 
         };
         addIngotRecipes(cm, ingotItems);
 
@@ -91,11 +101,11 @@ public class ModRecipes
     
     private static void addToolRecipes(CraftingManager cm, String[][] toolPatterns, Object[][] toolItems)
     {
-        for (int i = 0; i < toolItems[0].length; ++i)
+        for(int i = 0; i < toolItems[0].length; ++i)
         {
             Object object = toolItems[0][i];
 
-            for (int j = 0; j < toolItems.length - 1; ++j)
+            for(int j = 0; j < toolItems.length - 1; ++j)
             {
                 Item item = (Item) toolItems[j + 1][i];
                 cm.addRecipe(new ItemStack(item), new Object[] {toolPatterns[j], '#', Items.STICK, 'X', object});
@@ -105,10 +115,10 @@ public class ModRecipes
     
     private static void addWeaponRecipes(CraftingManager cm, String[][] weaponPatterns, Object[][] weaponItems)
     {
-        for (int i = 0; i < weaponItems[0].length; ++i)
+        for(int i = 0; i < weaponItems[0].length; ++i)
         {
             Object object = weaponItems[0][i];
-            for (int j = 0; j < weaponItems.length - 1; ++j)
+            for(int j = 0; j < weaponItems.length - 1; ++j)
             {
                 Item item = (Item) weaponItems[j + 1][i];
                 cm.addRecipe(new ItemStack(item), new Object[] {weaponPatterns[j], '#', Items.STICK, 'X', object});
@@ -159,4 +169,18 @@ public class ModRecipes
             }
         }
     }
+    
+    private static void addMetalRecipes(CraftingManager cm, String[] patterns, Item output, int amount)
+    {
+        for(EnumMetals metal : EnumMetals.values())
+        {
+            cm.addRecipe(new ItemStack(output, amount, metal.getMetadata()), 
+                    new Object[] {patterns, 'X', metal.getMetalIngot()});
+        }
+    }
+    
+    private static void addMetalRecipes(CraftingManager cm, String[] patterns, Block output, int amount)
+    {
+        addMetalRecipes(cm, patterns, Item.getItemFromBlock(output), amount);
+    }
 }

+ 78 - 0
src/main/java/me/km/items/ModelCylinder.java

@@ -0,0 +1,78 @@
+package me.km.items;
+
+import static net.minecraft.client.model.ModelBase.copyModelAngles;
+import net.minecraft.client.model.ModelBiped;
+import net.minecraft.client.model.ModelRenderer;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.item.EntityArmorStand;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class ModelCylinder extends ModelBiped
+{
+    private final ModelRenderer firstHeadPart;
+    private final ModelRenderer secHeadPart;
+
+    public ModelCylinder(float scale)
+    {
+        super(scale, 0, 64, 64);
+    
+        firstHeadPart = new ModelRenderer(this, 0, 32);
+        firstHeadPart.addBox(-5, -8.6f, -5, 10, 1, 10);
+        firstHeadPart.setRotationPoint(0F, 0F, 0F);
+        firstHeadPart.setTextureSize(64, 64);
+        firstHeadPart.mirror = true;
+        setRotation(firstHeadPart, 0, 0, 0);
+        
+        secHeadPart = new ModelRenderer(this, 0, 43);
+        secHeadPart.addBox(-3, -15.6f, -3, 6, 7, 6);
+        secHeadPart.setRotationPoint(0F, 0F, 0F);
+        secHeadPart.setTextureSize(64, 64);
+        secHeadPart.mirror = true;
+        setRotation(secHeadPart, 0, 0, 0);
+         
+        bipedHead.addChild(firstHeadPart);
+        bipedHead.addChild(secHeadPart);
+    }
+    
+    @Override
+    public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entityIn)
+    {
+        if (entityIn instanceof EntityArmorStand)
+        {
+            EntityArmorStand entityarmorstand = (EntityArmorStand)entityIn;
+            this.bipedHead.rotateAngleX = 0.017453292F * entityarmorstand.getHeadRotation().getX();
+            this.bipedHead.rotateAngleY = 0.017453292F * entityarmorstand.getHeadRotation().getY();
+            this.bipedHead.rotateAngleZ = 0.017453292F * entityarmorstand.getHeadRotation().getZ();
+            this.bipedHead.setRotationPoint(0.0F, 1.0F, 0.0F);
+            this.bipedBody.rotateAngleX = 0.017453292F * entityarmorstand.getBodyRotation().getX();
+            this.bipedBody.rotateAngleY = 0.017453292F * entityarmorstand.getBodyRotation().getY();
+            this.bipedBody.rotateAngleZ = 0.017453292F * entityarmorstand.getBodyRotation().getZ();
+            this.bipedLeftArm.rotateAngleX = 0.017453292F * entityarmorstand.getLeftArmRotation().getX();
+            this.bipedLeftArm.rotateAngleY = 0.017453292F * entityarmorstand.getLeftArmRotation().getY();
+            this.bipedLeftArm.rotateAngleZ = 0.017453292F * entityarmorstand.getLeftArmRotation().getZ();
+            this.bipedRightArm.rotateAngleX = 0.017453292F * entityarmorstand.getRightArmRotation().getX();
+            this.bipedRightArm.rotateAngleY = 0.017453292F * entityarmorstand.getRightArmRotation().getY();
+            this.bipedRightArm.rotateAngleZ = 0.017453292F * entityarmorstand.getRightArmRotation().getZ();
+            this.bipedLeftLeg.rotateAngleX = 0.017453292F * entityarmorstand.getLeftLegRotation().getX();
+            this.bipedLeftLeg.rotateAngleY = 0.017453292F * entityarmorstand.getLeftLegRotation().getY();
+            this.bipedLeftLeg.rotateAngleZ = 0.017453292F * entityarmorstand.getLeftLegRotation().getZ();
+            this.bipedLeftLeg.setRotationPoint(1.9F, 11.0F, 0.0F);
+            this.bipedRightLeg.rotateAngleX = 0.017453292F * entityarmorstand.getRightLegRotation().getX();
+            this.bipedRightLeg.rotateAngleY = 0.017453292F * entityarmorstand.getRightLegRotation().getY();
+            this.bipedRightLeg.rotateAngleZ = 0.017453292F * entityarmorstand.getRightLegRotation().getZ();
+            this.bipedRightLeg.setRotationPoint(-1.9F, 11.0F, 0.0F);
+            copyModelAngles(this.bipedHead, this.bipedHeadwear);
+            return;
+        }
+        super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entityIn);
+    }
+
+    private void setRotation(ModelRenderer model, float x, float y, float z)
+    {
+        model.rotateAngleX = x;
+        model.rotateAngleY = y;
+        model.rotateAngleZ = z;
+    }
+}

+ 78 - 0
src/main/java/me/km/items/ModelHat.java

@@ -0,0 +1,78 @@
+package me.km.items;
+
+import static net.minecraft.client.model.ModelBase.copyModelAngles;
+import net.minecraft.client.model.ModelBiped;
+import net.minecraft.client.model.ModelRenderer;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.item.EntityArmorStand;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class ModelHat extends ModelBiped
+{
+    private final ModelRenderer firstHeadPart;
+    private final ModelRenderer secHeadPart;
+
+    public ModelHat(float scale)
+    {
+        super(scale, 0, 64, 64);
+    
+        firstHeadPart = new ModelRenderer(this, 0, 32);
+        firstHeadPart.addBox(-5, -8.6f, -5, 10, 1, 10);
+        firstHeadPart.setRotationPoint(0F, 0F, 0F);
+        firstHeadPart.setTextureSize(64, 64);
+        firstHeadPart.mirror = true;
+        setRotation(firstHeadPart, 0, 0, 0);
+        
+        secHeadPart = new ModelRenderer(this, 0, 43);
+        secHeadPart.addBox(-3, -11.6f, -3, 6, 3, 6);
+        secHeadPart.setRotationPoint(0F, 0F, 0F);
+        secHeadPart.setTextureSize(64, 64);
+        secHeadPart.mirror = true;
+        setRotation(secHeadPart, 0, 0, 0);
+         
+        bipedHead.addChild(firstHeadPart);
+        bipedHead.addChild(secHeadPart);
+    }
+    
+    @Override
+    public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entityIn)
+    {
+        if (entityIn instanceof EntityArmorStand)
+        {
+            EntityArmorStand entityarmorstand = (EntityArmorStand)entityIn;
+            this.bipedHead.rotateAngleX = 0.017453292F * entityarmorstand.getHeadRotation().getX();
+            this.bipedHead.rotateAngleY = 0.017453292F * entityarmorstand.getHeadRotation().getY();
+            this.bipedHead.rotateAngleZ = 0.017453292F * entityarmorstand.getHeadRotation().getZ();
+            this.bipedHead.setRotationPoint(0.0F, 1.0F, 0.0F);
+            this.bipedBody.rotateAngleX = 0.017453292F * entityarmorstand.getBodyRotation().getX();
+            this.bipedBody.rotateAngleY = 0.017453292F * entityarmorstand.getBodyRotation().getY();
+            this.bipedBody.rotateAngleZ = 0.017453292F * entityarmorstand.getBodyRotation().getZ();
+            this.bipedLeftArm.rotateAngleX = 0.017453292F * entityarmorstand.getLeftArmRotation().getX();
+            this.bipedLeftArm.rotateAngleY = 0.017453292F * entityarmorstand.getLeftArmRotation().getY();
+            this.bipedLeftArm.rotateAngleZ = 0.017453292F * entityarmorstand.getLeftArmRotation().getZ();
+            this.bipedRightArm.rotateAngleX = 0.017453292F * entityarmorstand.getRightArmRotation().getX();
+            this.bipedRightArm.rotateAngleY = 0.017453292F * entityarmorstand.getRightArmRotation().getY();
+            this.bipedRightArm.rotateAngleZ = 0.017453292F * entityarmorstand.getRightArmRotation().getZ();
+            this.bipedLeftLeg.rotateAngleX = 0.017453292F * entityarmorstand.getLeftLegRotation().getX();
+            this.bipedLeftLeg.rotateAngleY = 0.017453292F * entityarmorstand.getLeftLegRotation().getY();
+            this.bipedLeftLeg.rotateAngleZ = 0.017453292F * entityarmorstand.getLeftLegRotation().getZ();
+            this.bipedLeftLeg.setRotationPoint(1.9F, 11.0F, 0.0F);
+            this.bipedRightLeg.rotateAngleX = 0.017453292F * entityarmorstand.getRightLegRotation().getX();
+            this.bipedRightLeg.rotateAngleY = 0.017453292F * entityarmorstand.getRightLegRotation().getY();
+            this.bipedRightLeg.rotateAngleZ = 0.017453292F * entityarmorstand.getRightLegRotation().getZ();
+            this.bipedRightLeg.setRotationPoint(-1.9F, 11.0F, 0.0F);
+            copyModelAngles(this.bipedHead, this.bipedHeadwear);
+            return;
+        }
+        super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entityIn);
+    }
+
+    private void setRotation(ModelRenderer model, float x, float y, float z)
+    {
+        model.rotateAngleX = x;
+        model.rotateAngleY = y;
+        model.rotateAngleZ = z;
+    }
+}

+ 1 - 5
src/main/java/me/km/scoreboard/ScoreBoardLeave.java

@@ -4,7 +4,6 @@ import me.km.KajetansMod;
 import me.km.api.Module;
 import me.km.api.ModuleListener;
 import me.km.events.PlayerLeaveMessageEvent;
-import net.minecraft.entity.player.EntityPlayerMP;
 import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
 
 public class ScoreBoardLeave extends ModuleListener
@@ -17,9 +16,6 @@ public class ScoreBoardLeave extends ModuleListener
     @SubscribeEvent
     public void onPlayerLeaveCleanup(PlayerLeaveMessageEvent e)
     {      
-        if(e.getEntityPlayer() instanceof EntityPlayerMP)
-        {
-            KajetansMod.scoreboard.removeScoreboard((EntityPlayerMP) e.getEntityPlayer());
-        }
+        KajetansMod.scoreboard.removeScoreboard(e.getEntityPlayer().getUniqueID());
     }
 }

+ 3 - 3
src/main/java/me/km/scoreboard/ScoreboardAPI.java

@@ -28,9 +28,9 @@ public class ScoreboardAPI extends Module
         boards.put(p.getUniqueID(), new PlayerScoreboard(p));
     }
     
-    public void removeScoreboard(EntityPlayerMP p)
+    public void removeScoreboard(UUID uuid)
     {
-        boards.remove(p.getUniqueID(), new PlayerScoreboard(p));
+        boards.remove(uuid);
     }
     
     public PlayerScoreboard getScoreboard(EntityPlayerMP p)
@@ -42,7 +42,7 @@ public class ScoreboardAPI extends Module
             boards.put(p.getUniqueID(), data);
             return data;
         }
-        return boards.get(p.getUniqueID());
+        return data;
     }
     
     public void resetScoreboard(EntityPlayerMP p)

+ 16 - 3
src/main/java/me/km/snuviscript/ScriptUtils.java

@@ -159,11 +159,24 @@ public class ScriptUtils
     private static ItemStack getSimpleItemStack(String stack) throws IllegalItemStackStringException
     {
         String[] parts = stack.split(":");
-        if(!parts[0].startsWith("km:") && !parts[0].startsWith("minecraft:"))
+        if(parts[0].equals("km") || parts[0].equals("minecraft"))
         {
-            parts[0] = "minecraft:" + parts[0];
+            if(parts.length <= 1)
+            {
+                throw new IllegalItemStackStringException(stack);
+            }
+            String[] newParts = new String[parts.length - 1];
+            newParts[0] = parts[0].toLowerCase() + ":" + parts[1].toLowerCase();
+            for(int i = 1; i < newParts.length; i++)
+            {
+                newParts[i] = parts[i + 1].toLowerCase();
+            }
+            parts = newParts;
+        }
+        else
+        {
+            parts[0] = "minecraft:" + parts[0].toLowerCase();
         }
-        parts[0] = parts[0].toLowerCase();
         int amount = 1;
         int data = 0;
         if(parts.length >= 2)

+ 2 - 1
src/main/java/me/km/snuviscript/ScriptVars.java

@@ -10,11 +10,12 @@ import net.minecraft.world.World;
 
 public class ScriptVars 
 {  
+    @SuppressWarnings("")
     public static void setBlockVars(Script qd, World w, BlockPos pos)
     {               
         IBlockState state = w.getBlockState(pos);
         qd.setVar("block-loc", new Location(w, pos));
-        qd.setVar("block-type", state.getBlock().getRegistryName());
+        qd.setVar("block-type", state.getBlock().getRegistryName().toString());
         qd.setVar("block-data", state.getBlock().getMetaFromState(state));
     }
     

+ 42 - 6
src/main/java/me/km/snuviscript/SnuviParser.java

@@ -49,6 +49,7 @@ import me.km.utils.RecipeUtils;
 import me.km.utils.ReflectionUtils;
 import me.km.utils.SpecialBlockUtils;
 import net.minecraft.block.Block;
+import net.minecraft.block.BlockDoor;
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.command.ICommandSender;
 import net.minecraft.enchantment.Enchantment;
@@ -119,7 +120,7 @@ public class SnuviParser
         registerFunction(list, s, list.get(translator.get(original))); 
     }
     
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings("")
     public SnuviParser()
     {
         ArrayList<BiFunction<Object[], Script, Object>> list = new ArrayList<>();
@@ -321,7 +322,7 @@ public class SnuviParser
         registerConsumer(list, "item.drop", (args, qd) ->       
                 dropItem(args));                              
         registerFunction(list, "item.gettype", (args, qd) ->    
-                ((ItemStack) args[0]).getItem().getRegistryName().getResourcePath());
+                ((ItemStack) args[0]).getItem().getRegistryName().toString());
         registerFunction(list, "item.getdata", (args, qd) ->    
                 ((ItemStack) args[0]).getMetadata());           
         registerConsumer(list, "item.setdata", (args, qd) ->    
@@ -367,7 +368,7 @@ public class SnuviParser
         // Block-Bibliothek
         // -------------------------------------------------------------    
         registerFunction(list, "block.gettype", (args, qd) -> 
-                ((Location) args[0]).getWorld().getBlockState(((Location) args[0]).getBlockPos()).getBlock().getRegistryName());
+                ((Location) args[0]).getWorld().getBlockState(((Location) args[0]).getBlockPos()).getBlock().getRegistryName().toString());
         registerFunction(list, "block.getdata", (args, qd) -> 
                 getBlockData((Location) args[0]));
         registerConsumer(list, "block.clone", (args, qd) -> 
@@ -380,8 +381,14 @@ public class SnuviParser
                 setSign(args));
         registerFunction(list, "block.getsign", (args, qd) -> 
                 getSign(args));
+        registerConsumer(list, "block.setdoorstatus", (args, qd) -> 
+                setDoorStatus(args));
+        registerFunction(list, "block.getdoorstatus", (args, qd) -> 
+                getDoorStatus(args));
+        registerFunction(list, "block.isdoor", (args, qd) -> 
+                isDoor(args));
         registerFunction(list, "block.issolid", (args, qd) -> 
-                getBlockState((Location) args[0]).isFullCube());
+                isSolid(args));
         registerFunction(list, "block.tostack", (args, qd) -> 
                 getStackFromBlock((Location) args[0]));
         registerFunction(list, "block.getitemamount", (args, qd) -> 
@@ -927,7 +934,7 @@ public class SnuviParser
     
     public boolean printStack = false;
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings("")
     public Object parseFunction(Script qd, int function, Object[] args)
     {
         try
@@ -993,6 +1000,25 @@ public class SnuviParser
     // Quest Befehle
     // -----------------------
     
+    private boolean isDoor(Object[] args)
+    {
+        Location l = (Location) args[0];
+        return l.getWorld().getBlockState(l.getBlockPos()).getBlock() instanceof BlockDoor;
+    }
+    
+    private boolean getDoorStatus(Object[] args)
+    {
+        Location l = (Location) args[0];
+        return l.getWorld().getBlockState(l.getBlockPos()).getValue(BlockDoor.OPEN);
+    }
+    
+    private void setDoorStatus(Object[] args)
+    {
+        Location l = (Location) args[0];
+        BlockPos pos = l.getBlockPos();
+        ((BlockDoor) l.getWorld().getBlockState(pos).getBlock()).toggleDoor(l.getWorld(), pos, (boolean) args[1]);
+    }
+    
     private void playerSay(Object[] args)
     {
         try
@@ -1287,12 +1313,19 @@ public class SnuviParser
         SpecialBlockUtils.setSignLine(sign, ScriptUtils.getInt(args[1]), ScriptUtils.connect(args, 2));
     }
     
+    @SuppressWarnings("")
     private String getSign(Object[] args) throws IllegalStringLocationException
     {
         Location l = (Location) args[0];
         TileEntitySign sign = (TileEntitySign) l.getWorld().getTileEntity(l.getBlockPos());
         return sign.signText[ScriptUtils.getInt(args[1])].getUnformattedText();
     }
+    
+    private boolean isSolid(Object[] args)
+    {
+        IBlockState state = getBlockState((Location) args[0]);
+        return !state.isTranslucent() && state.isFullBlock() && state.isOpaqueCube();
+    }
 
     private void spawnItemFrame(Object[] args) throws IllegalStringLocationException, IllegalItemStackStringException
     {
@@ -1415,6 +1448,7 @@ public class SnuviParser
         }, ScriptUtils.getInt(args[0]));
     }
     
+    @SuppressWarnings("")
     private void waitFor(Object[] args, Script qd) throws UnsupportedOperationException
     {           
         qd.resetOverflowProtection();
@@ -1533,6 +1567,7 @@ public class SnuviParser
         return ds.getSourceOfDamage();
     }
     
+    @SuppressWarnings("")
     private SnuviInventory newInventory(Location l, Script qd, String s)
     {
         TileEntityChest chest = (TileEntityChest) l.getWorld().getTileEntity(l.getBlockPos());
@@ -1594,9 +1629,10 @@ public class SnuviParser
         return KajetansMod.playerbank.getDataBank().getUUID(o.toString());
     }
     
+    @SuppressWarnings("")
     private String getPotionType(Object[] args)
     {
-        return PotionUtils.getPotionFromItem(((EntityPotion) args[0]).getPotion()).getRegistryName().getResourcePath();
+        return PotionUtils.getPotionFromItem(((EntityPotion) args[0]).getPotion()).getRegistryName().toString();
     }
     
     private void setTag(Object[] args)

+ 56 - 0
src/main/java/me/km/utils/ReflectionUtils.java

@@ -2,9 +2,11 @@ package me.km.utils;
 
 import java.lang.reflect.Field;
 import java.util.Map;
+import java.util.Random;
 import java.util.UUID;
 import net.minecraft.block.Block;
 import net.minecraft.block.material.Material;
+import net.minecraft.entity.Entity;
 import net.minecraft.entity.item.EntityItem;
 import net.minecraft.entity.passive.EntityVillager;
 import net.minecraft.entity.player.EntityPlayerMP;
@@ -12,6 +14,7 @@ import net.minecraft.entity.player.PlayerCapabilities;
 import net.minecraft.entity.projectile.EntityArrow;
 import net.minecraft.server.management.PlayerList;
 import net.minecraft.util.FoodStats;
+import net.minecraft.world.Explosion;
 import net.minecraftforge.fml.relauncher.ReflectionHelper;
 
 public class ReflectionUtils 
@@ -83,6 +86,19 @@ public class ReflectionUtils
         }
     }
     
+    private static <T> boolean getBoolean(T t, Field f, boolean error)
+    {
+        try
+        {
+            return f.getBoolean(t);
+        }
+        catch(SecurityException | IllegalArgumentException | IllegalAccessException | NullPointerException ex)
+        {
+            System.out.println(f + " - " + ex);
+            return error;
+        }
+    }
+    
     private static <T> T getFieldValue(Class<T> cast, Object o, Field f)
     {
         try
@@ -153,6 +169,46 @@ public class ReflectionUtils
         setFloat(cap, WALK_SPEED, f);
     }
     
+    // -----------------------------------------------------------------------------------
+    // explosion stuff
+    // -----------------------------------------------------------------------------------
+    
+    private final static Field IS_FLAMING = getField(Explosion.class, "field_77286_a", "isFlaming");
+    private final static Field IS_SMOKING = getField(Explosion.class, "field_82755_b", "isSmoking");
+    private final static Field EXPLOSION_RNG = getField(Explosion.class, "field_77290_i", "explosionRNG");
+    private final static Field EXPLOSION_SIZE = getField(Explosion.class, "field_77280_f", "explosionSize");
+    private final static Field EXPLODER = getField(Explosion.class, "field_77283_e", "exploder");
+    
+    public static boolean isFlaming(Explosion ex)
+    {
+        return getBoolean(ex, IS_FLAMING, false);
+    }
+    
+    public static boolean isSmoking(Explosion ex)
+    {
+        return getBoolean(ex, IS_SMOKING, false);
+    }
+    
+    public static Random getRandom(Explosion ex)
+    {
+        return getFieldValue(Random.class, ex, EXPLOSION_RNG);
+    }
+    
+    public static float getSize(Explosion ex)
+    {
+        return getFloat(ex, EXPLOSION_SIZE, 1); // 1 for preventing zero dividing
+    }
+    
+    public static void setSize(Explosion ex, float f)
+    {
+        setFloat(ex, EXPLOSION_SIZE, f);
+    }
+    
+    public static Entity getExploder(Explosion ex)
+    {
+        return getFieldValue(Entity.class, ex, EXPLODER);
+    }
+    
     // -----------------------------------------------------------------------------------
     // random field gets
     // -----------------------------------------------------------------------------------

BIN
src/main/resources/assets/forge/models/textures/items/honey_bucket.png


BIN
src/main/resources/assets/forge/models/textures/items/poison_bucket.png


+ 5 - 0
src/main/resources/assets/km/blockstates/artefact.json

@@ -0,0 +1,5 @@
+{
+    "variants": {
+        "normal": { "model": "km:artefact" }
+    }
+}

+ 5 - 0
src/main/resources/assets/km/blockstates/silver_block.json

@@ -0,0 +1,5 @@
+{
+    "variants": {
+        "normal": { "model": "km:silver_block" }
+    }
+}

+ 5 - 0
src/main/resources/assets/km/blockstates/silver_ore.json

@@ -0,0 +1,5 @@
+{
+    "variants": {
+        "normal": { "model": "km:silver_ore" }
+    }
+}

+ 18 - 0
src/main/resources/assets/km/blockstates/spikes.json

@@ -0,0 +1,18 @@
+{
+    "forge_marker": 1,
+    "defaults": {
+        "model": "km:spikes",
+        "uvlock": true
+    },
+    "variants": {
+        "variant"  : { 
+            "copper" : { "textures": { "side": "km:blocks/copper_block" } },
+            "tin" : { "textures": { "side": "km:blocks/tin_block" } },
+            "bronze" : { "textures": { "side": "km:blocks/bronze_block" } },
+            "gold" : { "textures": { "side": "blocks/gold_block" } },
+            "iron" : { "textures": { "side": "blocks/iron_block" } },
+            "silver" : { "textures": { "side": "km:blocks/silver_block" } }
+        }
+    }
+}
+

+ 29 - 4
src/main/resources/assets/km/lang/en_US.lang

@@ -4,6 +4,8 @@ item.ingotTin.name=Tin Ingot
 item.tinNugget.name=Tin Nugget
 item.ingotBronze.name=Bronze Ingot
 item.bronzeNugget.name=Bronze Nugget
+item.ingotSilver.name=Silver Ingot
+item.silverNugget.name=Silver Nugget
 
 item.swordCopper.name=Copper Sword
 item.shovelCopper.name=Copper Shovel
@@ -27,26 +29,49 @@ item.chestplateBronze.name=Bronze Chestplate
 item.leggingsBronze.name=Bronze Leggings
 item.bootsBronze.name=Bronze Boots
 
+
 tile.oreCopper.name=Copper Ore
 tile.blockCopper.name=Copper Block
 tile.oreTin.name=Tin Ore
 tile.blockTin.name=Tin Block
 tile.blockBronze.name=Bronze Block
+tile.oreSilver.name=Silver Ore
+tile.blockSilver.name=Silver Block
 
+tile.blockGuild.name=Guild Block
+tile.artefact.name=Artefact
 
 tile.hayBlock.name=Straw Bale
 tile.realHayBlock.name=Hay Bale
 
+tile.spikes.copper.name=Copper Spikes
+tile.spikes.tin.name=Tin Spikes
+tile.spikes.bronze.name=Bronze Spikes
+tile.spikes.gold.name=Gold Spikes
+tile.spikes.iron.name=Iron Spikes
+tile.spikes.silver.name=Silver Spikes
 
-item.coinCopper.name=Copper Coin
-item.coinSilver.name=Silver Coin
-item.coinGold.name=Gold Coin
 
 tile.fluid.poison.name=Poison
 tile.fluid.honey.name=Honey
+fluid.poison=Poison
+fluid.honey=Honey
+
+
+item.cylinder.name=Cylinder Hat
+item.chestplateSuit.name=Suit Jacket
+item.leggingsSuit.name=Dress Pants 
+item.bootsSuit.name=Dress Shoes
+
+item.hatStraw.name=Straw Hat
+
+item.coinCopper.name=Copper Coin
+item.coinSilver.name=Silver Coin
+item.coinGold.name=Gold Coin
 
 item.scroll.name=Magic Scroll
-tile.blockGuild.name=Guild Block
+item.realHayBed.name=Hay Mat
+item.bundleHay.name=Hay Bundle
 
 entity.BrownBear.name=Brown Bear
 entity.BlackBear.name=Black Bear

+ 21 - 0
src/main/resources/assets/km/models/block/artefact.json

@@ -0,0 +1,21 @@
+{
+    "parent": "block/cube",
+    "display": {
+        "firstperson_righthand": {
+            "rotation": [ 0, 135, 0 ],
+            "translation": [ 0, 0, 0 ],
+            "scale": [ 0.40, 0.40, 0.40 ]
+        }
+    },
+    "textures": {
+        "particle": "km:blocks/artefact/artefact_top",
+        "down": "km:blocks/artefact/artefact_bottom",
+        "up": "km:blocks/artefact/artefact_top",
+        "north": "km:blocks/artefact/artefact_sides",
+        "east": "km:blocks/artefact/artefact_sides",
+        "south": "km:blocks/artefact/artefact_sides",
+        "west": "km:blocks/artefact/artefact_sides"
+    }
+}
+
+

+ 6 - 0
src/main/resources/assets/km/models/block/silver_block.json

@@ -0,0 +1,6 @@
+{
+    "parent": "block/cube_all",
+    "textures": {
+        "all": "km:blocks/silver_block"
+    }
+}

+ 6 - 0
src/main/resources/assets/km/models/block/silver_ore.json

@@ -0,0 +1,6 @@
+{
+    "parent": "block/cube_all",
+    "textures": {
+        "all": "km:blocks/silver_ore"
+    }
+}

+ 164 - 0
src/main/resources/assets/km/models/block/spikes.json

@@ -0,0 +1,164 @@
+{
+    "parent": "block/block",
+    "textures": {
+        "particle": "#side"
+    },
+    "elements": [
+        {
+            "name": "base",
+            "from": [ 0.0, 0.0, 0.0 ], 
+            "to": [ 16.0, 1.0, 16.0 ], 
+            "faces": {
+                "north": { "texture": "#side", "uv": [ 0.0, 0.0, 16.0, 1.0 ], "rotation": 180 },
+                "east": { "texture": "#side", "uv": [ 15.0, 0.0, 16.0, 16.0 ], "rotation": 270 },
+                "south": { "texture": "#side", "uv": [ 0.0, 15.0, 16.0, 16.0 ] },
+                "west": { "texture": "#side", "uv": [ 0.0, 16.0, 1.0, 0.0 ], "rotation": 90 },
+                "up": { "texture": "#side", "uv": [ 0.0, 0.0, 16.0, 16.0 ] },
+                "down": { "texture": "#side", "uv": [ 0.0, 0.0, 16.0, 16.0 ] }
+            }
+        },
+        {
+            "name": "Spike1",
+            "from": [ 3.0, 1.0, 3.0 ], 
+            "to": [ 4.0, 4.0, 4.0 ], 
+            "faces": {
+                "north": { "texture": "#side", "uv": [ 1.0, 4.0, 2.0, 7.0 ] },
+                "east": { "texture": "#side", "uv": [ 1.0, 4.0, 2.0, 7.0 ] },
+                "south": { "texture": "#side", "uv": [ 1.0, 4.0, 2.0, 7.0 ] },
+                "west": { "texture": "#side", "uv": [ 1.0, 4.0, 2.0, 7.0 ] },
+                "up": { "texture": "#side", "uv": [ 1.0, 4.0, 2.0, 5.0 ] },
+                "down": { "texture": "#side", "uv": [ 1.0, 4.0, 2.0, 5.0 ] }
+            }
+        },
+        {
+            "name": "Spike2",
+            "from": [ 12.0, 1.0, 3.0 ], 
+            "to": [ 13.0, 3.0, 4.0 ], 
+            "faces": {
+                "north": { "texture": "#side", "uv": [ 4.0, 6.0, 5.0, 8.0 ] },
+                "east": { "texture": "#side", "uv": [ 4.0, 6.0, 5.0, 8.0 ] },
+                "south": { "texture": "#side", "uv": [ 4.0, 6.0, 5.0, 8.0 ] },
+                "west": { "texture": "#side", "uv": [ 4.0, 6.0, 5.0, 8.0 ] },
+                "up": { "texture": "#side", "uv": [ 4.0, 6.0, 5.0, 7.0 ] },
+                "down": { "texture": "#side", "uv": [ 4.0, 6.0, 5.0, 7.0 ] }
+            }
+        },
+        {
+            "name": "Spike3",
+            "from": [ 7.0, 1.0, 4.0 ], 
+            "to": [ 8.0, 5.0, 5.0 ], 
+            "faces": {
+                "north": { "texture": "#side", "uv": [ 8.0, 9.0, 9.0, 13.0 ] },
+                "east": { "texture": "#side", "uv": [ 8.0, 9.0, 9.0, 13.0 ] },
+                "south": { "texture": "#side", "uv": [ 8.0, 9.0, 9.0, 13.0 ] },
+                "west": { "texture": "#side", "uv": [ 8.0, 9.0, 9.0, 13.0 ] },
+                "up": { "texture": "#side", "uv": [ 8.0, 9.0, 9.0, 10.0 ] },
+                "down": { "texture": "#side", "uv": [ 8.0, 9.0, 9.0, 10.0 ] }
+            }
+        },
+        {
+            "name": "Spike4",
+            "from": [ 8.0, 1.0, 7.0 ], 
+            "to": [ 9.0, 4.0, 8.0 ], 
+            "faces": {
+                "north": { "texture": "#side", "uv": [ 1.0, 5.0, 2.0, 8.0 ] },
+                "east": { "texture": "#side", "uv": [ 1.0, 5.0, 2.0, 8.0 ] },
+                "south": { "texture": "#side", "uv": [ 1.0, 5.0, 2.0, 8.0 ] },
+                "west": { "texture": "#side", "uv": [ 1.0, 5.0, 2.0, 8.0 ] },
+                "up": { "texture": "#side", "uv": [ 1.0, 5.0, 2.0, 6.0 ] },
+                "down": { "texture": "#side", "uv": [ 1.0, 5.0, 2.0, 6.0 ] }
+            }
+        },
+        {
+            "name": "Spike5",
+            "from": [ 13.0, 1.0, 6.0 ], 
+            "to": [ 14.0, 4.0, 7.0 ], 
+            "faces": {
+                "north": { "texture": "#side", "uv": [ 2.0, 7.0, 3.0, 10.0 ] },
+                "east": { "texture": "#side", "uv": [ 2.0, 7.0, 3.0, 10.0 ] },
+                "south": { "texture": "#side", "uv": [ 2.0, 7.0, 3.0, 10.0 ] },
+                "west": { "texture": "#side", "uv": [ 2.0, 7.0, 3.0, 10.0 ] },
+                "up": { "texture": "#side", "uv": [ 2.0, 7.0, 3.0, 8.0 ] },
+                "down": { "texture": "#side", "uv": [ 2.0, 7.0, 3.0, 8.0 ] }
+            }
+        },
+        {
+            "name": "Spike6",
+            "from": [ 4.0, 1.0, 6.0 ], 
+            "to": [ 5.0, 4.0, 7.0 ], 
+            "faces": {
+                "north": { "texture": "#side", "uv": [ 4.0, 12.0, 5.0, 15.0 ] },
+                "east": { "texture": "#side", "uv": [ 4.0, 12.0, 5.0, 15.0 ] },
+                "south": { "texture": "#side", "uv": [ 4.0, 12.0, 5.0, 15.0 ] },
+                "west": { "texture": "#side", "uv": [ 4.0, 12.0, 5.0, 15.0 ] },
+                "up": { "texture": "#side", "uv": [ 4.0, 12.0, 5.0, 13.0 ] },
+                "down": { "texture": "#side", "uv": [ 4.0, 12.0, 5.0, 13.0 ] }
+            }
+        },
+        {
+            "name": "Spike7",
+            "from": [ 2.0, 1.0, 10.0 ], 
+            "to": [ 3.0, 3.0, 11.0 ], 
+            "faces": {
+                "north": { "texture": "#side", "uv": [ 2.0, 9.0, 3.0, 11.0 ] },
+                "east": { "texture": "#side", "uv": [ 2.0, 9.0, 3.0, 11.0 ] },
+                "south": { "texture": "#side", "uv": [ 2.0, 9.0, 3.0, 11.0 ] },
+                "west": { "texture": "#side", "uv": [ 2.0, 9.0, 3.0, 11.0 ] },
+                "up": { "texture": "#side", "uv": [ 2.0, 9.0, 3.0, 10.0 ] },
+                "down": { "texture": "#side", "uv": [ 2.0, 9.0, 3.0, 10.0 ] }
+            }
+        },
+        {
+            "name": "Spike8",
+            "from": [ 7.0, 1.0, 11.0 ], 
+            "to": [ 8.0, 5.0, 12.0 ], 
+            "faces": {
+                "north": { "texture": "#side", "uv": [ 4.0, 4.0, 5.0, 8.0 ] },
+                "east": { "texture": "#side", "uv": [ 4.0, 4.0, 5.0, 8.0 ] },
+                "south": { "texture": "#side", "uv": [ 4.0, 4.0, 5.0, 8.0 ] },
+                "west": { "texture": "#side", "uv": [ 4.0, 4.0, 5.0, 8.0 ] },
+                "up": { "texture": "#side", "uv": [ 4.0, 4.0, 5.0, 5.0 ] },
+                "down": { "texture": "#side", "uv": [ 4.0, 4.0, 5.0, 5.0 ] }
+            }
+        },
+        {
+            "name": "Spike9",
+            "from": [ 11.0, 1.0, 9.0 ], 
+            "to": [ 12.0, 5.0, 10.0 ], 
+            "faces": {
+                "north": { "texture": "#side", "uv": [ 1.0, 6.0, 2.0, 10.0 ] },
+                "east": { "texture": "#side", "uv": [ 1.0, 6.0, 2.0, 10.0 ] },
+                "south": { "texture": "#side", "uv": [ 1.0, 6.0, 2.0, 10.0 ] },
+                "west": { "texture": "#side", "uv": [ 1.0, 6.0, 2.0, 10.0 ] },
+                "up": { "texture": "#side", "uv": [ 1.0, 6.0, 2.0, 7.0 ] },
+                "down": { "texture": "#side", "uv": [ 1.0, 6.0, 2.0, 7.0 ] }
+            }
+        },
+        {
+            "name": "Spike10",
+            "from": [ 12.0, 1.0, 13.0 ], 
+            "to": [ 13.0, 3.0, 14.0 ], 
+            "faces": {
+                "north": { "texture": "#side", "uv": [ 3.0, 8.0, 4.0, 10.0 ] },
+                "east": { "texture": "#side", "uv": [ 3.0, 8.0, 4.0, 10.0 ] },
+                "south": { "texture": "#side", "uv": [ 3.0, 8.0, 4.0, 10.0 ] },
+                "west": { "texture": "#side", "uv": [ 3.0, 8.0, 4.0, 10.0 ] },
+                "up": { "texture": "#side", "uv": [ 3.0, 8.0, 4.0, 9.0 ] },
+                "down": { "texture": "#side", "uv": [ 3.0, 8.0, 4.0, 9.0 ] }
+            }
+        },
+        {
+            "name": "Spike11",
+            "from": [ 4.0, 1.0, 13.0 ], 
+            "to": [ 5.0, 4.0, 14.0 ], 
+            "faces": {
+                "north": { "texture": "#side", "uv": [ 12.0, 11.0, 13.0, 14.0 ] },
+                "east": { "texture": "#side", "uv": [ 12.0, 11.0, 13.0, 14.0 ] },
+                "south": { "texture": "#side", "uv": [ 12.0, 11.0, 13.0, 14.0 ] },
+                "west": { "texture": "#side", "uv": [ 12.0, 11.0, 13.0, 14.0 ] },
+                "up": { "texture": "#side", "uv": [ 12.0, 11.0, 13.0, 12.0 ] },
+                "down": { "texture": "#side", "uv": [ 12.0, 11.0, 13.0, 12.0 ] }
+            }
+        }
+    ]
+}

+ 6 - 0
src/main/resources/assets/km/models/item/cylinder.json

@@ -0,0 +1,6 @@
+{
+    "parent": "item/generated",
+    "textures": {
+        "layer0": "km:items/cylinder"
+    }
+}

+ 6 - 0
src/main/resources/assets/km/models/item/hay_bundle.json

@@ -0,0 +1,6 @@
+{
+    "parent": "item/generated",
+    "textures": {
+        "layer0": "km:items/hay_bundle"
+    }
+}

+ 6 - 0
src/main/resources/assets/km/models/item/silver_ingot.json

@@ -0,0 +1,6 @@
+{
+    "parent": "item/generated",
+    "textures": {
+        "layer0": "km:items/silver/silver_ingot"
+    }
+}

+ 6 - 0
src/main/resources/assets/km/models/item/silver_nugget.json

@@ -0,0 +1,6 @@
+{
+    "parent": "item/generated",
+    "textures": {
+        "layer0": "km:items/silver/silver_nugget"
+    }
+}

+ 6 - 0
src/main/resources/assets/km/models/item/straw_hat.json

@@ -0,0 +1,6 @@
+{
+    "parent": "item/generated",
+    "textures": {
+        "layer0": "km:items/straw_hat"
+    }
+}

+ 6 - 0
src/main/resources/assets/km/models/item/suit_boots.json

@@ -0,0 +1,6 @@
+{
+    "parent": "item/generated",
+    "textures": {
+        "layer0": "km:items/suit_boots"
+    }
+}

+ 6 - 0
src/main/resources/assets/km/models/item/suit_chestplate.json

@@ -0,0 +1,6 @@
+{
+    "parent": "item/generated",
+    "textures": {
+        "layer0": "km:items/suit_chestplate"
+    }
+}

+ 6 - 0
src/main/resources/assets/km/models/item/suit_leggings.json

@@ -0,0 +1,6 @@
+{
+    "parent": "item/generated",
+    "textures": {
+        "layer0": "km:items/suit_leggings"
+    }
+}

BIN
src/main/resources/assets/km/textures/blocks/artefact/artefact_bottom.png


BIN
src/main/resources/assets/km/textures/blocks/artefact/artefact_sides.png


BIN
src/main/resources/assets/km/textures/blocks/artefact/artefact_top.png


BIN
src/main/resources/assets/km/textures/blocks/silver_block.png


BIN
src/main/resources/assets/km/textures/blocks/silver_ore.png


BIN
src/main/resources/assets/km/textures/items/cylinder.png


BIN
src/main/resources/assets/km/textures/items/hay_bundle.png


BIN
src/main/resources/assets/km/textures/items/real_hay_bed.png


BIN
src/main/resources/assets/km/textures/items/silver/silver_ingot.png


BIN
src/main/resources/assets/km/textures/items/silver/silver_nugget.png


BIN
src/main/resources/assets/km/textures/items/straw_hat.png


BIN
src/main/resources/assets/km/textures/items/suit_boots.png


BIN
src/main/resources/assets/km/textures/items/suit_chestplate.png


BIN
src/main/resources/assets/km/textures/items/suit_leggings.png


BIN
src/main/resources/assets/km/textures/models/armor/cylinder_layer_1.png


BIN
src/main/resources/assets/km/textures/models/armor/cylinder_layer_2.png


BIN
src/main/resources/assets/km/textures/models/armor/straw_layer_1.png


BIN
src/main/resources/assets/km/textures/models/armor/straw_layer_2.png


BIN
src/main/resources/assets/km/textures/models/armor/suit_layer_1.png


BIN
src/main/resources/assets/km/textures/models/armor/suit_layer_2.png