Browse Source

farmland protection, capabilities(keys, defense, guns), guns, new effects, bugfixes, removed glinting of potions

Kajetan Johannes Hammerle 7 years ago
parent
commit
e20f9b4195
72 changed files with 1379 additions and 151 deletions
  1. 1 1
      build.gradle
  2. 35 1
      src/main/java/me/km/ClientEvents.java
  3. 0 10
      src/main/java/me/km/KajetansMod.java
  4. 9 1
      src/main/java/me/km/ObjectRegistry.java
  5. 1 1
      src/main/java/me/km/api/SimpleConfig.java
  6. 18 9
      src/main/java/me/km/api/Utils.java
  7. 24 0
      src/main/java/me/km/blocks/BlockNoTrampleFarmland.java
  8. 9 24
      src/main/java/me/km/blocks/ModBlocks.java
  9. 47 1
      src/main/java/me/km/capabilities/CapabilitiesEvents.java
  10. 39 0
      src/main/java/me/km/capabilities/ChestKeyProvider.java
  11. 27 0
      src/main/java/me/km/capabilities/ChestKeyStorage.java
  12. 0 1
      src/main/java/me/km/capabilities/DamageUtils.java
  13. 2 2
      src/main/java/me/km/capabilities/DefenseStorage.java
  14. 39 0
      src/main/java/me/km/capabilities/GunLoadProvider.java
  15. 23 0
      src/main/java/me/km/capabilities/GunLoadStorage.java
  16. 10 0
      src/main/java/me/km/capabilities/IChestKey.java
  17. 7 0
      src/main/java/me/km/capabilities/IGunLoad.java
  18. 37 0
      src/main/java/me/km/capabilities/ItemChestKey.java
  19. 23 0
      src/main/java/me/km/capabilities/ItemGunLoad.java
  20. 17 1
      src/main/java/me/km/chatmanager/ChatListener.java
  21. 22 1
      src/main/java/me/km/chatmanager/ChatManager.java
  22. 3 2
      src/main/java/me/km/chatmanager/CommandNickName.java
  23. 98 0
      src/main/java/me/km/commands/CommandGameRule.java
  24. 1 1
      src/main/java/me/km/commands/CommandSetHome.java
  25. 1 1
      src/main/java/me/km/commands/CommandSetWarp.java
  26. 28 22
      src/main/java/me/km/commands/CommandTest.java
  27. 109 0
      src/main/java/me/km/commands/CommandWeather.java
  28. 2 1
      src/main/java/me/km/effects/Effect.java
  29. 67 0
      src/main/java/me/km/effects/EffectAirBlockChanger.java
  30. 2 2
      src/main/java/me/km/effects/EffectBlockChanger.java
  31. 59 0
      src/main/java/me/km/effects/active/BlockExplosion.java
  32. 40 32
      src/main/java/me/km/effects/passive/EntityDamageEffects.java
  33. 0 1
      src/main/java/me/km/effects/passive/TrapEffects.java
  34. 184 0
      src/main/java/me/km/items/ItemGun.java
  35. 20 0
      src/main/java/me/km/items/ItemKey.java
  36. 83 1
      src/main/java/me/km/items/ModItems.java
  37. 16 0
      src/main/java/me/km/items/noglint/ItemNoGlintLingeringPotion.java
  38. 16 0
      src/main/java/me/km/items/noglint/ItemNoGlintPotion.java
  39. 16 0
      src/main/java/me/km/items/noglint/ItemNoGlintSplashPotion.java
  40. 1 1
      src/main/java/me/km/permissions/Permissions.java
  41. 1 2
      src/main/java/me/km/plots/ProtectionBlockAction.java
  42. 28 0
      src/main/java/me/km/recipes/ModRecipes.java
  43. 16 31
      src/main/java/me/km/snuviscript/MinecraftFunctions.java
  44. 1 1
      src/main/java/me/km/snuviscript/ScriptModule.java
  45. 38 0
      src/main/java/me/km/sounds/Sounds.java
  46. 15 0
      src/main/resources/assets/km/lang/en_US.lang
  47. 6 0
      src/main/resources/assets/km/models/item/bronze_key.json
  48. 6 0
      src/main/resources/assets/km/models/item/copper_key.json
  49. 6 0
      src/main/resources/assets/km/models/item/gold_key.json
  50. 25 0
      src/main/resources/assets/km/models/item/handheld_musket.json
  51. 25 0
      src/main/resources/assets/km/models/item/handheld_revolver.json
  52. 6 0
      src/main/resources/assets/km/models/item/iron_key.json
  53. 6 0
      src/main/resources/assets/km/models/item/iron_musket.json
  54. 6 0
      src/main/resources/assets/km/models/item/iron_revolver.json
  55. 7 0
      src/main/resources/assets/km/models/item/musket_ammunition.json
  56. 6 0
      src/main/resources/assets/km/models/item/revolver_bullet.json
  57. 7 0
      src/main/resources/assets/km/models/item/silver_key.json
  58. 6 0
      src/main/resources/assets/km/models/item/silver_musket.json
  59. 6 0
      src/main/resources/assets/km/models/item/silver_revolver.json
  60. 26 0
      src/main/resources/assets/km/sounds.json
  61. BIN
      src/main/resources/assets/km/sounds/item/musket_crit.ogg
  62. BIN
      src/main/resources/assets/km/sounds/item/musket_reload.ogg
  63. BIN
      src/main/resources/assets/km/sounds/item/musket_shot.ogg
  64. BIN
      src/main/resources/assets/km/sounds/item/revolver_crit.ogg
  65. BIN
      src/main/resources/assets/km/sounds/item/revolver_reload.ogg
  66. BIN
      src/main/resources/assets/km/sounds/item/revolver_shot.ogg
  67. BIN
      src/main/resources/assets/km/textures/items/guns/iron_musket.png
  68. BIN
      src/main/resources/assets/km/textures/items/guns/iron_revolver.png
  69. BIN
      src/main/resources/assets/km/textures/items/guns/musket_ammo.png
  70. BIN
      src/main/resources/assets/km/textures/items/guns/revolver_ammo.png
  71. BIN
      src/main/resources/assets/km/textures/items/guns/silver_musket.png
  72. BIN
      src/main/resources/assets/km/textures/items/guns/silver_revolver.png

+ 1 - 1
build.gradle

@@ -22,7 +22,7 @@ compileJava {
 }
 
 minecraft {
-    version = "1.12.1-14.22.0.2467"
+    version = "1.12.1-14.22.0.2475"
     runDir = "run"
     
     // the mappings can be changed at any time, and must be in the following format.

+ 35 - 1
src/main/java/me/km/ClientEvents.java

@@ -9,7 +9,7 @@ import net.minecraftforge.fml.relauncher.Side;
 import net.minecraftforge.fml.relauncher.SideOnly;
 
 public class ClientEvents 
-{
+{   
     @SideOnly(Side.CLIENT)
     @SubscribeEvent
     public void preventChatMessage(ClientChatReceivedEvent e) 
@@ -26,4 +26,38 @@ public class ClientEvents
             }   
         }
     }
+    
+    /*public final static HashSet<Location> LOCS = new HashSet();
+    
+    public void addLocation(Location l)
+    {
+        l = l.copy();
+        l.round();
+        LOCS.add(l);
+    }
+    
+    public boolean removeLocation(Location l)
+    {
+        return LOCS.remove(l);
+    }
+    
+    private static boolean b = true;
+    
+    @SubscribeEvent
+    public void onPlayerMove(PlayerMoveEvent e)
+    {      
+        EntityPlayer p = e.getEntityPlayer();
+        Location l = new Location(p);
+        l.round();
+        if(b)
+        {
+            b = false;
+            World w = p.world;
+            LOCS.add(new Location(w, -117, 86, 169, 0, 0));
+        }
+        if(LOCS.contains(l))
+        {
+            System.out.println(l);
+        }
+    }*/
 }

+ 0 - 10
src/main/java/me/km/KajetansMod.java

@@ -12,7 +12,6 @@ import me.km.databank.DataBank;
 import me.km.dimensions.ModWorldGeneration;
 import me.km.dimensions.WorldData;
 import me.km.effects.EffectUtils;
-import me.km.effects.passive.EntityDamageEffects;
 import me.km.events.CustomEventCaller;
 import me.km.fluids.ModFluids;
 import me.km.jobsystem.JobAPI;
@@ -136,15 +135,6 @@ public class KajetansMod
             generalCommands = new Module("GeneralCommands", "Commands", TextFormatting.GOLD);
             generalCommands.registerCommands(e, "me.km.commands");
             
-            worldManager = new WorldData("WorldManager", "Worlds", TextFormatting.RED);
-            worldManager.registerCommands(e, "me.km.dimensions");          
-            worldManager.registerEvents("me.km.dimensions");
-            
-            effects = new EffectUtils("Effects", "Effects", TextFormatting.BLUE);
-            effects.registerCommands(e, "me.km.effects"); 
-            //effects.registerEvents("me.km.effects.passive"); 
-            MinecraftForge.EVENT_BUS.register(new EntityDamageEffects(effects));
-            
             debugMode = true;*/
             return;
         }

+ 9 - 1
src/main/java/me/km/ObjectRegistry.java

@@ -3,13 +3,16 @@ package me.km;
 import me.km.blocks.ModBlocks;
 import me.km.items.ModItems;
 import me.km.recipes.ModRecipes;
+import me.km.sounds.Sounds;
 import net.minecraft.block.Block;
 import net.minecraft.init.Blocks;
 import net.minecraft.item.Item;
 import net.minecraft.item.crafting.IRecipe;
+import net.minecraft.util.SoundEvent;
 import net.minecraftforge.event.RegistryEvent;
 import net.minecraftforge.fml.common.Mod;
 import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.registries.IForgeRegistry;
 
 @Mod.EventBusSubscriber
 public class ObjectRegistry 
@@ -18,7 +21,6 @@ public class ObjectRegistry
     public static void onBlockRegistry(RegistryEvent.Register<Block> e) 
     {
         ModBlocks.initBlocks(e.getRegistry());
-        ModBlocks.initReplacementBlocks(e.getRegistry());
     }
     
     @SubscribeEvent
@@ -44,4 +46,10 @@ public class ObjectRegistry
     {
         ModRecipes.init(e.getRegistry());
     }
+    
+    @SubscribeEvent
+    public static void onSoundRegistry(RegistryEvent.Register<SoundEvent> e) 
+    {
+        Sounds.init(e.getRegistry());
+    }
 }

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

@@ -22,7 +22,7 @@ public class SimpleConfig extends SnuviConfig
             }
 
             @Override
-            public void printException(Exception ex) 
+            public void printException(Exception ex, String s, int line) 
             {
                  // should not happen
             }

+ 18 - 9
src/main/java/me/km/api/Utils.java

@@ -411,11 +411,6 @@ public class Utils
     // Entities
     // -------------------------------------------------------------------------
     
-    public static Location getEntityLocation(Entity ent)
-    {
-        return new Location(ent.getEntityWorld(), ent.getPositionVector(), ent.rotationYaw, ent.rotationPitch);
-    }
-    
     public static Vec3d getEyeLocation(Entity ent) 
     {
         return ent.getPositionVector().addVector(0, ent.getEyeHeight(), 0);
@@ -602,12 +597,20 @@ public class Utils
     }
     
     @SuppressWarnings("unchecked")
-    public static <T extends Entity> T getTargetedEntity(EntityPlayer p, double radius, Class<T> type)
+    public static <T extends Entity> T getTargetedEntity(EntityPlayer p, 
+            double radius, double mX, double mY, double mZ, Class<T> type)
     {
         World w = p.getEntityWorld();
         BlockPos l = getPlayerTarget(p, radius);
         Vec3d eye = getEyeLocation(p);
-        Vec3d unit = new Vec3d(l.getX() - eye.x, l.getY() - eye.y, l.getZ() - eye.z);
+        if(mX != 0 || mY != 0 || mZ != 0)
+        {
+            Random r = p.getRNG();
+            mX *= r.nextDouble();
+            mY *= r.nextDouble();
+            mZ *= r.nextDouble();
+        }
+        Vec3d unit = new Vec3d(l.getX() - eye.x + mX, l.getY() - eye.y + mY, l.getZ() - eye.z + mZ);
         
         List<Entity> col = getEntitiesExcluding(p, w, new BlockPos(eye), l);
         col.removeIf(ent -> !type.isAssignableFrom(ent.getClass()));
@@ -620,6 +623,12 @@ public class Utils
         }).findFirst().orElse(null);
     }
     
+    @SuppressWarnings("unchecked")
+    public static <T extends Entity> T getTargetedEntity(EntityPlayer p, double radius, Class<T> type)
+    {
+        return getTargetedEntity(p, radius, 0, 0, 0, type);
+    }
+    
     // -------------------------------------------------------------------------
     // Player-Tools
     // -------------------------------------------------------------------------
@@ -631,9 +640,9 @@ public class Utils
     
     public static BlockPos getPlayerTarget(EntityPlayer p, double range, boolean boundingBox)
     {
-        if(range > 64)
+        if(range > 128)
         {
-            range = 64;
+            range = 128;
         }
         World w = p.getEntityWorld();
         Vec3d start = getEyeLocation(p);

+ 24 - 0
src/main/java/me/km/blocks/BlockNoTrampleFarmland.java

@@ -0,0 +1,24 @@
+package me.km.blocks;
+
+import net.minecraft.block.BlockFarmland;
+import net.minecraft.block.SoundType;
+import net.minecraft.entity.Entity;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+
+public class BlockNoTrampleFarmland extends BlockFarmland
+{
+    public BlockNoTrampleFarmland()
+    {
+        super.setHardness(0.6F);
+        super.setSoundType(SoundType.GROUND);
+        super.setUnlocalizedName("farmland");
+        super.setLightOpacity(0);
+    }
+    
+    @Override
+    public void onFallenUpon(World worldIn, BlockPos pos, Entity entityIn, float fallDistance) 
+    {
+        entityIn.fall(fallDistance, 1.0F);
+    }
+}

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

@@ -69,6 +69,15 @@ public class ModBlocks
         // fluids
         poison = register(r, new BlockFluidPoison(ModFluids.poison, Material.WATER));
         honey = register(r, new BlockFluidHoney(ModFluids.honey, Material.WATER));
+        
+        // overwrites
+        register(r, Blocks.FARMLAND, new BlockNoTrampleFarmland());
+    }
+    
+    private static void register(IForgeRegistry<Block> r, Block old, Block newBlock)
+    {
+        newBlock.setRegistryName(old.getRegistryName());
+        r.register(newBlock);
     }
     
     public static void initItemBlocks(IForgeRegistry<Item> r) 
@@ -98,30 +107,6 @@ public class ModBlocks
         register(r, poison, getItemBlock(poison));
         register(r, honey, getItemBlock(honey));
     }
-    
-    // THIS IS ONLY FOR REPLACING VANILLA BLOCKS
-    public static void initReplacementBlocks(IForgeRegistry<Block> r) 
-    {
-        //overwriteBlockWorkaround(r, Blocks.TALLGRASS, new BlockTallGrass());
-        //overwriteBlock(r, Blocks.TALLGRASS, new BlockTallGrass());
-    }
-    
-    @SuppressWarnings("")
-    private static void overwriteBlock(IForgeRegistry<Block> r, Block old, Block block)
-    {
-        block.setRegistryName(old.getRegistryName());
-        block.setUnlocalizedName(old.getUnlocalizedName().substring(5));
-        r.register(block);
-    }
-    
-    @SuppressWarnings("")
-    private static void overwriteBlockWorkaround(IForgeRegistry<Block> r, Block old, Block block)
-    {
-        block.setRegistryName(old.getRegistryName().getResourcePath());
-        block.setUnlocalizedName(old.getUnlocalizedName().substring(5));
-        r.register(block);
-    }
-    //END OF REPLACING VANILLA BLOCKS
 
     private static void register(IForgeRegistry<Item> r, Block block, ItemBlock itemBlock) 
     {

+ 47 - 1
src/main/java/me/km/capabilities/CapabilitiesEvents.java

@@ -2,6 +2,9 @@ package me.km.capabilities;
 
 import java.util.List;
 import me.km.KajetansMod;
+import me.km.items.ItemGun;
+import me.km.items.ItemKey;
+import net.minecraft.item.Item;
 import net.minecraft.item.ItemArmor;
 import net.minecraft.item.ItemStack;
 import net.minecraft.util.ResourceLocation;
@@ -16,19 +19,32 @@ import net.minecraftforge.fml.relauncher.SideOnly;
 public class CapabilitiesEvents 
 {
     public static final ResourceLocation DEFENSE_CAP = new ResourceLocation(KajetansMod.MODID, "defense");
+    public static final ResourceLocation CHEST_KEY_CAP = new ResourceLocation(KajetansMod.MODID, "chestkey");
+    public static final ResourceLocation GUN_LOAD_CAP = new ResourceLocation(KajetansMod.MODID, "gunload");
     
     public static void init()
     {
         CapabilityManager.INSTANCE.register(IDefense.class, new DefenseStorage(), ItemDefenseStats.class);
+        CapabilityManager.INSTANCE.register(IChestKey.class, new ChestKeyStorage(), ItemChestKey.class);
+        CapabilityManager.INSTANCE.register(IGunLoad.class, new GunLoadStorage(), ItemGunLoad.class);
     }
     
     @SubscribeEvent
     public void attachDefenseData(AttachCapabilitiesEvent<ItemStack> e) 
     {
-        if(e.getObject().getItem() instanceof ItemArmor)
+        Item item = e.getObject().getItem();
+        if(item instanceof ItemArmor)
         {
             e.addCapability(DEFENSE_CAP, new DefenseProvider());
         }
+        else if(item.getClass() == ItemKey.class)
+        {
+            e.addCapability(CHEST_KEY_CAP, new ChestKeyProvider());
+        }
+        else if(item.getClass() == ItemGun.class)
+        {
+            e.addCapability(GUN_LOAD_CAP, new GunLoadProvider());
+        }
     }
     
     @SideOnly(Side.CLIENT)
@@ -54,5 +70,35 @@ public class CapabilitiesEvents
                 }
             }
         }
+        else if(stack.hasCapability(GunLoadProvider.GUN_LOAD_CAP, null))
+        {
+            IGunLoad gunLoad = stack.getCapability(GunLoadProvider.GUN_LOAD_CAP, null);
+            int load = gunLoad.getCurrentLoad();
+            if(load >= 0)
+            {
+                List<String> list = e.getToolTip();
+                if(load == 1)
+                {
+                    list.add(1, TextFormatting.GOLD + "" + load + " shot loaded");
+                }
+                else
+                {
+                    list.add(1, TextFormatting.GOLD + "" + load + " shots loaded");
+                }
+            }
+        }
+        else if(stack.hasCapability(ChestKeyProvider.CHEST_KEY_CAP, null))
+        {
+            IChestKey key = stack.getCapability(ChestKeyProvider.CHEST_KEY_CAP, null);
+            List<String> list = e.getToolTip();
+            if(key.getKey().isEmpty())
+            {
+                list.set(0, TextFormatting.RED + list.get(0));
+            }
+            else
+            {
+                list.set(0, TextFormatting.GREEN + list.get(0));
+            }
+        }
     }
 }

+ 39 - 0
src/main/java/me/km/capabilities/ChestKeyProvider.java

@@ -0,0 +1,39 @@
+package me.km.capabilities;
+
+import net.minecraft.nbt.NBTBase;
+import net.minecraft.util.EnumFacing;
+import net.minecraftforge.common.capabilities.Capability;
+import net.minecraftforge.common.capabilities.CapabilityInject;
+import net.minecraftforge.common.capabilities.ICapabilitySerializable;
+
+public class ChestKeyProvider implements ICapabilitySerializable<NBTBase>
+{
+    @CapabilityInject(IChestKey.class)
+    public static final Capability<IChestKey> CHEST_KEY_CAP = null;
+
+    private final IChestKey instance = CHEST_KEY_CAP.getDefaultInstance();
+
+    @Override
+    public boolean hasCapability(Capability<?> capability, EnumFacing facing)
+    {
+        return capability == CHEST_KEY_CAP;
+    }
+
+    @Override
+    public <T> T getCapability(Capability<T> capability, EnumFacing facing)
+    {
+        return capability == CHEST_KEY_CAP ? CHEST_KEY_CAP.<T>cast(this.instance) : null;
+    }
+
+    @Override
+    public NBTBase serializeNBT()
+    {
+        return CHEST_KEY_CAP.getStorage().writeNBT(CHEST_KEY_CAP, this.instance, null);
+    }
+
+    @Override
+    public void deserializeNBT(NBTBase nbt)
+    {
+        CHEST_KEY_CAP.getStorage().readNBT(CHEST_KEY_CAP, this.instance, null, nbt);
+    }
+}

+ 27 - 0
src/main/java/me/km/capabilities/ChestKeyStorage.java

@@ -0,0 +1,27 @@
+package me.km.capabilities;
+
+import net.minecraft.nbt.NBTBase;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumFacing;
+import net.minecraftforge.common.capabilities.Capability;
+import net.minecraftforge.common.capabilities.Capability.IStorage;
+
+public class ChestKeyStorage implements IStorage<IChestKey>
+{
+    @Override
+    public NBTBase writeNBT(Capability<IChestKey> cap, IChestKey instance, EnumFacing side) 
+    {
+        NBTTagCompound com = new NBTTagCompound();
+        com.setString("key", instance.getKey());
+        com.setBoolean("iscopy", instance.isCopy());
+        return com;
+    }
+
+    @Override
+    public void readNBT(Capability<IChestKey> cap, IChestKey instance, EnumFacing side, NBTBase nbt) 
+    {
+        NBTTagCompound com = (NBTTagCompound) nbt;
+        instance.setKey(com.getString("key"));
+        instance.setCopy(com.getBoolean("iscopy"));
+    }
+}

+ 0 - 1
src/main/java/me/km/capabilities/DamageUtils.java

@@ -3,7 +3,6 @@ package me.km.capabilities;
 import net.minecraft.entity.EntityLivingBase;
 import net.minecraft.item.ItemStack;
 import net.minecraft.util.DamageSource;
-import net.minecraft.util.EnumFacing;
 
 public class DamageUtils 
 {

+ 2 - 2
src/main/java/me/km/capabilities/DefenseStorage.java

@@ -10,13 +10,13 @@ import net.minecraftforge.common.capabilities.Capability.IStorage;
 public class DefenseStorage implements IStorage<IDefense>
 {
     @Override
-    public NBTBase writeNBT(Capability<IDefense> capability, IDefense instance, EnumFacing side) 
+    public NBTBase writeNBT(Capability<IDefense> cap, IDefense instance, EnumFacing side) 
     {
         return new NBTTagInt(instance.getMagicDefense());
     }
 
     @Override
-    public void readNBT(Capability<IDefense> capability, IDefense instance, EnumFacing side, NBTBase nbt) 
+    public void readNBT(Capability<IDefense> cap, IDefense instance, EnumFacing side, NBTBase nbt) 
     {
         instance.setMagicDefense(((NBTPrimitive) nbt).getInt());
     }

+ 39 - 0
src/main/java/me/km/capabilities/GunLoadProvider.java

@@ -0,0 +1,39 @@
+package me.km.capabilities;
+
+import net.minecraft.nbt.NBTBase;
+import net.minecraft.util.EnumFacing;
+import net.minecraftforge.common.capabilities.Capability;
+import net.minecraftforge.common.capabilities.CapabilityInject;
+import net.minecraftforge.common.capabilities.ICapabilitySerializable;
+
+public class GunLoadProvider implements ICapabilitySerializable<NBTBase>
+{
+    @CapabilityInject(IGunLoad.class)
+    public static final Capability<IGunLoad> GUN_LOAD_CAP = null;
+
+    private final IGunLoad instance = GUN_LOAD_CAP.getDefaultInstance();
+
+    @Override
+    public boolean hasCapability(Capability<?> capability, EnumFacing facing)
+    {
+        return capability == GUN_LOAD_CAP;
+    }
+
+    @Override
+    public <T> T getCapability(Capability<T> capability, EnumFacing facing)
+    {
+        return capability == GUN_LOAD_CAP ? GUN_LOAD_CAP.<T>cast(this.instance) : null;
+    }
+
+    @Override
+    public NBTBase serializeNBT()
+    {
+        return GUN_LOAD_CAP.getStorage().writeNBT(GUN_LOAD_CAP, this.instance, null);
+    }
+
+    @Override
+    public void deserializeNBT(NBTBase nbt)
+    {
+        GUN_LOAD_CAP.getStorage().readNBT(GUN_LOAD_CAP, this.instance, null, nbt);
+    }
+}

+ 23 - 0
src/main/java/me/km/capabilities/GunLoadStorage.java

@@ -0,0 +1,23 @@
+package me.km.capabilities;
+
+import net.minecraft.nbt.NBTBase;
+import net.minecraft.nbt.NBTPrimitive;
+import net.minecraft.nbt.NBTTagInt;
+import net.minecraft.util.EnumFacing;
+import net.minecraftforge.common.capabilities.Capability;
+import net.minecraftforge.common.capabilities.Capability.IStorage;
+
+public class GunLoadStorage implements IStorage<IGunLoad>
+{
+    @Override
+    public NBTBase writeNBT(Capability<IGunLoad> cap, IGunLoad instance, EnumFacing side) 
+    {
+        return new NBTTagInt(instance.getCurrentLoad());
+    }
+
+    @Override
+    public void readNBT(Capability<IGunLoad> cap, IGunLoad instance, EnumFacing side, NBTBase nbt) 
+    {
+        instance.setCurrentLoad(((NBTPrimitive) nbt).getInt());
+    }
+}

+ 10 - 0
src/main/java/me/km/capabilities/IChestKey.java

@@ -0,0 +1,10 @@
+package me.km.capabilities;
+
+public interface IChestKey 
+{
+    public String getKey();
+    public void setKey(String key);
+    
+    public boolean isCopy();
+    public void setCopy(boolean b);
+}

+ 7 - 0
src/main/java/me/km/capabilities/IGunLoad.java

@@ -0,0 +1,7 @@
+package me.km.capabilities;
+
+public interface IGunLoad 
+{
+    public int getCurrentLoad();
+    public void setCurrentLoad(int load);
+}

+ 37 - 0
src/main/java/me/km/capabilities/ItemChestKey.java

@@ -0,0 +1,37 @@
+package me.km.capabilities;
+
+public class ItemChestKey implements IChestKey
+{
+    private String key;
+    private boolean isCopy;
+    
+    public ItemChestKey()
+    {
+        this.key = "";
+        this.isCopy = false;
+    }
+    
+    @Override
+    public String getKey() 
+    {
+        return key;
+    }
+
+    @Override
+    public void setKey(String key) 
+    {
+        this.key = key;
+    }
+
+    @Override
+    public boolean isCopy() 
+    {
+        return isCopy;
+    }
+
+    @Override
+    public void setCopy(boolean b) 
+    {
+        this.isCopy = b;
+    }
+}

+ 23 - 0
src/main/java/me/km/capabilities/ItemGunLoad.java

@@ -0,0 +1,23 @@
+package me.km.capabilities;
+
+public class ItemGunLoad implements IGunLoad
+{
+    private int load;
+
+    public ItemGunLoad()
+    {
+        load = 0;
+    }
+    
+    @Override
+    public int getCurrentLoad() 
+    {
+        return load;
+    }
+
+    @Override
+    public void setCurrentLoad(int load) 
+    {
+        this.load = load;
+    }
+}

+ 17 - 1
src/main/java/me/km/chatmanager/ChatListener.java

@@ -5,18 +5,34 @@ import me.km.api.Module;
 import me.km.api.ModuleListener;
 import net.minecraft.util.text.TextComponentString;
 import net.minecraftforge.event.ServerChatEvent;
+import net.minecraftforge.event.entity.player.PlayerEvent;
 import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
 
 public class ChatListener extends ModuleListener
 {
+    private ChatManager manager;
+    
     public ChatListener(Module m) 
     {
         super(m);
+        manager = (ChatManager) m;
     }
     
     @SubscribeEvent
     public void onChatEvent(ServerChatEvent e)
     {
-        e.setComponent(new TextComponentString(KajetansMod.chatManager.getFullName(e.getPlayer()) + "§1 | §r"  + ChatManager.colorMessage(e.getMessage(), e.getPlayer())));
+        e.setComponent(new TextComponentString(
+                        KajetansMod.chatManager.getFullName(e.getPlayer()) + "§1 | §r"  + 
+                                ChatManager.colorMessage(e.getMessage(), e.getPlayer())));
+    }
+    
+    @SubscribeEvent
+    public void onGetPlayerName(PlayerEvent.NameFormat e)
+    {
+        String s = manager.getNickname(e.getEntityPlayer());
+        if(s != null)
+        {
+            e.setDisplayname(s);
+        }
     }
 }

+ 22 - 1
src/main/java/me/km/chatmanager/ChatManager.java

@@ -16,6 +16,7 @@ public class ChatManager extends Module
 {    
     private final HashMap<Integer, ArrayList<Rank>> ranks;
     private final HashMap<UUID, String> fakeRank;
+    private final HashMap<UUID, String> nickname;
     private final String fallback;
     private final HashMap<UUID, HashSet<String>> playerRanks;
 
@@ -24,7 +25,8 @@ public class ChatManager extends Module
         super(mname, prefix, color);
         ranks = new HashMap<>();
         fakeRank = new HashMap<>(); 
-        fallback = "§8Geist";
+        nickname = new HashMap<>(); 
+        fallback = "§8⮾";
         playerRanks = new HashMap<>();
     }
 
@@ -147,6 +149,25 @@ public class ChatManager extends Module
         fakeRank.remove(p.getUniqueID());
     }
     
+    // -------------------------------------------------------------------------
+    // nicknames
+    // -------------------------------------------------------------------------
+    
+    public void setNickname(EntityPlayer p, String name)
+    {
+        nickname.put(p.getUniqueID(), name);
+    }
+    
+    public String getNickname(EntityPlayer p)
+    {
+        return nickname.get(p.getUniqueID());
+    }
+
+    public void removeNickname(EntityPlayer p)
+    {
+        nickname.remove(p.getUniqueID());
+    }
+    
     // -------------------------------------------------------------------------
     // Text-Coloring-Helper
     // -------------------------------------------------------------------------

+ 3 - 2
src/main/java/me/km/chatmanager/CommandNickName.java

@@ -1,5 +1,6 @@
 package me.km.chatmanager;
 
+import me.km.KajetansMod;
 import me.km.api.GlobalText;
 import me.km.api.Module;
 import me.km.api.ModuleCommand;
@@ -49,7 +50,7 @@ public class CommandNickName extends ModuleCommand
         
         if(arg[0].equals("clear") || arg[0].equals("off"))
         {
-            affectedPlayer.setCustomNameTag(null);
+            KajetansMod.chatManager.removeNickname(affectedPlayer);
             this.getModule().send(affectedPlayer, "Du hast keinen Nicknamen mehr.");
             if(!cs.equals(affectedPlayer))
             {
@@ -57,7 +58,7 @@ public class CommandNickName extends ModuleCommand
             }
             return true;
         }
-        affectedPlayer.setCustomNameTag(arg[0]);
+        KajetansMod.chatManager.setNickname(affectedPlayer, arg[0]);
         this.getModule().send(affectedPlayer, "Du hast nun den Nicknamen '" + arg[0] + "'.");
         if(!cs.equals(affectedPlayer))
         {

+ 98 - 0
src/main/java/me/km/commands/CommandGameRule.java

@@ -0,0 +1,98 @@
+package me.km.commands;
+
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nullable;
+import me.km.api.Module;
+import me.km.api.ModuleCommand;
+import me.km.dimensions.ModDimensions;
+import me.km.permissions.Permissions;
+import net.minecraft.command.ICommandSender;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.GameRules;
+import net.minecraftforge.common.DimensionManager;
+
+public class CommandGameRule extends ModuleCommand
+{
+    public CommandGameRule(Module m) 
+    {
+        super("gamerule", m);
+        super.setDescription("Setzt GameRules einer Welt");
+        super.setUsage("/gamerule <name> [value]");
+        super.setPermission(Permissions.GAMERULE);            
+    }
+    
+    private GameRules getOverWorldGameRules()
+    {
+        return DimensionManager.getWorld(0).getGameRules();
+    }
+    
+    @Override
+    public List<String> getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos)
+    {
+        if(args.length == 1)
+        {
+            return getListOfStringsMatchingLastWord(args, getOverWorldGameRules().getRules());
+        }
+        else
+        {
+            if(args.length == 2)
+            {
+                GameRules gamerules = getOverWorldGameRules();
+                if(gamerules.areSameType(args[0], GameRules.ValueType.BOOLEAN_VALUE))
+                {
+                    return getListOfStringsMatchingLastWord(args, new String[] {"true", "false"});
+                }
+                else if(gamerules.areSameType(args[0], GameRules.ValueType.FUNCTION))
+                {
+                    return getListOfStringsMatchingLastWord(args, server.getFunctionManager().getFunctions().keySet());
+                }
+            }
+            return Collections.<String>emptyList();
+        }
+    }
+
+    @Override
+    public boolean execute(ICommandSender cs, String[] arg) 
+    {
+        GameRules rules;
+        if(cs instanceof EntityPlayer)
+        {
+            rules = ((EntityPlayer) cs).world.getGameRules();
+        }
+        else
+        {
+            rules = getOverWorldGameRules();
+        }
+        
+        String rule = arg.length > 0 ? arg[0] : "";
+        String value = arg.length > 1 ? buildString(arg, 1) : "";
+
+        switch(arg.length)
+        {
+            case 0:
+                this.getModule().send(cs, joinNiceString(rules.getRules()));
+                return true;
+            case 1:
+                if(!rules.hasRule(rule))
+                {
+                    this.getModule().send(cs, "'" + rule + "' ist keine gültige GameRule.");
+                    return true;
+                }
+                this.getModule().send(cs, rule + " = " + rules.getString(rule));
+                return true;
+            default:
+                if(rules.areSameType(rule, GameRules.ValueType.BOOLEAN_VALUE) && 
+                        !"true".equals(value) && !"false".equals(value))
+                {
+                    this.getModule().send(cs, "Es wird 'true' oder 'false' erwartet.");
+                    return true;
+                }
+                rules.setOrCreateGameRule(rule, value);
+                this.getModule().send(cs, "'" + rule + "' wurde auf '" + value + "' gesetzt.");
+        }
+        return true;
+    }
+}

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

@@ -45,7 +45,7 @@ public class CommandSetHome extends ModuleCommand
             return false;
         }
         EntityPlayer p = ((EntityPlayer) cs);
-        if(addHome(arg[0], p.getUniqueID().toString(), Utils.getEntityLocation(p)))
+        if(addHome(arg[0], p.getUniqueID().toString(), new Location(p)))
         {
             this.getModule().send(cs, "Der Home " + arg[0] + " wurde erstellt.");
             return true;

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

@@ -44,7 +44,7 @@ public class CommandSetWarp extends ModuleCommand
         {
             return false;
         }
-        if(addWarp(arg[0], Utils.getEntityLocation((EntityPlayer) cs)))
+        if(addWarp(arg[0], new Location((EntityPlayer) cs)))
         {
             this.getModule().send(cs, "Der Warp " + arg[0] + " wurde erstellt.");
             return true;

+ 28 - 22
src/main/java/me/km/commands/CommandTest.java

@@ -3,15 +3,12 @@ package me.km.commands;
 import me.km.api.GlobalText;
 import me.km.api.Module;
 import me.km.api.ModuleCommand;
-import me.km.capabilities.CapabilitiesEvents;
-import me.km.capabilities.DefenseProvider;
-import me.km.capabilities.IDefense;
+import me.km.capabilities.ChestKeyProvider;
+import me.km.capabilities.IChestKey;
 import me.km.permissions.Permissions;
 import net.minecraft.command.ICommandSender;
-import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
 import net.minecraft.item.ItemStack;
-import net.minecraft.util.EnumFacing;
-import net.minecraft.util.text.TextComponentString;
 
 public class CommandTest extends ModuleCommand
 {
@@ -26,34 +23,43 @@ public class CommandTest extends ModuleCommand
     @Override
     public boolean execute(ICommandSender cs, String[] arg) 
     {
-        if(!(cs instanceof EntityPlayer))
+        if(!(cs instanceof EntityPlayerMP))
         {
             this.getModule().send(cs, GlobalText.onlyPlayer());
             return true;
         }
-        EntityPlayer p = (EntityPlayer) cs; 
+        EntityPlayerMP p = (EntityPlayerMP) cs;
         ItemStack stack = p.getHeldItemMainhand();
-        if(stack.hasCapability(DefenseProvider.DEFENSE_CAP, null))
+        if(arg.length >= 1 && stack.hasCapability(ChestKeyProvider.CHEST_KEY_CAP, null))
         {
-            IDefense wusi = stack.getCapability(DefenseProvider.DEFENSE_CAP, null);
-            if(arg.length >= 1)
+            IChestKey key = stack.getCapability(ChestKeyProvider.CHEST_KEY_CAP, null);
+            if(key == null)
             {
-                try
+                // will never happen
+                return true;
+            }
+            switch(arg[0])
+            {
+                case "key":
                 {
-                    wusi.setMagicDefense(Integer.parseInt(arg[0]));
+                    if(arg.length >= 2)
+                    {
+                        key.setKey(arg[1]);
+                        this.getModule().send(cs, "Schlüssel geändert auf '" + arg[1] + "'");
+                    }
+                    else
+                    {
+                        this.getModule().send(cs, "'" + key.getKey() + "'");
+                    }
+                    break;
                 }
-                catch(NumberFormatException ex)
+                case "copy":
                 {
+                    key.setCopy(!key.isCopy());
+                    this.getModule().send(cs, "Copy-Status ist nun '" + key.isCopy() + "'");
+                    break;
                 }
             }
-            else
-            {
-                cs.sendMessage(new TextComponentString(" " + wusi.getMagicDefense()));
-            }
-        }
-        else
-        {
-            cs.sendMessage(new TextComponentString("Nichts"));
         }
         return true;
     }

+ 109 - 0
src/main/java/me/km/commands/CommandWeather.java

@@ -0,0 +1,109 @@
+package me.km.commands;
+
+import me.km.api.GlobalText;
+import me.km.api.Module;
+import me.km.api.ModuleCommand;
+import me.km.dimensions.ModDimensions;
+import me.km.permissions.Permissions;
+import net.minecraft.command.ICommandSender;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.world.World;
+import net.minecraft.world.storage.WorldInfo;
+
+public class CommandWeather extends ModuleCommand
+{
+    public CommandWeather(Module m) 
+    {
+        super("weather", m);
+        super.setDescription("Setzt das Wetter in einer Welt");
+        super.setUsage("/weather <clear|rain|thunder> [world] [ticks]");
+        super.setPermission(Permissions.WEATHER);
+    }
+
+    @Override
+    public boolean execute(ICommandSender cs, String[] arg) 
+    {
+        if(arg.length == 0)
+        {
+            return false;
+        }
+        World w;
+        if(arg.length >= 2)
+        {
+            w = ModDimensions.getWorldFromName(arg[1]);
+            if(w == null)
+            {
+                this.getModule().send(cs, "Die Welt '" + arg[1] + "' wurde nicht gefunden.");
+                return true;
+            }
+        }
+        else if(cs instanceof EntityPlayer)
+        {
+            w = ((EntityPlayer) cs).getEntityWorld();
+        }
+        else
+        {
+            this.getModule().send(cs, GlobalText.missingParameter());
+            return true;
+        }
+        
+        int time;
+        if(arg.length >= 3)
+        {
+            try
+            {
+                time = Integer.parseInt(arg[2]);
+                if(time < 0)
+                {
+                    this.getModule().send(cs, GlobalText.noNaturalNumber());
+                    return true;
+                }
+            }
+            catch(Exception ex)
+            {
+                this.getModule().send(cs, GlobalText.noNaturalNumber());
+                return true;
+            }
+        }
+        else
+        {
+            time = 24000;
+        }
+        
+        WorldInfo wi = w.getWorldInfo();
+        switch(arg[0].toLowerCase())
+        {
+            case "clear":
+            {
+                wi.setCleanWeatherTime(time);
+                wi.setRainTime(0);
+                wi.setThunderTime(0);
+                wi.setRaining(false);
+                wi.setThundering(false);
+                this.getModule().send(cs, "Das Wetter ist wieder klar.");
+                return true;
+            }
+            case "rain":
+            {
+                wi.setCleanWeatherTime(0);
+                wi.setRainTime(time);
+                wi.setThunderTime(time);
+                wi.setRaining(true);
+                wi.setThundering(false);
+                this.getModule().send(cs, "Es regnet nun für " + time + " Ticks.");
+                return true;
+            }
+            case "thunder":
+            {
+                wi.setCleanWeatherTime(0);
+                wi.setRainTime(time);
+                wi.setThunderTime(time);
+                wi.setRaining(true);
+                wi.setThundering(true);
+                this.getModule().send(cs, "Es gewittert nun für " + time + " Ticks.");
+                return true;
+            }
+        }
+        return false;
+    }
+}

+ 2 - 1
src/main/java/me/km/effects/Effect.java

@@ -138,7 +138,8 @@ public enum Effect
     SILENCE                 (Silence.class),
     POWER_ATTACK            (PowerAttack.class),
     HEAL                    (Heal.class),
-    JUMP_ATTACK             (JumpAttack.class);
+    JUMP_ATTACK             (JumpAttack.class),
+    BLOCK_EXPLOSION         (BlockExplosion.class);
     
     private final ArrayList<Skill> skills;
     private final Class<? extends ActiveEffectBase> c;

+ 67 - 0
src/main/java/me/km/effects/EffectAirBlockChanger.java

@@ -0,0 +1,67 @@
+package me.km.effects;
+
+import me.km.KajetansMod;
+import java.util.ArrayList;
+import java.util.function.Consumer;
+import me.km.api.Location;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+
+public class EffectAirBlockChanger
+{
+    private final World w;
+    private final ArrayList<ChangeBlock> list;
+    
+    public EffectAirBlockChanger(World w)
+    {
+        this.w = w;
+        list = new ArrayList<>();
+    }
+    
+    public void addBlock(BlockPos pos)
+    {
+        if(!w.isAirBlock(pos) && w.getTileEntity(pos) == null)
+        {
+            list.add(new ChangeBlock(pos));
+        }
+    }
+    
+    public void run(int clean)
+    {
+        list.forEach(c -> c.run());
+        KajetansMod.scheduler.scheduleTask(() -> list.forEach(c -> c.clear()), clean);
+    }
+    
+    public World getWorld()
+    {
+        return w;
+    }
+    
+    public void forEachLocation(Consumer<? super Location> c)
+    {
+        list.stream().map(l -> new Location(w, l.pos)).forEach(c);
+    }
+    
+    private class ChangeBlock
+    {
+        private final BlockPos pos;
+        private final IBlockState state;
+
+        public ChangeBlock(BlockPos pos)
+        {
+            this.pos = pos;
+            this.state = w.getBlockState(pos);
+        }
+
+        public void run()
+        {
+            w.setBlockToAir(pos);
+        }
+
+        public void clear()
+        {
+            w.setBlockState(pos, state);
+        }
+    }
+}

+ 2 - 2
src/main/java/me/km/effects/EffectBlockChanger.java

@@ -11,8 +11,8 @@ import net.minecraft.world.World;
 
 public class EffectBlockChanger
 {
-    private World w;
-    private ArrayList<ChangeBlock> list;
+    private final World w;
+    private final ArrayList<ChangeBlock> list;
     
     public EffectBlockChanger(World w)
     {

+ 59 - 0
src/main/java/me/km/effects/active/BlockExplosion.java

@@ -0,0 +1,59 @@
+package me.km.effects.active;
+
+import me.km.KajetansMod;
+import me.km.effects.ActiveEffectBase;
+import me.km.effects.EffectAirBlockChanger;
+import me.km.effects.EffectUtils;
+import net.minecraft.entity.item.EntityItem;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumParticleTypes;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.WorldServer;
+
+public class BlockExplosion extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {
+        WorldServer w = p.getServerWorld();
+        EntityItem item = new EntityItem(w, p.posX, p.posY, p.posZ, new ItemStack(Blocks.TNT));
+        item.setInfinitePickupDelay();
+        w.spawnEntity(item);
+        
+        BlockPos mid = p.getPosition();
+        EffectAirBlockChanger e = new EffectAirBlockChanger(w);
+
+        power = Math.max(0, Math.min(power, 6));
+        int radius2 = power * power;
+        for(int x = -power; x <= power; x++)
+        {
+            for(int y = -power; y <= power; y++)
+            {
+                for(int z = -power; z <= power; z++)
+                {
+                    if(x * x + y * y + z * z <= radius2)
+                    {
+                        e.addBlock(mid.add(x, y, z));
+                    }
+                }
+            }
+        }
+        
+        KajetansMod.scheduler.scheduleTask(() -> 
+        {
+            item.setDead();
+            EffectUtils.spawnParticle(w, EnumParticleTypes.EXPLOSION_LARGE, item.getPositionVector(), 1);
+            e.run(300);
+        }, 60);
+        
+        return true;
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 1;
+    }
+}

+ 40 - 32
src/main/java/me/km/effects/passive/EntityDamageEffects.java

@@ -19,6 +19,7 @@ import net.minecraft.util.CombatRules;
 import net.minecraft.util.DamageSource;
 import net.minecraftforge.event.entity.living.LivingHealEvent;
 import net.minecraftforge.event.entity.living.LivingHurtEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
 import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
 
 public class EntityDamageEffects extends ModuleListener
@@ -71,50 +72,57 @@ public class EntityDamageEffects extends ModuleListener
         }
     }
     
-    @SubscribeEvent(receiveCanceled = false)
+    @SubscribeEvent(priority = EventPriority.LOWEST)
     public void onEntityDamage(LivingHurtEvent e)
     {         
         // ---------------------------------------------------------------------
         // injection of new damage system
         // ---------------------------------------------------------------------
         
-        e.setCanceled(true);
-        KajetansMod.scheduler.scheduleTask(() -> 
-        {
-            float damageAmount = e.getAmount();
-            DamageSource ds = e.getSource();
-            EntityLivingBase liv = e.getEntityLiving();
-            
-            if(ds != DamageSource.LAVA && ds != DamageSource.IN_WALL && ds != DamageSource.CRAMMING && ds != DamageSource.DROWN)
+        if(!e.isCanceled())
+        {
+            e.setCanceled(true);
+            KajetansMod.scheduler.scheduleTask(() -> 
             {
-                if(ds.isMagicDamage() && !ds.isDamageAbsolute())
+                float damageAmount = e.getAmount();
+                DamageSource ds = e.getSource();
+                EntityLivingBase liv = e.getEntityLiving();
+
+                if(ds != DamageSource.LAVA && ds != DamageSource.IN_WALL && ds != DamageSource.CRAMMING && ds != DamageSource.DROWN)
                 {
-                    ReflectionUtils.damageArmor(liv, damageAmount);
-                    damageAmount = CombatRules.getDamageAfterAbsorb(damageAmount, DamageUtils.getMagicDefense(liv), 0);
+                    if(ds.isMagicDamage() && !ds.isDamageAbsolute())
+                    {
+                        ReflectionUtils.damageArmor(liv, damageAmount);
+                        damageAmount = CombatRules.getDamageAfterAbsorb(damageAmount, DamageUtils.getMagicDefense(liv), 0);
+                    }
+                    else
+                    {
+                        damageAmount = ReflectionUtils.applyArmorCalculations(liv, ds, damageAmount);
+                    }           
+                    damageAmount = ReflectionUtils.applyPotionDamageCalculations(liv, ds, damageAmount);
                 }
                 else
                 {
-                    damageAmount = ReflectionUtils.applyArmorCalculations(liv, ds, damageAmount);
-                }           
-                damageAmount = ReflectionUtils.applyPotionDamageCalculations(liv, ds, damageAmount);
-            }
-            else
-            {
-                damageAmount = liv.getMaxHealth() / 10;
-            }
-            
-            float f = damageAmount;
-            damageAmount = Math.max(damageAmount - liv.getAbsorptionAmount(), 0.0F);
-            liv.setAbsorptionAmount(liv.getAbsorptionAmount() - (f - damageAmount));
+                    damageAmount = liv.getMaxHealth() / 10;
+                }
 
-            if (damageAmount != 0.0F)
-            {
-                float f1 = liv.getHealth();
-                liv.setHealth(f1 - damageAmount);
-                liv.getCombatTracker().trackDamage(ds, f1, damageAmount);
-                liv.setAbsorptionAmount(liv.getAbsorptionAmount() - damageAmount);
-            }
-        });
+                float f = damageAmount;
+                damageAmount = Math.max(damageAmount - liv.getAbsorptionAmount(), 0.0F);
+                liv.setAbsorptionAmount(liv.getAbsorptionAmount() - (f - damageAmount));
+
+                if (damageAmount != 0.0F)
+                {
+                    float f1 = liv.getHealth();
+                    liv.setHealth(f1 - damageAmount);
+                    liv.getCombatTracker().trackDamage(ds, f1, damageAmount);
+                    liv.setAbsorptionAmount(liv.getAbsorptionAmount() - damageAmount);
+                }
+            });
+        }
+        else
+        {
+            return;
+        }
         
         // ---------------------------------------------------------------------
         // end of new damage system injection

+ 0 - 1
src/main/java/me/km/effects/passive/TrapEffects.java

@@ -9,7 +9,6 @@ import me.km.api.Utils;
 import me.km.effects.EffectBlockChanger;
 import me.km.effects.EffectUtils;
 import me.km.events.PlayerMoveEvent;
-import me.km.snuviscript.ScriptHelper;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.init.Blocks;
 import net.minecraft.init.MobEffects;

+ 184 - 0
src/main/java/me/km/items/ItemGun.java

@@ -0,0 +1,184 @@
+package me.km.items;
+
+import me.km.api.Utils;
+import me.km.capabilities.GunLoadProvider;
+import me.km.capabilities.IGunLoad;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.stats.StatList;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.EnumActionResult;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.SoundCategory;
+import net.minecraft.util.SoundEvent;
+import net.minecraft.world.World;
+
+public class ItemGun extends ItemWeapon
+{
+    private static final double STANDARD_AIM = 0.0625d;
+    private final Item ammo;
+    private final int damage;
+    private final double missAim;
+    private final int cooldown;
+    private final int maxLoad;
+    
+    private SoundEvent soundShot;
+    private SoundEvent soundReload;
+    private SoundEvent soundCrit;
+    
+    public ItemGun(String name, String local, ToolMaterial material, int durability, 
+            float attackDamage, Item ammo, int damage, double missAim, int cooldown, int maxLoad,
+            SoundEvent soundShot, SoundEvent soundReload, SoundEvent soundCrit) 
+    {
+        super(name, local, material, attackDamage);
+        super.setMaxDamage(durability);
+        this.ammo = ammo;
+        this.damage = damage;
+        this.missAim = missAim;
+        this.cooldown = cooldown;
+        this.maxLoad = maxLoad;
+        this.soundShot = soundShot;
+        this.soundReload = soundReload;
+        this.soundCrit = soundCrit;
+    }
+    
+    public ItemGun(String name, String local, ToolMaterial material, int durability, 
+            Item ammo, int damage, double missAim, int cooldown, int maxLoad,
+            SoundEvent soundShot, SoundEvent soundReload, SoundEvent soundCrit) 
+    {
+        this(name, local, material, durability, 0, ammo, damage, missAim, 
+                cooldown, maxLoad, soundShot, soundReload, soundCrit);
+    }
+    
+    public ItemGun(String name, String local, ToolMaterial material, int durability, 
+            Item ammo, int damage, int cooldown, int maxLoad,
+            SoundEvent soundShot, SoundEvent soundReload, SoundEvent soundCrit)
+    {
+        this(name, local, material, durability, ammo, damage, STANDARD_AIM, 
+                cooldown, maxLoad, soundShot, soundReload, soundCrit);
+    }
+    
+    public void fixSounds(SoundEvent soundShot, SoundEvent soundReload, SoundEvent soundCrit)
+    {
+        this.soundShot = soundShot;
+        this.soundReload = soundReload;
+        this.soundCrit = soundCrit;
+    }
+
+    @Override
+    public void onPlayerStoppedUsing(ItemStack stack, World w, EntityLivingBase liv, int timeLeft)
+    {
+        if(liv instanceof EntityPlayer)
+        {
+            EntityPlayer p = (EntityPlayer) liv;
+            IGunLoad gunLoad = stack.getCapability(GunLoadProvider.GUN_LOAD_CAP, null);
+            int load = gunLoad.getCurrentLoad();
+            boolean creative = p.capabilities.isCreativeMode;
+            
+            if(load > 0 || creative)
+            {
+                if (!w.isRemote)
+                {
+                    stack.damageItem(1, p);
+                    double d = missAim;
+                    if(d > STANDARD_AIM)
+                    {
+                        int time = ((this.getMaxItemUseDuration(stack) - timeLeft) / 20) + 1;
+                        d = Math.max(STANDARD_AIM, d / time);
+                    }
+                    EntityLivingBase target = Utils.getTargetedEntity(p, 128, d, d, d, EntityLivingBase.class);
+                    if(target != null)
+                    {
+                        target.attackEntityFrom(DamageSource.causeMobDamage(p), damage);
+                    }
+                }
+
+                playSound(p, w, soundShot);
+                
+                if(!creative)
+                {
+                    gunLoad.setCurrentLoad(load - 1);
+                }
+
+                p.addStat(StatList.getObjectUseStats(this));
+            }
+        }
+    }
+    
+    private void playSound(EntityPlayer p, World w, SoundEvent e)
+    {
+        w.playSound(null, p.posX, p.posY, p.posZ, e, SoundCategory.PLAYERS, 1.0F, 1.0f / (itemRand.nextFloat() * 0.4f + 1.2f));
+    }
+
+    @Override
+    public int getMaxItemUseDuration(ItemStack stack)
+    {
+        return 72000;
+    }
+    
+    private boolean isAmmo(ItemStack stack)
+    {
+        return stack.getItem() == ammo;
+    }
+    
+    private ItemStack findAmmo(EntityPlayer p)
+    {
+        if(this.isAmmo(p.getHeldItem(EnumHand.OFF_HAND)))
+        {
+            return p.getHeldItem(EnumHand.OFF_HAND);
+        }
+        else if(this.isAmmo(p.getHeldItem(EnumHand.MAIN_HAND)))
+        {
+            return p.getHeldItem(EnumHand.MAIN_HAND);
+        }
+        else
+        {
+            ItemStack stack;
+            for(int i = 0; i < p.inventory.getSizeInventory(); i++)
+            {
+                stack = p.inventory.getStackInSlot(i);
+                if(this.isAmmo(stack))
+                {
+                    return stack;
+                }
+            }
+            return ItemStack.EMPTY;
+        }
+    }
+
+    @Override
+    public ActionResult<ItemStack> onItemRightClick(World w, EntityPlayer p, EnumHand hand)
+    {
+        if(p.capabilities.isCreativeMode)
+        {
+            p.getHeldItem(hand).getCapability(GunLoadProvider.GUN_LOAD_CAP, null).setCurrentLoad(maxLoad);
+            playSound(p, w, soundReload);
+            return new ActionResult(EnumActionResult.FAIL, p.getHeldItem(hand));
+        }
+        ItemStack stack = p.getHeldItem(hand);
+        IGunLoad gunLoad = stack.getCapability(GunLoadProvider.GUN_LOAD_CAP, null);
+        int load = gunLoad.getCurrentLoad();
+        if(load <= 0)
+        {
+            ItemStack ammoStack = findAmmo(p);
+            if(!ammoStack.isEmpty())
+            {
+                int newLoad = Math.min(ammoStack.getCount(), maxLoad);
+                gunLoad.setCurrentLoad(newLoad);
+                ammoStack.shrink(newLoad);
+                if(ammoStack.isEmpty())
+                {
+                    p.inventory.deleteStack(ammoStack);
+                }
+                p.getCooldownTracker().setCooldown(this, cooldown * newLoad);
+                playSound(p, w, soundReload);
+            }
+            return new ActionResult(EnumActionResult.FAIL, stack);
+        }
+        p.setActiveHand(hand);
+        return new ActionResult<>(EnumActionResult.SUCCESS, p.getHeldItem(hand));
+    }
+}

+ 20 - 0
src/main/java/me/km/items/ItemKey.java

@@ -0,0 +1,20 @@
+package me.km.items;
+
+import net.minecraft.item.Item;
+
+public class ItemKey extends ItemBase
+{
+    private final Item.ToolMaterial toolMaterial;
+    
+    public ItemKey(String name, String local, Item.ToolMaterial materialIn)
+    {
+        super(name, local);
+        this.toolMaterial = materialIn;
+        this.maxStackSize = 1;
+    }
+    
+    public int getLockPickResistance()
+    {
+        return toolMaterial.getHarvestLevel() + 1;
+    }
+}

+ 83 - 1
src/main/java/me/km/items/ModItems.java

@@ -1,7 +1,11 @@
 package me.km.items;
 
+import me.km.items.noglint.ItemNoGlintPotion;
 import me.km.KajetansMod;
 import me.km.blocks.EnumMetals;
+import me.km.items.noglint.ItemNoGlintLingeringPotion;
+import me.km.items.noglint.ItemNoGlintSplashPotion;
+import me.km.sounds.Sounds;
 import net.minecraft.creativetab.CreativeTabs;
 import net.minecraft.init.Items;
 import net.minecraft.init.SoundEvents;
@@ -34,7 +38,7 @@ public class ModItems
     public static final Item.ToolMaterial TOOL_REDSTONE = 
             EnumHelper.addToolMaterial("REDSTONE", 0,   59, 1,    0, 22);
     public static final Item.ToolMaterial TOOL_SILVER = 
-            EnumHelper.addToolMaterial("SILVER",   0,  250, 5,    2, 20);
+            EnumHelper.addToolMaterial("SILVER",   2,  250, 5,    2, 20);
     public static final Item.ToolMaterial TOOL_EMERALD = 
             EnumHelper.addToolMaterial("EMERALD",  0, 1248, 7, 2.5f, 10);
     public static final Item.ToolMaterial TOOL_LAPIS = 
@@ -149,6 +153,24 @@ public class ModItems
     public static ItemHammer goldHammer;
     public static ItemHammer diamondHammer;
     
+    // guns
+    public static ItemBase revolverBullet;
+    public static ItemBase musketAmmunition;
+    
+    public static ItemGun ironMusket;
+    public static ItemGun silverMusket;
+    public static ItemGun ironRevolver;
+    public static ItemGun silverRevolver;
+    
+    // key
+    //public static ItemKey woodenKey;
+    public static ItemKey silverKey;
+    public static ItemKey copperKey;
+    public static ItemKey bronzeKey;
+    public static ItemKey ironKey;
+    public static ItemKey goldKey;
+    //public static ItemKey diamondKey;
+    
     // coins
     public static ItemBase copperCoin;
     public static ItemBase silverCoin;
@@ -257,6 +279,32 @@ public class ModItems
         goldHammer = register(r, new ItemHammer("gold_hammer", "hammerGold", Item.ToolMaterial.GOLD));
         diamondHammer = register(r, new ItemHammer("diamond_hammer", "hammerDiamond", Item.ToolMaterial.DIAMOND));
         
+        // guns
+        musketAmmunition = register(r, new ItemBase("musket_ammunition", "musketAmmunition").setCreativeTab(CreativeTabs.COMBAT));
+        revolverBullet = register(r, new ItemBase("revolver_bullet", "revolverBullet").setCreativeTab(CreativeTabs.COMBAT));
+    
+        ironMusket = register(r, new ItemGun("iron_musket", "musketIron", 
+                Item.ToolMaterial.IRON, 312, musketAmmunition, 12, 0.2d, 80, 1,
+                Sounds.MUSKET_SHOT, Sounds.MUSKET_RELOAD, Sounds.MUSKET_CRIT));
+        silverMusket = register(r, new ItemGun("silver_musket", "musketSilver", 
+                TOOL_SILVER, 504, musketAmmunition, 12, 0.2d, 80, 1,
+                Sounds.MUSKET_SHOT, Sounds.MUSKET_RELOAD, Sounds.MUSKET_CRIT));
+        ironRevolver = register(r, new ItemGun("iron_revolver", "revolverIron", 
+                Item.ToolMaterial.IRON, 384, revolverBullet, 5, 20, 6,
+                Sounds.REVOLVER_SHOT, Sounds.REVOLVER_RELOAD, Sounds.REVOLVER_CRIT));
+        silverRevolver = register(r, new ItemGun("silver_revolver", "revolverSilver", 
+                TOOL_SILVER, 600, revolverBullet, 5, 20, 6,
+                Sounds.REVOLVER_SHOT, Sounds.REVOLVER_RELOAD, Sounds.REVOLVER_CRIT));
+        
+        // key
+        //woodenKey = register(r, new ItemKey("wood_key", "keyWood", Item.ToolMaterial.WOOD));
+        silverKey = register(r, new ItemKey("silver_key", "keySilver", TOOL_SILVER));
+        copperKey = register(r, new ItemKey("copper_key", "keyCopper", TOOL_COPPER));
+        bronzeKey = register(r, new ItemKey("bronze_key", "keyBronze", TOOL_BRONZE));
+        ironKey = register(r, new ItemKey("iron_key", "keyIron", Item.ToolMaterial.IRON));
+        goldKey = register(r, new ItemKey("gold_key", "keyGold", Item.ToolMaterial.GOLD));
+        //diamondKey = register(r, new ItemKey("diamond_key", "keyDiamond", Item.ToolMaterial.DIAMOND));
+        
         // coins
         copperCoin = register(r, new ItemBase("coin_copper", "coinCopper").setCreativeTab(CreativeTabs.MISC));
         silverCoin = register(r, new ItemBase("coin_silver", "coinSilver").setCreativeTab(CreativeTabs.MISC));
@@ -270,9 +318,37 @@ public class ModItems
         wolfFur = register(r, new ItemBase("wolf_fur", "wolfFur").setCreativeTab(CreativeTabs.MATERIALS));
     
         
+        try
+        {
+            for(int i = 0; i < 10; i++)
+            {
+                System.out.println("DOING EVIL SHIT");
+            }
+            register(r, Items.POTIONITEM, new ItemNoGlintPotion());
+            register(r, Items.SPLASH_POTION, new ItemNoGlintSplashPotion());
+            register(r, Items.LINGERING_POTION, new ItemNoGlintLingeringPotion());
+            for(int i = 0; i < 10; i++)
+            {
+                System.out.println("DONE WITH EVIL SHIT");
+            }
+        }
+        catch(Exception ex)
+        {
+            ex.printStackTrace();
+        }
+        
+        
         // workaround
         EnumMetals.fixMetalIngots();
     }
+    
+    public static void fixSounds()
+    {
+        ironMusket.fixSounds(Sounds.MUSKET_SHOT, Sounds.MUSKET_RELOAD, Sounds.MUSKET_CRIT);
+        silverMusket.fixSounds(Sounds.MUSKET_SHOT, Sounds.MUSKET_RELOAD, Sounds.MUSKET_CRIT);
+        ironRevolver.fixSounds(Sounds.REVOLVER_SHOT, Sounds.REVOLVER_RELOAD, Sounds.REVOLVER_CRIT);
+        silverRevolver.fixSounds(Sounds.REVOLVER_SHOT, Sounds.REVOLVER_RELOAD, Sounds.REVOLVER_CRIT);
+    }
 	
     private static <T extends Item> T register(IForgeRegistry<Item> r, T item) 
     {
@@ -283,4 +359,10 @@ public class ModItems
         }
         return item;
     }
+    
+    private static void register(IForgeRegistry<Item> r, Item old, Item newItem) 
+    {
+        newItem.setRegistryName(old.getRegistryName());
+        r.register(newItem);
+    }
 }

+ 16 - 0
src/main/java/me/km/items/noglint/ItemNoGlintLingeringPotion.java

@@ -0,0 +1,16 @@
+package me.km.items.noglint;
+
+import net.minecraft.item.ItemLingeringPotion;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+public class ItemNoGlintLingeringPotion extends ItemLingeringPotion
+{
+    @SideOnly(Side.CLIENT)
+    @Override
+    public boolean hasEffect(ItemStack stack)
+    {
+        return stack.isItemEnchanted();
+    }
+}

+ 16 - 0
src/main/java/me/km/items/noglint/ItemNoGlintPotion.java

@@ -0,0 +1,16 @@
+package me.km.items.noglint;
+
+import net.minecraft.item.ItemPotion;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+public class ItemNoGlintPotion extends ItemPotion
+{
+    @SideOnly(Side.CLIENT)
+    @Override
+    public boolean hasEffect(ItemStack stack)
+    {
+        return stack.isItemEnchanted();
+    }
+}

+ 16 - 0
src/main/java/me/km/items/noglint/ItemNoGlintSplashPotion.java

@@ -0,0 +1,16 @@
+package me.km.items.noglint;
+
+import net.minecraft.item.ItemSplashPotion;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+public class ItemNoGlintSplashPotion extends ItemSplashPotion
+{
+    @SideOnly(Side.CLIENT)
+    @Override
+    public boolean hasEffect(ItemStack stack)
+    {
+        return stack.isItemEnchanted();
+    }
+}

+ 1 - 1
src/main/java/me/km/permissions/Permissions.java

@@ -9,7 +9,7 @@ public enum Permissions
     PVP_OTHER, LIGHTUPDATE, LAG, COORDS, INVSEE, SET_HOME, KICK, ADD_USER, ENDERCHEST,
     EXP, SAY, BAN, BACK, BED, BED_OTHER, POTION, MSG, ANSWER, ITEMINFO, FEED, MEMORY,
     POSITION, SEEN, TIME, TOP, TP_POS, USER, WARP, BOOK, GROW, ENCHANT, SPEED,
-    TELEPORT_ACCEPT, WORLD,
+    TELEPORT_ACCEPT, WORLD, WEATHER, GAMERULE,
     
     // Chat-Manager
     COLOR, USE_COLOR, NICKNAME, FAKERANK, 

+ 1 - 2
src/main/java/me/km/plots/ProtectionBlockAction.java

@@ -1,7 +1,6 @@
 package me.km.plots;
 
 import me.km.KajetansMod;
-import me.km.api.Location;
 import me.km.api.Module;
 import me.km.permissions.Permissions;
 import net.minecraft.entity.player.EntityPlayer;
@@ -20,7 +19,7 @@ public class ProtectionBlockAction extends Protection
     {
         super(m);
     }
-    
+
     @SubscribeEvent(priority = EventPriority.HIGHEST)
     public void onBlockPlace(BlockEvent.PlaceEvent e)
     {

+ 28 - 0
src/main/java/me/km/recipes/ModRecipes.java

@@ -147,6 +147,20 @@ public class ModRecipes
         registerShaped(r, "", new String[] {" X ", "XXX"}, new ItemStack(ModItems.strawHat), 
                 new char[] {'X'}, new ItemStack[][] {{new ItemStack(Items.WHEAT)}});
         
+        // guns
+        addPlankRecipe(r, new String[] {"XX", "# "}, Items.IRON_INGOT, new ItemStack(ModItems.ironRevolver));
+        addPlankRecipe(r, new String[] {"XX", "# "}, ModItems.silverIngot, new ItemStack(ModItems.silverRevolver));
+        addPlankRecipe(r, new String[] {"  X", " X ", "#  "}, Items.IRON_INGOT, new ItemStack(ModItems.ironMusket));
+        addPlankRecipe(r, new String[] {"  X", " X ", "#  "}, ModItems.silverIngot, new ItemStack(ModItems.silverMusket));
+        registerShapeless(r, "", new ItemStack(ModItems.revolverBullet, 2), new Item[] 
+        {
+            Items.FLINT, Items.IRON_NUGGET
+        });
+        registerShapeless(r, "", new ItemStack(ModItems.musketAmmunition, 1), new Item[] 
+        {
+            Items.GUNPOWDER, Items.IRON_NUGGET
+        });
+        
         // traps
         addMetalRecipes(r, "", new String[] {" X ", "XXX"}, ModBlocks.spikes, 3);
         
@@ -361,4 +375,18 @@ public class ModRecipes
     {
         addMetalRecipes(r, group, patterns, Item.getItemFromBlock(output), amount);
     }
+    
+    private static void addPlankRecipe(IForgeRegistry<IRecipe> r, String[] pattern, Item item, ItemStack result)
+    {       
+        char[] chars = new char[] {'#', 'X'};
+        ItemStack[][] stacks = new ItemStack[][] {{} , {new ItemStack(item)}};
+        NonNullList<ItemStack> list = NonNullList.<ItemStack>create();               
+        Blocks.PLANKS.getSubBlocks(CreativeTabs.BUILDING_BLOCKS, list);
+        stacks[0] = new ItemStack[list.size()];
+        for(int k = 0; k < list.size(); k++)
+        {
+            stacks[0][k] = list.get(k);
+        }
+        registerShaped(r, "", pattern, result, chars, stacks);
+    }
 }

+ 16 - 31
src/main/java/me/km/snuviscript/MinecraftFunctions.java

@@ -73,7 +73,6 @@ import net.minecraft.util.math.Vec3d;
 import net.minecraft.util.text.TextComponentString;
 import net.minecraft.world.World;
 import net.minecraft.world.WorldServer;
-import me.hammerle.exceptions.PreScriptException;
 import me.hammerle.exceptions.IllegalStringException;
 import me.hammerle.code.SnuviParser;
 import me.hammerle.exceptions.HoldCodeException;
@@ -672,24 +671,30 @@ public class MinecraftFunctions implements ISnuviLogger
     }
     
     @Override
-    public void printException(Exception ex)
+    public void printException(Exception ex, String s, int line)
     {
         if(KajetansMod.debugMode || KajetansMod.scripts.getSnuviParser().printStack)
         {
-            printConsoleException(ex, null, -1);
+            Module m = KajetansMod.scripts;
+            m.sendWarningToConsole("Error in '" + s + "'");
+            if(line != -1)
+            {
+                m.sendWarningToConsole("Zeile: " + line);
+            }
+            m.sendWarningToConsole("Fehler: " + ex.getClass().getSimpleName() + " - " + ex.getLocalizedMessage());
         }
-        printGeneralException(ex, -1);
+        sendToDevsWithSuffix("§cError in '" + s + "'");
+        if(line != -1)
+        {
+            sendToDevsWithHelpList("§cZeile:", String.valueOf(line));
+        }
+        sendToDevsWithHelpList("§cFehler:", ex.getClass().getSimpleName() + " - " + ex.getLocalizedMessage());
     }
     
     @Override
     public void printException(Exception ex, Script sc, int line)
     {
-        if(KajetansMod.debugMode || KajetansMod.scripts.getSnuviParser().printStack)
-        {
-            printConsoleException(ex, sc, line);
-        }
-        sendToDevsWithSuffix("§cError in '" + sc.getName()+ "'");
-        printGeneralException(ex, line);
+        printException(ex, sc == null ? "null" : sc.getName(), line);
     }
     
     @Override
@@ -703,27 +708,7 @@ public class MinecraftFunctions implements ISnuviLogger
     {
         sendWarningToAllDevs(s);
     }
-    
-    private void printGeneralException(Exception ex, int line)
-    {
-        if(line != -1)
-        {
-            sendToDevsWithHelpList("§cZeile:", String.valueOf(line));
-        }
-        sendToDevsWithHelpList("§cFehler:", ex.getClass().getSimpleName() + " - " + ex.getLocalizedMessage());
-    }
-    
-    public void printConsoleException(Exception ex, Script sc, int line)
-    {
-        Module m = KajetansMod.scripts;
-        m.sendWarningToConsole("Error in '" + (sc == null ? "null": sc.getName()) + "'");
-        if(line != -1)
-        {
-            m.sendWarningToConsole("Zeilen: " + line);
-        }
-        m.sendWarningToConsole("Fehler: " + ex.getClass().getSimpleName() + " - " + ex.getLocalizedMessage());
-    }
-    
+
     private static void printTable(Object[] args, Script sc)
     {
         Table t = (Table) args[1];

+ 1 - 1
src/main/java/me/km/snuviscript/ScriptModule.java

@@ -192,7 +192,7 @@ public class ScriptModule extends Module
         }
         catch(PreScriptException ex)
         {
-            logger.printException(ex);
+            logger.printException(ex, name, ex.getLine());
         }
     }
 }

+ 38 - 0
src/main/java/me/km/sounds/Sounds.java

@@ -0,0 +1,38 @@
+package me.km.sounds;
+
+import me.km.KajetansMod;
+import me.km.items.ModItems;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.SoundEvent;
+import net.minecraftforge.registries.IForgeRegistry;
+
+public class Sounds 
+{
+    public static SoundEvent MUSKET_CRIT;
+    public static SoundEvent MUSKET_RELOAD;
+    public static SoundEvent MUSKET_SHOT;
+    public static SoundEvent REVOLVER_CRIT;
+    public static SoundEvent REVOLVER_RELOAD;
+    public static SoundEvent REVOLVER_SHOT;
+    
+    public static void init(IForgeRegistry<SoundEvent> r)
+    {
+        MUSKET_CRIT = register(r, "musket_crit");
+        MUSKET_RELOAD = register(r, "musket_reload");
+        MUSKET_SHOT = register(r, "musket_shot");
+        REVOLVER_CRIT = register(r, "revolver_crit");
+        REVOLVER_RELOAD = register(r, "revolver_reload");
+        REVOLVER_SHOT = register(r, "revolver_shot");
+        
+        ModItems.fixSounds();
+    }
+    
+    private static SoundEvent register(IForgeRegistry<SoundEvent> r, String name)
+    {       
+        ResourceLocation loc = new ResourceLocation(KajetansMod.MODID, name);
+        SoundEvent e = new SoundEvent(loc);
+        e.setRegistryName(loc);
+        r.register(e);
+        return e;
+    }
+}

+ 15 - 0
src/main/resources/assets/km/lang/en_US.lang

@@ -94,6 +94,21 @@ item.hammerIron.name=Iron Hammer
 item.hammerGold.name=Gold Hammer
 item.hammerDiamond.name=Diamond Hammer
 
+#item.keyWood.name=Wooden Key
+item.keySilver.name=Silver Key
+item.keyCopper.name=Copper Key
+item.keyBronze.name=Bronze Key
+item.keyIron.name=Iron Key
+item.keyGold.name=Gold Key
+#item.keyDiamond.name=Diamond Key
+
+item.musketAmmunition.name=Musket Ammunition
+item.revolverBullet.name=Revolver Bullet
+item.musketIron.name=Iron Musket
+item.musketSilver.name=Silver Musket
+item.revolverIron.name=Iron Revolver
+item.revolverSilver.name=Silver Revolver
+
 item.cylinder.name=Cylinder Hat
 item.chestplateSuit.name=Suit Jacket
 item.leggingsSuit.name=Dress Pants 

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

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

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

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

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

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

+ 25 - 0
src/main/resources/assets/km/models/item/handheld_musket.json

@@ -0,0 +1,25 @@
+{
+    "parent": "item/generated",
+    "display": {
+        "thirdperson_righthand": {
+            "rotation": [ 0, -90, -40 ],
+            "translation": [ 0, 6.0, 0.5 ],
+            "scale": [ 0.85, 0.85, 0.85 ]
+        },
+        "thirdperson_lefthand": {
+            "rotation": [ 0, 90, 40 ],
+            "translation": [ 0, 6.0, 0.5 ],
+            "scale": [ 0.85, 0.85, 0.85 ]
+        },
+        "firstperson_righthand": {
+            "rotation": [ 0, -90, 25 ],
+            "translation": [ 1.13, 3.2, 1.13 ],
+            "scale": [ 0.68, 0.68, 0.68 ]
+        },
+        "firstperson_lefthand": {
+            "rotation": [ 0, 90, -25 ],
+            "translation": [ 1.13, 3.2, 1.13 ],
+            "scale": [ 0.68, 0.68, 0.68 ]
+        }
+    }
+}

+ 25 - 0
src/main/resources/assets/km/models/item/handheld_revolver.json

@@ -0,0 +1,25 @@
+{
+    "parent": "item/generated",
+    "display": {
+        "thirdperson_righthand": {
+            "rotation": [ 0, -90, -30 ],
+            "translation": [ 0, 3.5, 2 ],
+            "scale": [ 0.85, 0.85, 0.85 ]
+        },
+        "thirdperson_lefthand": {
+            "rotation": [ 0, 90, 30 ],
+            "translation": [ 0, 3.5, 2 ],
+            "scale": [ 0.85, 0.85, 0.85 ]
+        },
+        "firstperson_righthand": {
+            "rotation": [ 0, -90, 25 ],
+            "translation": [ 1.13, 3.2, 1.13 ],
+            "scale": [ 0.68, 0.68, 0.68 ]
+        },
+        "firstperson_lefthand": {
+            "rotation": [ 0, 90, -25 ],
+            "translation": [ 1.13, 3.2, 1.13 ],
+            "scale": [ 0.68, 0.68, 0.68 ]
+        }
+    }
+}

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

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

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

@@ -0,0 +1,6 @@
+{
+    "parent": "km:item/handheld_musket",
+    "textures": {
+        "layer0": "km:items/guns/iron_musket"
+    }
+}

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

@@ -0,0 +1,6 @@
+{
+    "parent": "km:item/handheld_revolver",
+    "textures": {
+        "layer0": "km:items/guns/iron_revolver"
+    }
+}

+ 7 - 0
src/main/resources/assets/km/models/item/musket_ammunition.json

@@ -0,0 +1,7 @@
+{
+    "parent": "item/generated",
+    "textures": {
+        "layer0": "km:items/guns/musket_ammo"
+    }
+}
+

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

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

+ 7 - 0
src/main/resources/assets/km/models/item/silver_key.json

@@ -0,0 +1,7 @@
+{
+    "parent": "item/generated",
+    "textures": {
+        "layer0": "km:items/keys/silver_key"
+    }
+}
+

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

@@ -0,0 +1,6 @@
+{
+    "parent": "km:item/handheld_musket",
+    "textures": {
+        "layer0": "km:items/guns/silver_musket"
+    }
+}

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

@@ -0,0 +1,6 @@
+{
+    "parent": "km:item/handheld_revolver",
+    "textures": {
+        "layer0": "km:items/guns/silver_revolver"
+    }
+}

+ 26 - 0
src/main/resources/assets/km/sounds.json

@@ -0,0 +1,26 @@
+{
+  "musket_crit": {
+    "category": "player",
+    "sounds": [ "km:item/musket_crit" ]
+  },
+  "musket_reload": {
+    "category": "player",
+    "sounds": [ "km:item/musket_reload" ]
+  },
+  "musket_shot": {
+    "category": "player",
+    "sounds": [ "km:item/musket_shot" ]
+  },
+  "revolver_crit": {
+    "category": "player",
+    "sounds": [ "km:item/revolver_crit" ]
+  },
+  "revolver_reload": {
+    "category": "player",
+    "sounds": [ "km:item/revolver_reload" ]
+  },
+  "revolver_shot": {
+    "category": "player",
+    "sounds": [ "km:item/revolver_shot" ]
+  }
+}

BIN
src/main/resources/assets/km/sounds/item/musket_crit.ogg


BIN
src/main/resources/assets/km/sounds/item/musket_reload.ogg


BIN
src/main/resources/assets/km/sounds/item/musket_shot.ogg


BIN
src/main/resources/assets/km/sounds/item/revolver_crit.ogg


BIN
src/main/resources/assets/km/sounds/item/revolver_reload.ogg


BIN
src/main/resources/assets/km/sounds/item/revolver_shot.ogg


BIN
src/main/resources/assets/km/textures/items/guns/iron_musket.png


BIN
src/main/resources/assets/km/textures/items/guns/iron_revolver.png


BIN
src/main/resources/assets/km/textures/items/guns/musket_ammo.png


BIN
src/main/resources/assets/km/textures/items/guns/revolver_ammo.png


BIN
src/main/resources/assets/km/textures/items/guns/silver_musket.png


BIN
src/main/resources/assets/km/textures/items/guns/silver_revolver.png