Browse Source

Bugfixes, lots of new effects

Kajetan Johannes Hammerle 6 years ago
parent
commit
a874387ce8
44 changed files with 770 additions and 297 deletions
  1. 1 1
      build.gradle
  2. 1 1
      src/main/java/me/km/KajetansMod.java
  3. 12 3
      src/main/java/me/km/ObjectRegistry.java
  4. 5 6
      src/main/java/me/km/api/Location.java
  5. 3 5
      src/main/java/me/km/api/SimpleConfig.java
  6. 50 0
      src/main/java/me/km/api/Utils.java
  7. 2 2
      src/main/java/me/km/blocks/ModBlocks.java
  8. 0 1
      src/main/java/me/km/commands/CommandMsg.java
  9. 1 1
      src/main/java/me/km/databank/SimpleDataBank.java
  10. 4 4
      src/main/java/me/km/dimensions/ModWorldGeneration.java
  11. 15 0
      src/main/java/me/km/effects/EffectUtils.java
  12. 54 0
      src/main/java/me/km/effects/active/AreaDamage.java
  13. 25 0
      src/main/java/me/km/effects/active/ArmorPasser.java
  14. 34 0
      src/main/java/me/km/effects/active/BoneBreaker.java
  15. 25 0
      src/main/java/me/km/effects/active/ConstantPower.java
  16. 30 0
      src/main/java/me/km/effects/active/Cripple.java
  17. 3 14
      src/main/java/me/km/effects/active/Doomed.java
  18. 1 0
      src/main/java/me/km/effects/active/ElvishHorn.java
  19. 34 0
      src/main/java/me/km/effects/active/FireProtectionRain.java
  20. 37 0
      src/main/java/me/km/effects/active/HungerPunch.java
  21. 26 0
      src/main/java/me/km/effects/active/ImpactPunch.java
  22. 35 0
      src/main/java/me/km/effects/active/JumpAttack.java
  23. 32 0
      src/main/java/me/km/effects/active/LifeBreaker.java
  24. 37 0
      src/main/java/me/km/effects/active/LifeSteal.java
  25. 30 0
      src/main/java/me/km/effects/active/Smash.java
  26. 1 1
      src/main/java/me/km/effects/active/SmokeBomb.java
  27. 2 0
      src/main/java/me/km/effects/passive/ArrowEffects.java
  28. 47 6
      src/main/java/me/km/effects/passive/EntityDamageEffects.java
  29. 9 45
      src/main/java/me/km/entities/EntityItemProjectile.java
  30. 2 3
      src/main/java/me/km/exception/IllegalStringLocationException.java
  31. 18 14
      src/main/java/me/km/inventory/CustomContainer.java
  32. 5 2
      src/main/java/me/km/inventory/TeleportContainer.java
  33. 1 0
      src/main/java/me/km/jobsystem/Job.java
  34. 3 0
      src/main/java/me/km/jobsystem/JobAPI.java
  35. 3 1
      src/main/java/me/km/nms/NmsUtilities.java
  36. 9 0
      src/main/java/me/km/plots/ProtectionBank.java
  37. 1 1
      src/main/java/me/km/skills/ActiveSkillContainer.java
  38. 2 0
      src/main/java/me/km/skills/SkillContainer.java
  39. 126 140
      src/main/java/me/km/snuviscript/MinecraftFunctions.java
  40. 3 3
      src/main/java/me/km/snuviscript/ScriptBank.java
  41. 29 35
      src/main/java/me/km/snuviscript/ScriptEvents.java
  42. 2 4
      src/main/java/me/km/snuviscript/ScriptInventoryHolder.java
  43. 4 3
      src/main/java/me/km/snuviscript/ScriptVars.java
  44. 6 1
      src/main/java/me/km/utils/ReflectionUtils.java

+ 1 - 1
build.gradle

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

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

@@ -70,7 +70,7 @@ public class KajetansMod
 
     public static final String MODID = "km";
     public static final String NAME = "Kajetans Mod";
-    public static final String VERSION = "0.0.8";
+    public static final String VERSION = "0.0.9";
 
     @Mod.Instance(MODID)
     public static KajetansMod instance;

+ 12 - 3
src/main/java/me/km/ObjectRegistry.java

@@ -4,6 +4,7 @@ import me.km.blocks.ModBlocks;
 import me.km.items.ModItems;
 import me.km.recipes.ModRecipes;
 import net.minecraft.block.Block;
+import net.minecraft.init.Blocks;
 import net.minecraft.item.Item;
 import net.minecraft.item.crafting.IRecipe;
 import net.minecraftforge.event.RegistryEvent;
@@ -16,15 +17,24 @@ public class ObjectRegistry
     @SubscribeEvent
     public static void onBlockRegistry(RegistryEvent.Register<Block> e) 
     {
-        System.out.println(1);
         ModBlocks.initBlocks(e.getRegistry());
         ModBlocks.initReplacementBlocks(e.getRegistry());
     }
     
+    @SubscribeEvent
+    public static void onBlockMissing(RegistryEvent.MissingMappings<Block> e) 
+    {
+        e.getMappings().stream()
+                .filter((missing) -> (missing.key.getResourcePath().equals("tallgrass")))
+                .forEach((missing) -> 
+                {
+                    missing.remap(Blocks.TALLGRASS);   
+                });
+    }
+
     @SubscribeEvent
     public static void onItemRegistry(RegistryEvent.Register<Item> e) 
     {
-        System.out.println(2);
         ModBlocks.initItemBlocks(e.getRegistry());
         ModItems.init(e.getRegistry());
     }
@@ -32,7 +42,6 @@ public class ObjectRegistry
     @SubscribeEvent
     public static void onRecipeRegistry(RegistryEvent.Register<IRecipe> e) 
     {
-        System.out.println(3);
         ModRecipes.init(e.getRegistry());
     }
 }

+ 5 - 6
src/main/java/me/km/api/Location.java

@@ -3,6 +3,7 @@ package me.km.api;
 import java.util.Objects;
 import java.util.regex.PatternSyntaxException;
 import me.hammerle.code.Script;
+import me.hammerle.exceptions.HoldCodeException;
 import me.km.dimensions.ModDimensions;
 import me.km.exception.IllegalStringLocationException;
 import net.minecraft.block.state.IBlockState;
@@ -81,11 +82,13 @@ public class Location
                 this.pitch = 0;
                 return;
             }
-            throw new IllegalStringLocationException(sc, location);
+            sc.getLogger().printException(new IllegalStringLocationException(location), sc, sc.getActiveRealCodeLine());
+            throw new HoldCodeException();
         }
         catch(PatternSyntaxException | NumberFormatException ex)
         {
-            throw new IllegalStringLocationException(sc, location);
+            sc.getLogger().printException(new IllegalStringLocationException(location), sc, sc.getActiveRealCodeLine());
+            throw new HoldCodeException();
         }
     }
 
@@ -97,8 +100,6 @@ public class Location
         hash = 17 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32));
         hash = 17 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32));
         hash = 17 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32));
-        hash = 17 * hash + Float.floatToIntBits(this.yaw);
-        hash = 17 * hash + Float.floatToIntBits(this.pitch);
         return hash;
     }
 
@@ -117,8 +118,6 @@ public class Location
         return Double.doubleToLongBits(this.x) == Double.doubleToLongBits(other.x) &&
                 Double.doubleToLongBits(this.y) == Double.doubleToLongBits(other.y) &&
                 Double.doubleToLongBits(this.z) == Double.doubleToLongBits(other.z) &&
-                Float.floatToIntBits(this.yaw) == Float.floatToIntBits(other.yaw) &&
-                Float.floatToIntBits(this.pitch) == Float.floatToIntBits(other.pitch) &&
                 Objects.equals(this.w, other.w);
     }
 

+ 3 - 5
src/main/java/me/km/api/SimpleConfig.java

@@ -4,12 +4,10 @@ import java.io.File;
 import me.hammerle.code.ISnuviLogger;
 import me.hammerle.code.Script;
 import me.hammerle.config.SnuviConfig;
-import me.hammerle.exceptions.SnuviException;
 import me.km.dimensions.ModDimensions;
 import me.km.exception.IllegalItemStackStringException;
 import me.km.utils.ItemStackUtils;
 import net.minecraft.item.ItemStack;
-import net.minecraft.util.math.Vec3d;
 
 public class SimpleConfig extends SnuviConfig
 {                   
@@ -18,13 +16,13 @@ public class SimpleConfig extends SnuviConfig
         super(new ISnuviLogger() 
         {
             @Override
-            public void printException(SnuviException ex)
+            public void printException(Exception ex, Script sc, int line)
             {
                 // should not happen
             }
 
             @Override
-            public void printException(SnuviException ex, Script s) 
+            public void printException(Exception ex) 
             {
                  // should not happen
             }
@@ -60,7 +58,7 @@ public class SimpleConfig extends SnuviConfig
     public Location getLocation(String key)
     {
         return new Location(ModDimensions.getWorldFromName(getString(key + ".world")), 
-                new Vec3d(getDouble(key + ".x", 0), getDouble(key + ".y", 0), getDouble(key + ".z", 0)),
+                getDouble(key + ".x", 0), getDouble(key + ".y", 0), getDouble(key + ".z", 0),
                 getFloat(key + ".yaw", 0), getFloat(key + ".pitch", 0));
     }
     

+ 50 - 0
src/main/java/me/km/api/Utils.java

@@ -28,6 +28,8 @@ import net.minecraft.block.BlockTrapDoor;
 import net.minecraft.block.properties.IProperty;
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.SharedMonsterAttributes;
 import net.minecraft.entity.player.EntityPlayerMP;
 import net.minecraft.entity.projectile.EntityArrow;
 import net.minecraft.entity.projectile.EntityFireball;
@@ -35,6 +37,7 @@ import net.minecraft.entity.projectile.EntityThrowable;
 import net.minecraft.init.Blocks;
 import net.minecraft.init.Enchantments;
 import net.minecraft.init.Items;
+import net.minecraft.init.MobEffects;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemAxe;
 import net.minecraft.item.ItemHoe;
@@ -49,6 +52,7 @@ import net.minecraft.item.ItemSword;
 import net.minecraft.nbt.NBTTagCompound;
 import net.minecraft.nbt.NBTUtil;
 import net.minecraft.tileentity.TileEntitySkull;
+import net.minecraft.util.CombatRules;
 import net.minecraft.util.DamageSource;
 import net.minecraft.util.math.RayTraceResult;
 import net.minecraft.util.text.ITextComponent;
@@ -447,6 +451,52 @@ public class Utils
         teleportEntity(ent, new Location(ent2.world, ent2.getPositionVector(), ent2.rotationYaw, ent2.rotationPitch));
     }
     
+    public static float getRealDamage(EntityLivingBase ent, DamageSource ds, float d)
+    {
+        if(!ent.isEntityInvulnerable(ds))
+        {
+            if(d <= 0)
+            {
+                return 0;
+            }
+            // Armor from applyArmorCalculations
+            d = getDamagerAfterArmor(ent, ds, d);
+            // Potion / Enchantment from applyPotionDamageCalculations
+            if(!ds.isDamageAbsolute())
+            {
+                if(ent.isPotionActive(MobEffects.RESISTANCE) && ds != DamageSource.OUT_OF_WORLD)
+                {
+                    int i = (ent.getActivePotionEffect(MobEffects.RESISTANCE).getAmplifier() + 1) * 5;
+                    d = (d * (25 - i)) / 25;
+                }
+                if(d <= 0)
+                {
+                    return 0;
+                }
+                else
+                {
+                    int k = EnchantmentHelper.getEnchantmentModifierDamage(ent.getArmorInventoryList(), ds);
+                    if(k > 0)
+                    {
+                        d = CombatRules.getDamageAfterMagicAbsorb(d, k);
+                    }
+                }
+            }
+            d = Math.max(d - ent.getAbsorptionAmount(), 0);
+            return d;
+        }
+        return 0;
+    }
+    
+    public static float getDamagerAfterArmor(EntityLivingBase ent, DamageSource ds, float d)
+    {
+        if(!ds.isUnblockable())
+        {
+            return CombatRules.getDamageAfterAbsorb(d, ent.getTotalArmorValue(), (float) ent.getEntityAttribute(SharedMonsterAttributes.ARMOR_TOUGHNESS).getAttributeValue());
+        }
+        return d;
+    }
+    
     // -------------------------------------------------------------------------
     // Entities aus Umgebung
     // -------------------------------------------------------------------------

+ 2 - 2
src/main/java/me/km/blocks/ModBlocks.java

@@ -102,8 +102,8 @@ public class ModBlocks
     // 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());
+        //overwriteBlockWorkaround(r, Blocks.TALLGRASS, new BlockTallGrass());
+        //overwriteBlock(r, Blocks.TALLGRASS, new BlockTallGrass());
     }
     
     @SuppressWarnings("")

+ 0 - 1
src/main/java/me/km/commands/CommandMsg.java

@@ -4,7 +4,6 @@ import me.km.api.GlobalText;
 import me.km.api.Module;
 import me.km.api.ModuleCommand;
 import java.util.HashMap;
-import me.km.KajetansMod;
 import me.km.api.Utils;
 import me.km.chatmanager.ChatManager;
 import me.km.exception.PlayerNotFoundException;

+ 1 - 1
src/main/java/me/km/databank/SimpleDataBank.java

@@ -276,7 +276,7 @@ public abstract class SimpleDataBank
             ResultSet rs = stmt.executeQuery(query);
             while(rs.next())
             {
-                table.addRow(new Object[] {rs.getString(1), Code.convertInput(rs.getString(2), false)});
+                table.addRow(new Object[] {rs.getString(1), Code.convertInput(null, rs.getString(2), false)});
             }
             return table;
         }

+ 4 - 4
src/main/java/me/km/dimensions/ModWorldGeneration.java

@@ -28,11 +28,11 @@ public class ModWorldGeneration implements IWorldGenerator
             IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) 
     {
         generateOre(ModBlocks.copperOre.getDefaultState(), w, random, 
-                chunkX << 4, chunkZ << 4, 0, 128, 20, 5);
+                chunkX << 4, chunkZ << 4, 0, 128, 9, 25);
         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);
+                chunkX << 4, chunkZ << 4, 0, 96, 8, 12);
+        generateOre(ModBlocks.silverOre.getDefaultState(), w, random, 
+                chunkX << 4, chunkZ << 4, 0, 64, 8, 3);
     } 
     
     private void generateOre(IBlockState ore, World world, Random random, int x, int z, 

+ 15 - 0
src/main/java/me/km/effects/EffectUtils.java

@@ -377,4 +377,19 @@ public class EffectUtils extends Module
         EntityTippedArrow arrow = launchProjectile(p, EntityTippedArrow.class, scale, stack);
         return arrow;
     }
+    
+    public static void jumpTo(EntityLivingBase ent, EntityLivingBase ent2)
+    {
+        Vec3d v1 = ent2.getPositionVector();
+        Vec3d v2 = ent.getPositionVector();
+        
+        Utils.setVelocity(ent, (v1.x - v2.x) * 0.2, (v1.y - v2.y) * 0.2 + 0.9, (v1.z - v2.z) * 0.2);
+
+        KajetansMod.scheduler.scheduleTask(() -> 
+        {
+            Vec3d v3 = ent2.getPositionVector();
+            Vec3d v4 = ent.getPositionVector();
+            Utils.setVelocity(ent, (v3.x - v4.x) * 0.2, (v3.y - v4.y) * 0.2, (v3.z - v4.z) * 0.2);
+        }, 12);
+    }
 }

+ 54 - 0
src/main/java/me/km/effects/active/AreaDamage.java

@@ -0,0 +1,54 @@
+package me.km.effects.active;
+
+import me.km.KajetansMod;
+import me.km.effects.ActiveEffectBase;
+import me.km.effects.EffectUtils;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.EnumParticleTypes;
+import net.minecraft.util.math.Vec3d;
+import net.minecraft.world.WorldServer;
+
+public class AreaDamage extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {       
+        if(!KajetansMod.playerbank.getData(p).hasData("aoe"))
+        {
+            // just adding a bit to time to make sure the last call works
+            KajetansMod.playerbank.getData(p).addGoodTimedData("aoe", true, power * 20 + 3, "AOE Schaden", 61);
+            for(int i = 0; i < power; i++)
+            {
+                KajetansMod.scheduler.scheduleTask(() -> attack(p), i * 20);
+            }
+            return true;
+        }
+        return false;
+    } 
+    
+    private void attack(EntityPlayerMP p)
+    {
+        if(KajetansMod.playerbank.getData(p).hasData("aoe"))
+        {
+            WorldServer w = p.getServerWorld();
+            Vec3d v = p.getPositionVector();
+            EffectUtils.playEffectCircleWithData(w, v, EnumParticleTypes.FLAME, 5, 12);
+            EffectUtils.playEffectCircleWithData(w, v, EnumParticleTypes.FLAME, 4, 12);
+            EffectUtils.playEffectCircleWithData(w, v, EnumParticleTypes.FLAME, 3, 12);
+            EffectUtils.playEffectCircleWithData(w, v, EnumParticleTypes.FLAME, 2, 12);
+            EffectUtils.playEffectCircleWithData(w, v, EnumParticleTypes.FLAME, 1, 12);
+            DamageSource ds = DamageSource.causeMobDamage(p);
+            EffectUtils.getEntsOfNotGuild(p, 5).stream().forEach((m) -> 
+            {
+                m.attackEntityFrom(ds, 2);   
+            });
+        }
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 1;
+    }
+}

+ 25 - 0
src/main/java/me/km/effects/active/ArmorPasser.java

@@ -0,0 +1,25 @@
+package me.km.effects.active;
+
+import me.km.KajetansMod;
+import me.km.effects.ActiveEffectBase;
+import net.minecraft.entity.player.EntityPlayerMP;
+
+public class ArmorPasser extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {
+        if(!KajetansMod.playerbank.getData(p).hasData("armorpasser"))
+        {
+            KajetansMod.playerbank.getData(p).addGoodTimedData("armorpasser", true, power * 40, " + 35% Stich", 64);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 5 * manaFactor;
+    }
+}

+ 34 - 0
src/main/java/me/km/effects/active/BoneBreaker.java

@@ -0,0 +1,34 @@
+package me.km.effects.active;
+
+import me.km.api.Utils;
+import me.km.effects.ActiveEffectBase;
+import me.km.effects.EffectUtils;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.init.MobEffects;
+import net.minecraft.util.DamageSource;
+
+public class BoneBreaker extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {
+        EntityLivingBase liv = Utils.getTargetedEntity(p, 4, EntityLivingBase.class);
+        if(liv == null)
+        {
+            return false;
+        }
+        DamageSource ds = DamageSource.causeMobDamage(p);
+        ds.setDamageIsAbsolute();
+        ds.setDamageBypassesArmor();
+        liv.attackEntityFrom(ds, liv.getMaxHealth() / 7f);
+        EffectUtils.addPotionTo(liv, MobEffects.NAUSEA, power * 20, 2);
+        return true;
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 4 * manaFactor;
+    }
+}

+ 25 - 0
src/main/java/me/km/effects/active/ConstantPower.java

@@ -0,0 +1,25 @@
+package me.km.effects.active;
+
+import me.km.KajetansMod;
+import me.km.effects.ActiveEffectBase;
+import net.minecraft.entity.player.EntityPlayerMP;
+
+public class ConstantPower extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {
+        if(!KajetansMod.playerbank.getData(p).hasData("cpower"))
+        {
+            KajetansMod.playerbank.getData(p).addGoodTimedData("cpower", 1.3d, power * 20, " + 30 % Schaden", 62);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 3 * manaFactor;
+    }
+}

+ 30 - 0
src/main/java/me/km/effects/active/Cripple.java

@@ -0,0 +1,30 @@
+package me.km.effects.active;
+
+import me.km.api.Utils;
+import me.km.effects.ActiveEffectBase;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.init.MobEffects;
+import net.minecraft.potion.PotionEffect;
+
+public class Cripple extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {
+        EntityLivingBase liv = Utils.getTargetedEntity(p, 4, EntityLivingBase.class);
+        if(liv == null)
+        {
+            return false;
+        }
+        liv.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, power * 20, 2));
+        liv.addPotionEffect(new PotionEffect(MobEffects.NAUSEA, power * 20, 1));
+        return true;
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 1;
+    }
+}

+ 3 - 14
src/main/java/me/km/effects/active/Doomed.java

@@ -3,9 +3,9 @@ package me.km.effects.active;
 import me.km.KajetansMod;
 import me.km.api.Utils;
 import me.km.effects.ActiveEffectBase;
+import me.km.effects.EffectUtils;
 import net.minecraft.entity.player.EntityPlayerMP;
 import net.minecraft.util.DamageSource;
-import net.minecraft.util.math.Vec3d;
 
 public class Doomed extends ActiveEffectBase
 {
@@ -17,18 +17,7 @@ public class Doomed extends ActiveEffectBase
         {
             return false;
         }
-        
-        Vec3d v1 = p2.getPositionVector();
-        Vec3d v2 = p.getPositionVector();
-        
-        Utils.setVelocity(p, (v1.x - v2.x) * 0.2, (v1.y - v2.y) * 0.2 + 0.9, (v1.z - v2.z) * 0.2);
-
-         KajetansMod.scheduler.scheduleTask(() -> 
-        {
-            Vec3d v3 = p2.getPositionVector();
-            Vec3d v4 = p.getPositionVector();
-            Utils.setVelocity(p, (v3.x - v4.x) * 0.2, (v3.y - v4.y) * 0.2, (v3.z - v4.z) * 0.2);
-        }, 12);
+        EffectUtils.jumpTo(p, p2);
         int duration = 20 * power;
         KajetansMod.playerbank.getData(p2).addBadTimedData("doomed", p, duration, "Todgeweiht", 52);
         KajetansMod.scheduler.scheduleTask(() -> 
@@ -41,6 +30,6 @@ public class Doomed extends ActiveEffectBase
     @Override
     protected int getManaCost(int manaFactor) 
     {
-        return 4 * manaFactor;
+        return 1;
     }
 }

+ 1 - 0
src/main/java/me/km/effects/active/ElvishHorn.java

@@ -24,6 +24,7 @@ public class ElvishHorn extends ActiveEffectBase
         }
         EffectUtils.getPlayersOfGuild(p, power + 2).forEach(pl -> 
         {
+            EffectUtils.addPotionTo(p, MobEffects.SPEED, time, 1);
         });
         return true;
     }

+ 34 - 0
src/main/java/me/km/effects/active/FireProtectionRain.java

@@ -0,0 +1,34 @@
+package me.km.effects.active;
+
+import me.km.effects.ActiveEffectBase;
+import me.km.effects.EffectUtils;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.init.MobEffects;
+import net.minecraft.util.EnumParticleTypes;
+import net.minecraft.util.math.Vec3d;
+import net.minecraft.world.WorldServer;
+
+public class FireProtectionRain extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {
+        WorldServer w = p.getServerWorld();
+        Vec3d v = p.getPositionVector();
+        for(int i = 1; i <= power + 2; i++)
+        {
+            EffectUtils.playEffectCircle(w, v, EnumParticleTypes.FLAME, i, 6 * i);
+        }
+        EffectUtils.getPlayersOfGuild(p, power + 2).forEach(pl -> 
+        {
+            EffectUtils.addPotionTo(p, MobEffects.FIRE_RESISTANCE, 240, 1);
+        });
+        return true;
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 1;
+    }
+}

+ 37 - 0
src/main/java/me/km/effects/active/HungerPunch.java

@@ -0,0 +1,37 @@
+package me.km.effects.active;
+
+import me.km.api.Utils;
+import me.km.effects.ActiveEffectBase;
+import me.km.effects.EffectUtils;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.init.MobEffects;
+import net.minecraft.util.DamageSource;
+
+public class HungerPunch extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {
+        EntityLivingBase liv = Utils.getTargetedEntity(p, 4, EntityLivingBase.class);
+        if(liv == null)
+        {
+            return false;
+        }
+        DamageSource ds = DamageSource.causeMobDamage(p);
+        ds.setDamageIsAbsolute();
+        ds.setDamageBypassesArmor();
+        liv.attackEntityFrom(ds, p.getMaxHealth() / 7f);
+        if(p.getMaxHealth() / 2 < p.getHealth())
+        {
+            EffectUtils.addPotionTo(liv, MobEffects.HUNGER, power * 40, 2);
+        }
+        return true;
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 4 * manaFactor;
+    }
+}

+ 26 - 0
src/main/java/me/km/effects/active/ImpactPunch.java

@@ -0,0 +1,26 @@
+package me.km.effects.active;
+
+import me.km.KajetansMod;
+import me.km.effects.ActiveEffectBase;
+import net.minecraft.entity.player.EntityPlayerMP;
+
+public class ImpactPunch extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {
+        if(!KajetansMod.playerbank.getData(p).hasData("impactpunch"))
+        {
+            double d = power / 10d;
+            KajetansMod.playerbank.getData(p).addGoodData("impactpunch", d + 1, " + " + (d * 100) + "% Schaden", 60);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 1;
+    }
+}

+ 35 - 0
src/main/java/me/km/effects/active/JumpAttack.java

@@ -0,0 +1,35 @@
+package me.km.effects.active;
+
+import me.km.KajetansMod;
+import me.km.api.Utils;
+import me.km.effects.ActiveEffectBase;
+import me.km.effects.EffectUtils;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.init.MobEffects;
+
+public class JumpAttack extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {
+        EntityLivingBase liv = Utils.getTargetedEntity(p, 8, EntityLivingBase.class);
+        if(liv == null)
+        {
+            return false;
+        }
+        EffectUtils.jumpTo(p, liv);
+        KajetansMod.scheduler.scheduleTask(() -> 
+        {
+            EffectUtils.addPotionTo(liv, MobEffects.SLOWNESS, power * 20, 2);
+            EffectUtils.addPotionTo(liv, MobEffects.BLINDNESS, power * 20, 0);
+        }, 20);
+        return true;
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 1;
+    }
+}

+ 32 - 0
src/main/java/me/km/effects/active/LifeBreaker.java

@@ -0,0 +1,32 @@
+package me.km.effects.active;
+
+import me.km.api.Utils;
+import me.km.effects.ActiveEffectBase;
+import me.km.effects.EffectUtils;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.init.MobEffects;
+
+public class LifeBreaker extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {
+        EntityLivingBase liv = Utils.getTargetedEntity(p, 6, EntityLivingBase.class);
+        if(liv == null || liv.getHealth() > liv.getMaxHealth() / 5)
+        {
+            return false;
+        }
+        Utils.teleportEntity(p, liv);
+        EffectUtils.addPotionTo(liv, MobEffects.SLOWNESS, power * 20, 200);
+        EffectUtils.addPotionTo(liv, MobEffects.JUMP_BOOST, power * 20, 128);
+        EffectUtils.addPotionTo(liv, MobEffects.WEAKNESS, power * 20, 1);
+        return true;
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 4 * manaFactor;
+    }
+}

+ 37 - 0
src/main/java/me/km/effects/active/LifeSteal.java

@@ -0,0 +1,37 @@
+package me.km.effects.active;
+
+import me.km.KajetansMod;
+import me.km.api.Utils;
+import me.km.effects.ActiveEffectBase;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.util.DamageSource;
+
+public class LifeSteal extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {
+        EntityLivingBase liv = Utils.getTargetedEntity(p, 6, EntityLivingBase.class);
+        if(liv == null || liv.getHealth() > liv.getMaxHealth() / 5)
+        {
+            return false;
+        }
+        DamageSource ds = DamageSource.causeMobDamage(p);
+        float real = Utils.getRealDamage(liv, ds, power);
+        liv.attackEntityFrom(ds, power);
+        p.heal(real);
+        if(liv instanceof EntityPlayerMP)
+        {
+            KajetansMod.playerbank.getData((EntityPlayerMP) liv)
+                    .addBadTimedData("lessheal", true, 100, " - 50% Heilung", 63);
+        }
+        return true;
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 1;
+    }
+}

+ 30 - 0
src/main/java/me/km/effects/active/Smash.java

@@ -0,0 +1,30 @@
+package me.km.effects.active;
+
+import me.km.api.Utils;
+import me.km.effects.ActiveEffectBase;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.util.DamageSource;
+
+public class Smash extends ActiveEffectBase
+{
+    @Override
+    protected boolean executeEffect(EntityPlayerMP p, int power) 
+    {
+        EntityLivingBase liv = Utils.getTargetedEntity(p, 4, EntityLivingBase.class);
+        if(liv == null)
+        {
+            return false;
+        }
+        DamageSource ds = DamageSource.causeMobDamage(p);
+        ds.setDamageBypassesArmor();
+        liv.attackEntityFrom(ds, power);
+        return true;
+    }
+
+    @Override
+    protected int getManaCost(int manaFactor) 
+    {
+        return 1;
+    }
+}

+ 1 - 1
src/main/java/me/km/effects/active/SmokeBomb.java

@@ -12,7 +12,7 @@ public class SmokeBomb extends ActiveEffectBase
     protected boolean executeEffect(EntityPlayerMP p, int power) 
     {
         EntitySnowball ball = EffectUtils.launchProjectile(p, EntitySnowball.class, power / 4f, p);
-        KajetansMod.effects.addEntityData(p, "smokebomb");
+        KajetansMod.effects.addEntityData(ball, "smokebomb");
         return false;
     }
 

+ 2 - 0
src/main/java/me/km/effects/passive/ArrowEffects.java

@@ -157,9 +157,11 @@ public class ArrowEffects extends ModuleListener
         {
             return;
         }
+        DamageSource ds = DamageSource.causeMobDamage(p);
         EffectUtils.spawnParticle(p.getServerWorld(), EnumParticleTypes.EXPLOSION_LARGE, pro.getPositionVector(), 1);
         EffectUtils.getEntsOfNotGuild(p, p.getServerWorld(), pro.getPositionVector(), 3).forEach(ent -> 
         {
+            ent.attackEntityFrom(ds, 4);    
             EffectUtils.addPotionTo(ent, MobEffects.BLINDNESS, 200, 0);
         });
     }

+ 47 - 6
src/main/java/me/km/effects/passive/EntityDamageEffects.java

@@ -9,10 +9,12 @@ import me.km.effects.EffectUtils;
 import me.km.events.PlayerHurtEvent;
 import me.km.playerbank.PlayerData;
 import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.entity.player.EntityPlayerMP;
 import net.minecraft.init.MobEffects;
 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.SubscribeEvent;
 
@@ -73,12 +75,12 @@ public class EntityDamageEffects extends ModuleListener
         {
             return;
         }  
-        Entity ent = e.getSource().getImmediateSource();
-        if(ent == null || !(ent instanceof EntityPlayerMP))
+        Entity pEnt = e.getSource().getImmediateSource();
+        if(pEnt == null || !(pEnt instanceof EntityPlayerMP))
         {
             return;
         } 
-        EntityPlayerMP p = (EntityPlayerMP) ent;
+        EntityPlayerMP p = (EntityPlayerMP) pEnt;
         Utils.ToolTypes tt = Utils.getToolType(p.getHeldItemMainhand());
         float damageBonus = 1;
         if(tt != null)
@@ -112,6 +114,7 @@ public class EntityDamageEffects extends ModuleListener
             }
         }
         
+        EntityLivingBase ent = e.getEntityLiving();
         PlayerData data = KajetansMod.playerbank.getData(p);
 
         if(data.removeData("shadowhit"))
@@ -120,9 +123,9 @@ public class EntityDamageEffects extends ModuleListener
             EffectUtils.addPotionTo(p, MobEffects.INVISIBILITY, 40, 0);
         }
         
-        if(e.getEntity() instanceof EntityPlayerMP)
+        if(ent instanceof EntityPlayerMP)
         {
-            EntityPlayerMP victim = (EntityPlayerMP) e.getEntity();
+            EntityPlayerMP victim = (EntityPlayerMP) ent;
             EntityPlayer damager = KajetansMod.playerbank.getData(victim).getData("doomed", EntityPlayer.class);
             if(damager != null && damager.equals(p))
             {
@@ -132,7 +135,13 @@ public class EntityDamageEffects extends ModuleListener
         
         if(data.hasData("poisonedblade"))
         {
-            EffectUtils.addPotionTo(e.getEntityLiving(), MobEffects.SPEED, 80, 1);
+            EffectUtils.addPotionTo(ent, MobEffects.POISON, 80, 1);
+        }
+        
+        if(data.hasData("armorpasser"))
+        {
+            float reduced = e.getAmount() - Utils.getDamagerAfterArmor(ent, e.getSource(), e.getAmount());
+            e.setAmount(e.getAmount() + reduced * 0.35f);
         }
         
         double powerAttack = data.getDouble("powerattack");
@@ -141,7 +150,39 @@ public class EntityDamageEffects extends ModuleListener
             damageBonus *= powerAttack;
             data.removeData("powerattack");
         }
+        powerAttack = data.getDouble("cpower");
+        if(powerAttack != 0)
+        {
+            damageBonus *= powerAttack;
+        }
+        powerAttack = data.getDouble("impactpunch");
+        if(powerAttack != 0)
+        {
+            damageBonus *= powerAttack;
+            EffectUtils.addPotionTo(ent, MobEffects.SLOWNESS, (int) (powerAttack * 20), 1);
+            data.removeData("impactpunch");
+        }
         
         e.setAmount(e.getAmount() * damageBonus);
     }
+    
+    @SubscribeEvent(receiveCanceled = false)
+    public void onEntityHeal(LivingHealEvent e)
+    {         
+        if(!KajetansMod.worldManager.getWorldPreferences(e.getEntity().world).skills)
+        {
+            return;
+        }  
+        Entity ent = e.getEntityLiving();
+        if(!(ent instanceof EntityPlayerMP))
+        {
+            return;
+        } 
+        EntityPlayerMP p = (EntityPlayerMP) ent;
+        PlayerData data = KajetansMod.playerbank.getData(p);
+        if(data.hasData("lessheal"))
+        {
+            e.setAmount(e.getAmount() / 2);
+        }
+    }
 }

+ 9 - 45
src/main/java/me/km/entities/EntityItemProjectile.java

@@ -93,61 +93,25 @@ public class EntityItemProjectile extends EntityItem implements IProjectile
             
             float fw = this.width / 2;
             float fh = this.height / 2;
-            List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this, new AxisAlignedBB(prevPosX, prevPosY, prevPosZ, posX, posY, posZ).expand(fw, fh, fw));
+            List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this, 
+                    new AxisAlignedBB(prevPosX, prevPosY, prevPosZ, posX, posY, posZ).expand(fw, fh, fw));
             if(list.isEmpty())
             {
                 return;
             }
             
-            double oldX = this.prevPosX;
-            double oldY = this.prevPosY;
-            double oldZ = this.prevPosZ;
-            double newX = this.posX;
-            double newY = this.posY;
-            double newZ = this.posZ;
-            
-            if(oldX < newX)
-            {
-                oldX -= fw;
-                newX += fw;
-            }
-            else
-            {
-                oldX += fw;
-                newX -= fw;
-            }
-            
-            if(oldY < newY)
-            {
-                oldY -= fh;
-                newY += fh;
-            }
-            else
-            {
-                oldY += fh;
-                newY -= fh;
-            }
-            
-            if(oldZ < newZ)
-            {
-                oldZ -= fw;
-                newZ += fw;
-            }
-            else
-            {
-                oldZ += fw;
-                newZ -= fw;
-            }
-            
-            Vec3d oldV = new Vec3d(oldX, oldY, oldZ);
-            Vec3d newV = new Vec3d(newX, newY, newZ);
+            Vec3d oldV = new Vec3d(this.prevPosX, prevPosY, prevPosZ);
+            Vec3d newV = new Vec3d(this.posX, this.posY, this.posZ);          
             list.removeIf(ent -> 
             {
+                // this prevents the projectile from hitting its shooter during
+                // the first ticks
                 if(ent == thrower && ReflectionUtils.getAge(this) < 5)
                 {
                     return true;
                 }
-                return ent.getEntityBoundingBox().calculateIntercept(oldV, newV) == null;
+                // size of the projectile is 0.25 x 0.25
+                return ent.getEntityBoundingBox().grow(0.125f).calculateIntercept(oldV, newV) == null;
             });
             if(!list.isEmpty())
             {
@@ -164,7 +128,7 @@ public class EntityItemProjectile extends EntityItem implements IProjectile
         {
             if(thrower instanceof EntityPlayer)
             {
-                KajetansMod.scripts.getEvent(ScriptEvents.class).onEntityItemProjectileHit((EntityPlayer) thrower, this.getItem(), list);
+                KajetansMod.scripts.getEvent(ScriptEvents.class).onEntityItemProjectileHit(this, (EntityPlayer) thrower, this.getItem(), list);
             }
         }
         else

+ 2 - 3
src/main/java/me/km/exception/IllegalStringLocationException.java

@@ -1,12 +1,11 @@
 package me.km.exception;
 
-import me.hammerle.code.Script;
 import me.hammerle.exceptions.IllegalStringException;
 
 public class IllegalStringLocationException extends IllegalStringException
 {
-    public IllegalStringLocationException(Script sc, String s) 
+    public IllegalStringLocationException(String s) 
     {
-        super(sc, s);
+        super(s);
     }
 }

+ 18 - 14
src/main/java/me/km/inventory/CustomContainer.java

@@ -21,6 +21,24 @@ public class CustomContainer extends ContainerChest
         canBeClosed = true;
     }
     
+    public void closeSafe(EntityPlayer p)
+    {
+        if(canBeClosed)
+        {
+            p.closeScreen();
+        }
+        else
+        {
+            KajetansMod.scheduler.scheduleTask(() -> 
+            {
+                if(p.openContainer.windowId == this.windowId)
+                {
+                    p.closeScreen();
+                }
+            });
+        }
+    }
+    
     public CustomContainer(SnuviInventory inv, EntityPlayerMP p) 
     {
         super(p.inventory, inv, p);
@@ -82,18 +100,4 @@ public class CustomContainer extends ContainerChest
     public void onCanceledClick(int slotId, int dragType, ClickType clickTypeIn, EntityPlayerMP player)
     {
     }
-
-    @Override
-    public void onContainerClosed(EntityPlayer p) 
-    {
-        if(canBeClosed)
-        {
-            super.onContainerClosed(p);
-        }
-        else
-        {
-            // closing container on next tick to prevent closing during noClicking or onCanceledClick
-            KajetansMod.scheduler.scheduleTask(() -> super.onContainerClosed(p));
-        }
-    }
 }

+ 5 - 2
src/main/java/me/km/inventory/TeleportContainer.java

@@ -20,12 +20,15 @@ public class TeleportContainer extends CustomContainer
     {
         super("Teleport to Player ...", list.size() % 9 == 0 ? list.size() : ((list.size() / 9) + 1) * 9, p);
         this.players = list;
-        this.players.remove(p);
         
         InventoryBasic inv = super.getShownInventory();
         int counter = 0;
         for(EntityPlayer player : players) 
         {
+            if(player == p)
+            {
+                continue;
+            }
             inv.setInventorySlotContents(counter, Utils.getPlayerHead(player).setStackDisplayName("§6" + player.getName()));
             counter++;
         }     
@@ -45,6 +48,6 @@ public class TeleportContainer extends CustomContainer
         m.send(p2, "Du kannst mit /tpa akzeptieren.");
         HashMap<UUID, UUID> tpaccept = KajetansMod.generalCommands.getCommand(CommandTeleportAccept.class).tpaccept;
         tpaccept.put(p2.getUniqueID(), p.getUniqueID());
-        p.closeScreen();
+        this.closeSafe(p);
     }
 }

+ 1 - 0
src/main/java/me/km/jobsystem/Job.java

@@ -117,6 +117,7 @@ public class Job
     
     public HashMap<Skill, Byte> getSkillMap(byte level)
     {
+        //System.out.println("SKILLMAP CONTAINS " + skillmap.size() + " ELEMENTS");
         HashMap<Skill, Byte> map = new HashMap<>();
         if(level < 1)
         {

+ 3 - 0
src/main/java/me/km/jobsystem/JobAPI.java

@@ -128,8 +128,10 @@ public class JobAPI extends Module
             Job j = jobs.get(b);
             if(j == null)
             {
+                //System.out.println("CANT FIND JOB " + b);
                 return;
             }
+            //System.out.println("FOUND JOB " + b);
             j.getSkillMap(getLevel(p, b)).forEach((k, v) -> 
             {
                 map.merge(k, v, (b1, b2) -> (b1 > b2 ? b1 : b2));
@@ -144,6 +146,7 @@ public class JobAPI extends Module
     
     public void registerJob(byte job, String name)
     {
+        //System.out.println("REGISTERING JOB " + job + " " + name);
         jobs.put(job, new Job(name));
     }
     

+ 3 - 1
src/main/java/me/km/nms/NmsUtilities.java

@@ -2,6 +2,7 @@ package me.km.nms;
 
 import java.util.List;
 import me.hammerle.code.Script;
+import me.hammerle.exceptions.HoldCodeException;
 import me.hammerle.exceptions.IllegalStringException;
 import me.km.api.Location;
 import net.minecraft.block.Block;
@@ -83,7 +84,8 @@ public class NmsUtilities
         }
         catch(NBTException ex)
         {
-            throw new IllegalStringException(sc, s);
+            sc.getLogger().printException(new IllegalStringException(s), sc, sc.getActiveRealCodeLine());
+            throw new HoldCodeException();
         }
     }
     

+ 9 - 0
src/main/java/me/km/plots/ProtectionBank.java

@@ -467,6 +467,15 @@ public class ProtectionBank extends SimpleDataBank
         });
     }
     
+    public ArrayList<Object> getRegionIds(World w, BlockPos pos)
+    {
+        return this.getFirstColumn("SELECT id FROM plots WHERE " +
+                "x1<=" + pos.getX() + " AND x2>=" + pos.getX() + 
+                " AND y1<=" + pos.getY() + " AND y2>=" + pos.getY() + 
+                " AND z1<=" + pos.getZ() + " AND z2>=" + pos.getZ() +
+                " AND world_name='" + ModDimensions.getWorldName(w) + "';");
+    }
+    
     public Integer getFirstRegionId(World w, BlockPos pos)
     {
         return this.getFirst("SELECT id FROM plots WHERE " +

+ 1 - 1
src/main/java/me/km/skills/ActiveSkillContainer.java

@@ -27,7 +27,7 @@ public class ActiveSkillContainer extends SkillContainer
         if(ActiveEffectBase.executeEffect(s.getEffect().getEffectBase(), p, level, level, EffectCause.SKILL))
         {
             KajetansMod.skills.sendToPlayers(p.world, p.getPositionVector(), 20, "§3" + p.getName() + "§r hat §3" + s.getName() + "§r benutzt.");
-            p.closeScreen();
+            this.closeSafe(p);
         }
     }
 }

+ 2 - 0
src/main/java/me/km/skills/SkillContainer.java

@@ -21,6 +21,8 @@ public class SkillContainer extends CustomContainer
     {
         super(title, stacks.size() % 9 != 0 ? ((stacks.size() / 9) + 1) + 9 : stacks.size(), p);
         
+        //System.out.println("ANZAHL DER SKILLS: " + stacks.size());
+        
         EntityInventory inv = (EntityInventory) super.getShownInventory();
         if(inv.getSizeInventory() > 45)
         {

+ 126 - 140
src/main/java/me/km/snuviscript/MinecraftFunctions.java

@@ -16,13 +16,13 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.UUID;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import me.hammerle.code.ISnuviLogger;
 import me.hammerle.code.Script;
 import me.hammerle.code.ScriptUtils;
-import me.hammerle.exceptions.SnuviException;
 import me.km.api.Location;
 import me.km.api.TitleAPI;
 import me.km.dimensions.ModDimensions;
@@ -77,6 +77,9 @@ import me.hammerle.exceptions.PreScriptException;
 import me.hammerle.exceptions.IllegalStringException;
 import me.hammerle.code.SnuviParser;
 import me.hammerle.exceptions.HoldCodeException;
+import me.hammerle.math.Fraction;
+import me.km.inventory.CustomContainer;
+import net.minecraft.entity.item.EntityItem;
 import net.minecraft.util.math.MathHelper;
 
 public class MinecraftFunctions implements ISnuviLogger
@@ -130,15 +133,15 @@ public class MinecraftFunctions implements ISnuviLogger
         // Player-Bibliothek
         // -------------------------------------------------------------  
         parser.registerFunction("player.getitemamount", (args, qd) ->       
-                InventoryUtils.searchInventoryFor(((EntityPlayer) args[0]).inventory, (ItemStack) args[2], (boolean) args[1]));                
+                new Fraction(InventoryUtils.searchInventoryFor(((EntityPlayer) args[0]).inventory, (ItemStack) args[2], (boolean) args[1])));                
         parser.registerFunction("player.removeitem", (args, qd) -> 
                 removeItem(args));                 
         parser.registerFunction("player.giveitem", (args, qd) ->       
                 giveItem(args));
-        parser.registerConsumer("player.shootprojectile", (args, qd) -> 
+        parser.registerFunction("player.shootprojectile", (args, qd) -> 
                 EffectUtils.launchProjectile((EntityPlayer) args[0], getClass(args[1].toString()), ScriptUtils.getDouble(args[2]), args[3]));
         parser.registerConsumer("player.respawn", (args, qd) ->
-                respawnPlayer(args));
+                respawnPlayer(qd, args));
         parser.registerConsumer("player.inventorytolist", (args, qd) -> 
                 qd.setVar(args[0].toString(), ((EntityPlayer) args[1]).inventory.mainInventory));    
         parser.registerFunction("player.getnearest", (args, qd) ->                            
@@ -152,11 +155,11 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerConsumer("player.setcompass", (args, qd) -> 
                 ((EntityPlayerMP) args[0]).connection.sendPacket(new SPacketSpawnPosition(((Location) args[1]).getBlockPos()))); 
         parser.registerFunction("player.gethunger", (args, qd) -> 
-                ((EntityPlayer) args[0]).getFoodStats().getFoodLevel());
+                new Fraction(((EntityPlayer) args[0]).getFoodStats().getFoodLevel()));
         parser.registerConsumer("player.sethunger", (args, qd) -> 
                 ((EntityPlayer) args[0]).getFoodStats().setFoodLevel(ScriptUtils.getInt(args[1])));
         parser.registerFunction("player.getsaturation", (args, qd) -> 
-                ReflectionUtils.getSaturation(((EntityPlayer) args[0]).getFoodStats()));
+                Fraction.fromDouble(ReflectionUtils.getSaturation(((EntityPlayer) args[0]).getFoodStats())));
         parser.registerConsumer("player.setsaturation", (args, qd) -> 
                 ReflectionUtils.setSaturation(((EntityPlayer) args[0]).getFoodStats(), ScriptUtils.getFloat(args[1])));
         parser.registerFunction("player.getname", (args, qd) -> 
@@ -182,11 +185,13 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerConsumer("player.settag", (args, qd) -> 
                 setTag(args));
         parser.registerFunction("player.gettag", (args, qd) -> 
-                (double) getTag(args));
+                getTag(args));
         parser.registerConsumer("player.dropinventory", (args, qd) -> 
                 dropInventory(args));
         parser.registerFunction("player.gettarget", (args, qd) -> 
-                Utils.getPlayerTarget((EntityPlayer) args[0], ScriptUtils.getInt(args[1])));
+                new Location(((EntityPlayer) args[0]).world, Utils.getPlayerTarget((EntityPlayer) args[0], ScriptUtils.getInt(args[1]))));
+        parser.registerFunction("player.gettargetentity", (args, qd) -> 
+                Utils.getTargetedEntity((EntityPlayer) args[0], ScriptUtils.getDouble(args[1]), getClass(args[2].toString())));
         parser.registerFunction("player.hasquest", (args, qd) ->     
                 KajetansMod.scripts.hasScript((EntityPlayer) args[0]));
         parser.registerConsumer("player.action", (args, qd) ->     
@@ -206,13 +211,13 @@ public class MinecraftFunctions implements ISnuviLogger
         // Players-Bibliothek
         // ------------------------------------------------------------- 
         parser.registerFunction("players.getamount", (args, qd) ->                            
-                KajetansMod.server.getCurrentPlayerCount());
+                new Fraction(KajetansMod.server.getCurrentPlayerCount()));
         parser.registerConsumer("players.tolist", (args, qd) ->     
-                qd.setVar(args[0].toString(), Arrays.asList(KajetansMod.server.getOnlinePlayerNames())));    
+                qd.setVar(args[0].toString(), new ArrayList(KajetansMod.server.getPlayerList().getPlayers())));    
         parser.registerConsumer("players.toworldlist", (args, qd) ->     
                 qd.setVar(args[0].toString(), new ArrayList(ModDimensions.getWorldFromName(args[1].toString()).playerEntities)));
         parser.registerConsumer("players.near", (args, qd) ->     
-                qd.setVar(args[0].toString(), Utils.getNearbyEntities(((Location) args[1]).getWorld(), ((Location) args[1]).getPos(), ScriptUtils.getDouble(args[2]), EntityPlayer.class).stream().map(p -> p.getName()).collect(Collectors.toList()))); 
+                qd.setVar(args[0].toString(), new ArrayList(Utils.getNearbyEntities(((Location) args[1]).getWorld(), ((Location) args[1]).getPos(), ScriptUtils.getDouble(args[2]), EntityPlayer.class)))); 
 
         // -------------------------------------------------------------    
         // Rank-Bibliothek
@@ -269,11 +274,11 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerFunction("item.gettype", (args, qd) ->    
                 ((ItemStack) args[0]).getItem().getRegistryName().toString());
         parser.registerFunction("item.getdata", (args, qd) ->    
-                ((ItemStack) args[0]).getMetadata());           
+                new Fraction(((ItemStack) args[0]).getMetadata()));           
         parser.registerConsumer("item.setdata", (args, qd) ->    
                 ((ItemStack) args[0]).setItemDamage(ScriptUtils.getInt(args[1])));
         parser.registerFunction("item.getamount", (args, qd) ->    
-                ((ItemStack) args[0]).getCount()); 
+                new Fraction(((ItemStack) args[0]).getCount())); 
         parser.registerConsumer("item.setamount", (args, qd) ->   
                 ((ItemStack) args[0]).setCount(ScriptUtils.getInt(args[1])));   
         parser.registerFunction("item.getname", (args, qd) ->    
@@ -287,7 +292,7 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerConsumer("item.addlore", (args, qd) ->   
                 ItemStackUtils.addLore((ItemStack) args[0], ScriptUtils.connect(args, 2), ScriptUtils.getInt(args[1])));
         parser.registerFunction("item.getenchantlevel", (args, qd) ->   
-                EnchantmentHelper.getEnchantmentLevel(Enchantment.getEnchantmentByLocation(args[1].toString()), (ItemStack) args[0]));
+                new Fraction(EnchantmentHelper.getEnchantmentLevel(Enchantment.getEnchantmentByLocation(args[1].toString()), (ItemStack) args[0])));
         parser.registerConsumer("item.setcooldown", (args, qd) ->   
                 ((EntityPlayer) args[0]).getCooldownTracker().setCooldown(((ItemStack) args[1]).getItem(), ScriptUtils.getInt(args[2])));
         parser.registerFunction("item.gettooltype", (args, qd) ->   
@@ -297,7 +302,7 @@ public class MinecraftFunctions implements ISnuviLogger
         // Location-Bibliothek
         // -------------------------------------------------------------  
         parser.registerFunction("loc.distance", (args, qd) -> 
-                ((Location) args[0]).getPos().distanceTo(((Location) args[1]).getPos()));  
+                Fraction.fromDouble(((Location) args[0]).getPos().distanceTo(((Location) args[1]).getPos())));  
         parser.registerConsumer("loc.setyaw", (args, qd) -> 
                 ((Location) args[0]).setYaw(ScriptUtils.getFloat(args[1])));  
         parser.registerConsumer("loc.setpitch", (args, qd) -> 
@@ -307,7 +312,7 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerFunction("loc.getcoord", (args, qd) -> 
                 getCoordOfLocation(args));
         parser.registerFunction("loc.gettime", (args, qd) -> 
-                ((Long) ((Location) args[0]).getWorld().getWorldTime()).doubleValue());
+                new Fraction(((Location) args[0]).getWorld().getWorldTime()));
         parser.registerFunction("loc.hasstorm", (args, qd) -> 
                 ((Location) args[0]).getWorld().isRaining());
         parser.registerFunction("loc.isbetween", (args, qd) -> 
@@ -319,7 +324,7 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerFunction("block.gettype", (args, qd) -> 
                 ((Location) args[0]).getWorld().getBlockState(((Location) args[0]).getBlockPos()).getBlock().getRegistryName().toString());
         parser.registerFunction("block.getdata", (args, qd) -> 
-                (double) getBlockData((Location) args[0]));
+                getBlockData((Location) args[0]));
         parser.registerConsumer("block.clone", (args, qd) -> 
                 cloneBlock(args));
         parser.registerConsumer("block.set", (args, qd) -> 
@@ -369,13 +374,13 @@ public class MinecraftFunctions implements ISnuviLogger
         // Job-Bibliothek 
         // -------------------------------------------------------------  
         parser.registerFunction("job.getlevel", (args, qd) -> 
-                (double) KajetansMod.jobs.getLevel((EntityPlayer) args[0], ScriptUtils.getByte(args[1])));
+                new Fraction(KajetansMod.jobs.getLevel((EntityPlayer) args[0], ScriptUtils.getByte(args[1]))));
         parser.registerConsumer("job.addlevel", (args, qd) -> 
                 KajetansMod.jobs.addLevel((EntityPlayer) args[0], ScriptUtils.getByte(args[1]), ScriptUtils.getByte(args[2])));
         parser.registerConsumer("job.setlevel", (args, qd) -> 
                 KajetansMod.jobs.setLevel((EntityPlayer) args[0], ScriptUtils.getByte(args[1]), ScriptUtils.getByte(args[2])));
         parser.registerFunction("job.getxp", (args, qd) -> 
-                (double) KajetansMod.jobs.getXP((EntityPlayer) args[0], ScriptUtils.getByte(args[1])));
+                new Fraction(KajetansMod.jobs.getXP((EntityPlayer) args[0], ScriptUtils.getByte(args[1]))));
         parser.registerConsumer("job.addxp", (args, qd) -> 
                 KajetansMod.jobs.addXP((EntityPlayer) args[0], ScriptUtils.getByte(args[1]), ScriptUtils.getByte(args[2])));
         parser.registerConsumer("job.setxp", (args, qd) -> 
@@ -389,17 +394,17 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerConsumer("job.registerskill", (args, qd) -> 
                 KajetansMod.jobs.registerSkill(ScriptUtils.getByte(args[0]), KajetansMod.skills.getSkill(ScriptUtils.getInt(args[1])), ScriptUtils.getByte(args[2]), ScriptUtils.getByte(args[3])));
         parser.registerFunction("job.getamount", (args, qd) -> 
-                (double) KajetansMod.jobs.getNumberOfJobs());
+                new Fraction(KajetansMod.jobs.getNumberOfJobs()));
         parser.registerFunction("job.getname", (args, qd) -> 
                 KajetansMod.jobs.getJobName(ScriptUtils.getByte(args[0])));
         parser.registerFunction("job.geteffectlevel", (args, qd) -> 
-                (double) EffectUtils.getEffectLevel((EntityPlayer) args[0], me.km.effects.Effect.valueOf(args[1].toString())));
+                new Fraction(EffectUtils.getEffectLevel((EntityPlayer) args[0], me.km.effects.Effect.valueOf(args[1].toString()))));
         parser.registerFunction("job.hasjob", (args, qd) -> 
                 KajetansMod.jobs.hasJob((EntityPlayer) args[0], ScriptUtils.getByte(args[1])));
         parser.registerFunction("job.hasrecipe", (args, qd) -> 
                 KajetansMod.jobs.hasRecipe((EntityPlayer) args[0], ScriptHelper.getItem(args[1].toString())));
         parser.registerConsumer("job.getjobs", (args, qd) -> 
-                qd.setVar(args[0].toString(), KajetansMod.jobs.getJobs((EntityPlayer) args[1]).stream().map(b -> (double) b).collect(Collectors.toList())));
+                qd.setVar(args[0].toString(), KajetansMod.jobs.getJobs((EntityPlayer) args[1]).stream().map(b -> new Fraction(b)).collect(Collectors.toList())));
         parser.registerFunction("job.isregmaterial", (args, qd) -> 
                 KajetansMod.jobs.isPreferedMaterial((EntityPlayer) args[0],Block.getBlockFromName(args[1].toString())));
         parser.registerConsumer("job.setjob", (args, qd) -> 
@@ -415,7 +420,7 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerConsumer("entity.damage", (args, qd) -> 
                 damageEntity(args));  
         parser.registerFunction("entity.gethealth", (args, qd) -> 
-                ((EntityLivingBase) args[0]).getHealth());     
+                Fraction.fromDouble(((EntityLivingBase) args[0]).getHealth()));     
         parser.registerConsumer("entity.sethealth", (args, qd) -> 
                 ((EntityLivingBase) args[0]).setHealth(ScriptUtils.getFloat(args[1])));  
         parser.registerConsumer("entity.setname", (args, qd) -> 
@@ -445,7 +450,7 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerConsumer("entity.setvars", (args, qd) -> 
                 ScriptVars.setEntityVars(qd, Utils.getNearestEntity(((Location) args[0]).getWorld(), ((Location) args[0]).getPos(), 3, (Class<? extends Entity>) getClass("net.minecraft.entity." + args[1]))));
         parser.registerConsumer("entity.addeffect", (args, qd) -> 
-                EffectUtils.addPotionTo((EntityLivingBase) args[0], Potion.getPotionFromResourceLocation(args[1].toString()), ScriptUtils.getInt(args[2]), ScriptUtils.getInt(args[3])));
+                addEffect(args));
         parser.registerFunction("entity.haseffect", (args, qd) -> 
                 ((EntityLivingBase) args[0]).isPotionActive(Potion.getPotionFromResourceLocation(args[1].toString())));
         parser.registerConsumer("entity.goto", (args, qd) ->
@@ -462,18 +467,22 @@ public class MinecraftFunctions implements ISnuviLogger
                 ((Entity) args[0]).setNoGravity(!(boolean) args[1]));
         parser.registerConsumer("entity.iswet", (args, qd) -> 
                 ((Entity) args[0]).isWet());
+        parser.registerConsumer("entity.setpickupdelay", (args, qd) -> 
+                ((EntityItem) args[0]).setPickupDelay(ScriptUtils.getInt(args[1])));
+        parser.registerConsumer("entity.setage", (args, qd) -> 
+                ReflectionUtils.setAge((EntityItem) args[0], ScriptUtils.getInt(args[1])));
 
         // -------------------------------------------------------------
         // Status-Bibliothek
         // -------------------------------------------------------------  
         parser.registerFunction("status.getmana", (args, qd) -> 
-                (double) EnvironmentAPI.getMana(((EntityPlayer) args[0])));
+                new Fraction(EnvironmentAPI.getMana(((EntityPlayer) args[0]))));
         parser.registerFunction("status.getcold", (args, qd) -> 
-                (double) EnvironmentAPI.getCold(((EntityPlayer) args[0])));
+                new Fraction(EnvironmentAPI.getCold(((EntityPlayer) args[0]))));
         parser.registerFunction("status.getenergy", (args, qd) -> 
-                (double) EnvironmentAPI.getEnergy(((EntityPlayer) args[0])));
+                new Fraction(EnvironmentAPI.getEnergy(((EntityPlayer) args[0]))));
         parser.registerFunction("status.getthirst", (args, qd) -> 
-                (double) EnvironmentAPI.getThirst(((EntityPlayer) args[0])));
+                new Fraction(EnvironmentAPI.getThirst(((EntityPlayer) args[0]))));
         parser.registerConsumer("status.changemange", (args, qd) -> 
                 EnvironmentAPI.changeMana(((EntityPlayer) args[0]), ScriptUtils.getInt(args[1])));
         parser.registerConsumer("status.changecold", (args, qd) -> 
@@ -491,7 +500,7 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerConsumer("status.resetthirst", (args, qd) -> 
                 EnvironmentAPI.resetThirst(((EntityPlayer) args[0])));
         parser.registerFunction("status.gettemperature", (args, qd) -> 
-                (double) EnvironmentAPI.getTemperature(((Location) args[0]).getWorld(), ((Location) args[0]).getBlockPos()));    
+                new Fraction(EnvironmentAPI.getTemperature(((Location) args[0]).getWorld(), ((Location) args[0]).getBlockPos())));    
 
         // -------------------------------------------------------------  
         // GMap-Bibliothek   
@@ -545,11 +554,11 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerFunction("table.get", (args, qd) -> 
                 ((Table) args[0]).getElement(ScriptUtils.getInt(args[1]), ScriptUtils.getInt(args[2])));
         parser.registerFunction("table.getindexof", (args, qd) -> 
-                (double) ((Table) args[0]).getIndexOf(args[1]));
+                new Fraction(((Table) args[0]).getIndexOf(args[1])));
         parser.registerConsumer("table.setsortcolumn", (args, qd) -> 
                 ((Table) args[0]).setSortColumn(ScriptUtils.getInt(args[1])));
         parser.registerFunction("table.getsize", (args, qd) -> 
-                (double) ((Table) args[0]).getSize());
+                new Fraction(((Table) args[0]).getSize()));
 
         // -------------------------------------------------------------  
         // Plot-Bibliothek   
@@ -558,8 +567,8 @@ public class MinecraftFunctions implements ISnuviLogger
                 KajetansMod.plots.getDataBank(ProtectionBank.class).hasTag(((Location) args[0]).getWorld(), ((Location) args[0]).getBlockPos(), args[1].toString())); 
         parser.registerConsumer("plot.add", (args, qd) ->    
                 addPlot(args));
-        parser.registerFunction("plot.getid", (args, qd) ->    
-                KajetansMod.plots.getDataBank(ProtectionBank.class).getFirstRegionId(((Location) args[0]).getWorld(), ((Location) args[0]).getBlockPos()));
+        parser.registerConsumer("plot.getids", (args, qd) ->  
+                qd.setVar(args[0].toString(), getPlotIds(args)));
         parser.registerFunction("plot.canbuild", (args, qd) ->    
                 KajetansMod.plots.getDataBank(ProtectionBank.class).canBuild(((Location) args[0]).getWorld(), ((Location) args[0]).getBlockPos(), (EntityPlayer) args[1]));
         parser.registerFunction("plot.getname", (args, qd) ->    
@@ -575,7 +584,7 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerConsumer("quest.playerstolist", (args, qd) ->  
                 qd.setVar(args[0].toString(), new ArrayList<>(((PlayerScript) qd).getPlayers()))); 
         parser.registerFunction("quest.getplayeramount", (args, qd) ->      
-                ((PlayerScript) qd).getPlayers().size()); 
+                new Fraction(((PlayerScript) qd).getPlayers().size())); 
         parser.registerConsumer("quest.start", (args, qd) ->  
                 startPlayerScript(args, qd));
         parser.registerFunction("quest.isactive", (args, qd) ->  
@@ -615,7 +624,7 @@ public class MinecraftFunctions implements ISnuviLogger
         parser.registerConsumer("inv.open", (args, qd) -> 
                 new ScriptInventoryHolder((SnuviInventory) args[0], (EntityPlayerMP) args[1], (MinecraftScript) qd).openForPlayer((EntityPlayerMP) args[1]));
         parser.registerConsumer("inv.close", (args, qd) -> 
-                ((EntityPlayer) args[0]).closeScreen());                 
+                invClose(args));                 
 
         // -------------------------------------------------------------  
         // Read-Bibliothek   
@@ -663,25 +672,24 @@ public class MinecraftFunctions implements ISnuviLogger
     }
     
     @Override
-    public void printException(SnuviException ex)
+    public void printException(Exception ex)
     {
         if(KajetansMod.debugMode || KajetansMod.scripts.getSnuviParser().printStack)
         {
-            printConsoleException(ex, null);
+            printConsoleException(ex, null, -1);
         }
-        sendToDevsWithSuffix("§cError in '" + ex.getScriptName() + "'");
-        printGeneralException(ex);
+        printGeneralException(ex, -1);
     }
     
     @Override
-    public void printException(SnuviException ex, Script sc)
+    public void printException(Exception ex, Script sc, int line)
     {
         if(KajetansMod.debugMode || KajetansMod.scripts.getSnuviParser().printStack)
         {
-            printConsoleException(ex, sc);
+            printConsoleException(ex, sc, line);
         }
         sendToDevsWithSuffix("§cError in '" + sc.getName()+ "'");
-        printGeneralException(ex);
+        printGeneralException(ex, line);
     }
     
     @Override
@@ -696,90 +704,24 @@ public class MinecraftFunctions implements ISnuviLogger
         sendWarningToAllDevs(s);
     }
     
-    private void printGeneralException(SnuviException ex)
+    private void printGeneralException(Exception ex, int line)
     {
-        if(ex.getCode() != null)
+        if(line != -1)
         {
-            ArrayList<String> list = ex.getWholeCode();
-            for(int i = 1; i <= list.size(); i++)
-            {
-                sendToDevsWithHelpList("§cZeile " + i + ":", list.get(i - 1));
-            }
-        }
-        if(ex.getLine() != -1)
-        {
-            sendToDevsWithHelpList("§cZeilennummer:", String.valueOf(ex.getLine()));
-        }
-        
-        if(ex.getOriginalException() != null)
-        {
-            Exception another = ex.getOriginalException();
-            if(another.getLocalizedMessage() == null)
-            {
-                sendToDevsWithHelpList("§cFehler:", another.getClass().getSimpleName());
-            }
-            else
-            {
-                sendToDevsWithHelpList("§cFehler:", another.getClass().getSimpleName() + " - " + another.getLocalizedMessage());
-            }
-        }
-        else
-        {
-            sendToDevsWithHelpList("§cFehler:", ex.getClass().getSimpleName());
-            if(ex instanceof PreScriptException)
-            {
-                sendToDevsWithList("§c" + ((PreScriptException) ex).getException());
-                return;
-            }
-        }
-        if(ex instanceof IllegalStringException)
-        {
-            sendToDevsWithHelpList("§cUngültiger Wert:", ((IllegalStringException) ex).getBadString());
+            sendToDevsWithHelpList("§cZeile:", String.valueOf(line));
         }
+        sendToDevsWithHelpList("§cFehler:", ex.getClass().getSimpleName() + " - " + ex.getLocalizedMessage());
     }
     
-    public void printConsoleException(SnuviException ex, Script sc)
+    public void printConsoleException(Exception ex, Script sc, int line)
     {
         Module m = KajetansMod.scripts;
-        m.sendWarningToConsole("Error in '" + (sc == null ? ex.getScriptName() : sc.getName()) + "'");
-        if(ex.getCode() != null)
-        {
-            ArrayList<String> list = ex.getWholeCode();
-            for(int i = 1; i <= list.size(); i++)
-            {
-                m.sendWarningToConsole("Zeile " + i + ": " + list.get(i - 1));
-            }
-        }
-        if(ex.getLine() != -1)
-        {
-            m.sendWarningToConsole("Zeilennummer: " + ex.getLine());
-        }
-        
-        if(ex.getOriginalException() != null)
-        {
-            Exception another = ex.getOriginalException();
-            if(another.getLocalizedMessage() == null)
-            {
-                m.sendWarningToConsole("Fehler: " + another.getClass().getSimpleName());
-            }
-            else
-            {
-                m.sendWarningToConsole("Fehler: " + another.getClass().getSimpleName() + " - " + another.getLocalizedMessage());
-            }
-        }
-        else
+        m.sendWarningToConsole("Error in '" + (sc == null ? "null": sc.getName()) + "'");
+        if(line != -1)
         {
-            m.sendWarningToConsole("Fehler: " + ex.getClass().getSimpleName());
-            if(ex instanceof PreScriptException)
-            {
-                m.sendWarningToConsole(((PreScriptException) ex).getException());
-                return;
-            }
-        }
-        if(ex instanceof IllegalStringException)
-        {
-            m.sendWarningToConsole("Ungültiger Wert: " + ((IllegalStringException) ex).getBadString());
+            m.sendWarningToConsole("Zeilen: " + line);
         }
+        m.sendWarningToConsole("Fehler: " + ex.getClass().getSimpleName() + " - " + ex.getLocalizedMessage());
     }
     
     private static void printTable(Object[] args, Script sc)
@@ -831,16 +773,19 @@ public class MinecraftFunctions implements ISnuviLogger
         }
     }
     
-    private static void respawnPlayer(Object[] args)
+    private static void respawnPlayer(Script sc, Object[] args)
     {
-        try
+        KajetansMod.scheduler.scheduleTask(() ->
         {
-            ((EntityPlayerMP) args[0]).connection.processClientStatus(new CPacketClientStatus(CPacketClientStatus.State.PERFORM_RESPAWN));
-        }
-        catch(ThreadQuickExitException ex)
-        {
-            // Minecraft needs this for canceling and queueing into main thread
-        }
+            try
+            {
+                ((EntityPlayerMP) args[0]).connection.processClientStatus(new CPacketClientStatus(CPacketClientStatus.State.PERFORM_RESPAWN));
+            }
+            catch(ThreadQuickExitException ex)
+            {
+                // Minecraft needs this for canceling and queueing into main thread
+            }
+        });
     }
     
     private static Class getClass(String s)
@@ -855,15 +800,15 @@ public class MinecraftFunctions implements ISnuviLogger
         }
     }
     
-    private static int getItemAmountChest(Object[] args) throws IllegalStringLocationException, IllegalItemStackStringException
+    private static Fraction getItemAmountChest(Object[] args) throws IllegalStringLocationException, IllegalItemStackStringException
     {       
         Location l = (Location) args[0];
         TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
         if(te == null || !(te instanceof TileEntityChest))
         {
-            return 0;
+            return new Fraction(0);
         }        
-        return InventoryUtils.searchInventoryFor(((TileEntityChest) te), (ItemStack) args[2], (boolean) args[1]);
+        return new Fraction(InventoryUtils.searchInventoryFor(((TileEntityChest) te), (ItemStack) args[2], (boolean) args[1]));
     }
     
     private static ItemStack addItemAmountChest(Object[] args) throws IllegalStringLocationException, IllegalItemStackStringException
@@ -898,17 +843,17 @@ public class MinecraftFunctions implements ISnuviLogger
         switch(args[1].toString())
         {
             case "x":
-                return l.getX();
+                return Fraction.fromDouble(l.getX());
             case "y":
-                return l.getY();
+                return Fraction.fromDouble(l.getY());
             case "z":
-                return l.getZ();
+                return Fraction.fromDouble(l.getZ());
             case "bx":
-                return (double) MathHelper.floor(l.getX());
+                return new Fraction(MathHelper.floor(l.getX()));
             case "by":
-                return (double) MathHelper.floor(l.getY());
+                return new Fraction(MathHelper.floor(l.getY()));
             case "bz":
-                return (double) MathHelper.floor(l.getZ());
+                return new Fraction(MathHelper.floor(l.getZ()));
             case "w":
                 return ModDimensions.getWorldName(l.getWorld());
             default:
@@ -1063,6 +1008,19 @@ public class MinecraftFunctions implements ISnuviLogger
         return ItemStack.EMPTY;
     } 
     
+    private static void invClose(Object[] args)
+    {
+        EntityPlayer p = (EntityPlayer) args[0];
+        if(p.openContainer instanceof CustomContainer)
+        {
+            ((CustomContainer) p.openContainer).closeSafe(p);
+        }
+        else
+        {
+            p.closeScreen();
+        }
+    }
+    
     @SuppressWarnings("unchecked")
     private static void removeEntities(Object[] args) throws IllegalStringLocationException
     {
@@ -1280,6 +1238,15 @@ public class MinecraftFunctions implements ISnuviLogger
         return KajetansMod.playerbank.getDataBank().getUUID(o.toString());
     }
     
+    private static Set<Fraction> getPlotIds(Object[] args)
+    {
+        return KajetansMod.plots.getDataBank(ProtectionBank.class).getRegionIds(
+                ((Location) args[1]).getWorld(), 
+                ((Location) args[1]).getBlockPos()).stream()
+                .map(o -> new Fraction(Integer.parseInt(o.toString())))
+                .collect(Collectors.toSet());
+    }
+    
     @SuppressWarnings("")
     private static String getPotionType(Object[] args)
     {
@@ -1296,13 +1263,13 @@ public class MinecraftFunctions implements ISnuviLogger
         KajetansMod.playerbank.getDataBank().setTag(KajetansMod.playerbank.getDataBank().getUUID(args[0].toString()), args[1].toString(), ScriptUtils.getInt(args[2]));
     }
     
-    private static int getTag(Object[] args)
+    private static Fraction getTag(Object[] args)
     {
         if(args[0] instanceof EntityPlayer)
         {
-            return KajetansMod.playerbank.getDataBank().getTag((EntityPlayer) args[0], args[1].toString());
+            return new Fraction(KajetansMod.playerbank.getDataBank().getTag((EntityPlayer) args[0], args[1].toString()));
         }
-        return KajetansMod.playerbank.getDataBank().getTag(KajetansMod.playerbank.getDataBank().getUUID(args[0].toString()), args[1].toString());
+        return new Fraction(KajetansMod.playerbank.getDataBank().getTag(KajetansMod.playerbank.getDataBank().getUUID(args[0].toString()), args[1].toString()));
     }
     
     private static void setGlobalVar(Object[] args)
@@ -1323,15 +1290,34 @@ public class MinecraftFunctions implements ISnuviLogger
         }
         return KajetansMod.scripts.getDataBank(ScriptBank.class).getVar(args[1].toString(), KajetansMod.playerbank.getDataBank().getUUID(args[0].toString()));
     }
-
+    
+    // -------------------------------------------------------------------------    
+    // Potion
+    // -------------------------------------------------------------------------
+    
+    private static void addEffect(Object[] args)
+    {
+        EntityLivingBase base = (EntityLivingBase) args[0];
+        Potion potion = Potion.getPotionFromResourceLocation(args[1].toString());
+        if(base == null) // doing this only to prevent EffectUtils.addPotionTo doing shit
+        {
+            throw new NullPointerException("null not allowed for entity");
+        }
+        else if(potion == null)
+        {
+            throw new NullPointerException("potion does not exist");
+        }
+        EffectUtils.addPotionTo(base, potion, ScriptUtils.getInt(args[2]), ScriptUtils.getInt(args[3]));
+    }
+    
     // -------------------------------------------------------------------------    
     // Block
     // ------------------------------------------------------------------------- 
     
-    private static int getBlockData(Location l)
+    private static Fraction getBlockData(Location l)
     {
         IBlockState state = l.getWorld().getBlockState(l.getBlockPos());
-        return state.getBlock().getMetaFromState(state);
+        return new Fraction(state.getBlock().getMetaFromState(state));
     }
     
     private static IBlockState getBlockState(Location l)

+ 3 - 3
src/main/java/me/km/snuviscript/ScriptBank.java

@@ -88,7 +88,7 @@ public class ScriptBank extends SimpleDataBank
 
     public Object getVar(String var, String uuid)
     {
-        return Code.convertInput(this.getFirst("SELECT value from questdata "
+        return Code.convertInput(null, this.getFirst("SELECT value from questdata "
                 + "LEFT JOIN players ON players.id = questdata.player_id "
                 + "WHERE players.uuid = '" + uuid + "' AND "
                 + "questdata.var='" + var + "';", String.class), false);
@@ -120,7 +120,7 @@ public class ScriptBank extends SimpleDataBank
 
     public Object getMapValue(String map, String key)
     {
-        return Code.convertInput(this.getFirst("SELECT value from questmaps "
+        return Code.convertInput(null, this.getFirst("SELECT value from questmaps "
                 + "WHERE map = '" + map + "' AND "
                 + "keyname='" + key + "';", String.class), false);
     }  
@@ -152,7 +152,7 @@ public class ScriptBank extends SimpleDataBank
 
     public Object getDualMapValue(String map, String key, String key2)
     {
-        return Code.convertInput(this.getFirst("SELECT value from questdualmaps "
+        return Code.convertInput(null, this.getFirst("SELECT value from questdualmaps "
                 + "WHERE map = '" + map + "' AND "
                 + "keyname = '" + key + "' AND "
                 + "seckeyname='" + key2 + "';", String.class), false);

+ 29 - 35
src/main/java/me/km/snuviscript/ScriptEvents.java

@@ -11,7 +11,7 @@ import me.hammerle.code.Code;
 import me.hammerle.code.Script;
 import me.hammerle.code.ScriptUtils;
 import me.hammerle.code.SnuviParser;
-import me.hammerle.exceptions.SnuviException;
+import me.hammerle.math.Fraction;
 import me.km.KajetansMod;
 import me.km.api.Location;
 import me.km.api.ModuleListener;
@@ -19,6 +19,7 @@ import me.km.api.Module;
 import me.km.api.Utils;
 import me.km.dimensions.ModDimensions;
 import me.km.effects.PlayerUsesEffectEvent;
+import me.km.entities.EntityItemProjectile;
 import me.km.events.PlayerHurtEvent;
 import me.km.events.PlayerJoinMessageEvent;
 import me.km.events.PlayerLeaveMessageEvent;
@@ -26,9 +27,7 @@ import me.km.events.PlayerMoveEvent;
 import me.km.events.PlayerRespawnAtEvent;
 import net.minecraft.entity.Entity;
 import net.minecraft.entity.EntityLivingBase;
-import net.minecraft.entity.item.EntityItem;
 import net.minecraft.entity.passive.EntitySheep;
-import net.minecraft.entity.passive.EntityVillager;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.init.Items;
 import net.minecraft.inventory.ClickType;
@@ -141,20 +140,16 @@ public class ScriptEvents extends ModuleListener
         EntityPlayer p = e.getEntityPlayer();
         Location l = new Location(p);
         l.round();
-        parser.getScripts().stream().filter(sc -> sc.isLoadedEvent("player_move")).forEach(sc -> 
+        parser.callEvent("player_move", (sc) -> ScriptVars.setPlayerVars(sc, p), null, 
+                sc -> ((MinecraftScript) sc).removeLocation(l));
+      
+        PlayerScript data = KajetansMod.scripts.getScript(p);
+        if(data != null)
         {
-            if(((MinecraftScript) sc).removeLocation(l))
+            parser.callEvent("player_move", data, (sc) -> 
             {
-                ScriptVars.setPlayerVars(sc, p);   
-                parser.callEvent("player_move", sc, null, null);
-            }
-        });
-
-        PlayerScript sc = KajetansMod.scripts.getScript(p);
-        if(sc != null && sc.isLoadedEvent("player_move") && sc.removeLocation(l))
-        {
-            ScriptVars.setPlayerVars(sc, p); 
-            parser.callEvent("player_move", sc, null, null);
+                ScriptVars.setPlayerVars(sc, p); 
+            }, null, data.removeLocation(l));
         }
     } 
     
@@ -163,25 +158,23 @@ public class ScriptEvents extends ModuleListener
         parser.callEvent("inv_click", qd, sc -> 
         {
             ScriptVars.setPlayerVars(qd, p); 
-            qd.setEventVar("inv_id", (double) inv.getId());
+            qd.setEventVar("inv_id", new Fraction(inv.getId()));
             qd.setEventVar("inv_name", inv.getName());
-            qd.setEventVar("inv_slot", (double) slot);
+            qd.setEventVar("inv_slot", new Fraction(slot));
             ScriptVars.setItemVars(qd, inv.getStackInSlot(slot));
             qd.setVar("cancel", false); 
         }, null);
         return qd.getBooleanVar("cancel");
     }
 
-    public boolean QuestCloseInventory(Script qd, SnuviInventory inv, EntityPlayer p)
+    public void QuestCloseInventory(Script qd, SnuviInventory inv, EntityPlayer p)
     {
         parser.callEvent("inv_close", qd, sc -> 
         {
             ScriptVars.setPlayerVars(qd, p); 
-            qd.setEventVar("inv_id", (double) inv.getId());
+            qd.setEventVar("inv_id", new Fraction(inv.getId()));
             qd.setEventVar("inv_name", inv.getName());
-            qd.setVar("cancel", false); 
         }, null);
-        return qd.getBooleanVar("cancel");
     }
     
     @SubscribeEvent
@@ -202,7 +195,7 @@ public class ScriptEvents extends ModuleListener
             } 
             catch(ClassCastException | NullPointerException ex) 
             {
-                KajetansMod.scripts.logger.printException(new SnuviException(ex, qd.getName(), "(respawn_loc)"));
+                KajetansMod.scripts.logger.printException(ex, qd, qd.getActiveRealCodeLine());
             }
         });
     }
@@ -221,7 +214,7 @@ public class ScriptEvents extends ModuleListener
             {
                 qd.setEventVar("player_killed", false); 
             }
-            qd.setEventVar("player_damage", (double) e.getAmount());   
+            qd.setEventVar("player_damage", Fraction.fromDouble(e.getAmount()));   
             qd.setEventVar("player_damage_cause", e.getSource().getDamageType());
             EntityPlayer ent = Utils.getDamager(e.getSource());
             if(ent != null)
@@ -300,7 +293,7 @@ public class ScriptEvents extends ModuleListener
         {
             qd.setEventVar("entity_killed", e.getEntityLiving().getHealth() <= e.getAmount());        
             ScriptVars.setEntityVars(qd, e.getEntity()); 
-            qd.setEventVar("entity_damage", (double) e.getAmount());   
+            qd.setEventVar("entity_damage", Fraction.fromDouble(e.getAmount()));   
             qd.setEventVar("entity_damage_cause", e.getSource().getDamageType());
             qd.setVar("cancel", e.isCanceled());   
         }, (qd) -> 
@@ -374,10 +367,11 @@ public class ScriptEvents extends ModuleListener
         }           
     }
     
-    public void onEntityItemProjectileHit(EntityPlayer p, ItemStack stack, List<Entity> ents)
+    public void onEntityItemProjectileHit(EntityItemProjectile ent, EntityPlayer p, ItemStack stack, List<Entity> ents)
     {        
         handleEvent(p, "item_hit", (qd) -> 
         {
+            ScriptVars.setEntityVars(qd, ent);
             ScriptVars.setItemVars(qd, stack);
             qd.setEventVar("entities", ents);
         });      
@@ -610,7 +604,7 @@ public class ScriptEvents extends ModuleListener
         }
         handleEvent((EntityPlayer) e.getEntityLiving(), "item_use_start", (qd) -> 
         {
-            qd.setEventVar("duration", (double) e.getDuration());
+            qd.setEventVar("duration", new Fraction(e.getDuration()));
             qd.setVar("cancel", e.isCanceled());  
         }, (qd) -> 
         {
@@ -621,7 +615,7 @@ public class ScriptEvents extends ModuleListener
             }
             catch(Exception ex)
             {
-                KajetansMod.scripts.logger.printException(new SnuviException(ex, qd.getName(), "(duration)"));
+                KajetansMod.scripts.logger.printException(ex, qd, qd.getActiveRealCodeLine());
             }
         });
     }
@@ -711,7 +705,7 @@ public class ScriptEvents extends ModuleListener
             handleEvent((EntityPlayer) e.getSender(), "command", (qd) -> 
             {
                 qd.setEventVar("command", e.getCommand().getName()); 
-                qd.setEventVar("args", Arrays.stream(e.getParameters()).map(s -> Code.convertInput(s, false)).collect(Collectors.toList()));
+                qd.setEventVar("args", Arrays.stream(e.getParameters()).map(s -> Code.convertInput(null, s, false)).collect(Collectors.toList()));
                 qd.setVar("cancel", e.isCanceled()); 
             }, (qd) -> 
             {
@@ -730,7 +724,7 @@ public class ScriptEvents extends ModuleListener
                 qd.setEventVar("args", new ArrayList<>());
                 return;
             }
-            qd.setEventVar("args", Arrays.stream(args.trim().split(" ")).map(s -> Code.convertInput(s, false)).collect(Collectors.toList()));
+            qd.setEventVar("args", Arrays.stream(args.trim().split(" ")).map(s -> Code.convertInput(null, s, false)).collect(Collectors.toList()));
         });
     }
       
@@ -738,8 +732,8 @@ public class ScriptEvents extends ModuleListener
     {    
         handleEvent(e.getPlayer(), "player_use_effect", (qd) -> 
         {       
-            qd.setEventVar("power", (double) e.getPower());
-            qd.setEventVar("mana_cost", (double) e.getMana());
+            qd.setEventVar("power", new Fraction(e.getPower()));
+            qd.setEventVar("mana_cost", new Fraction(e.getMana()));
             qd.setEventVar("cause", e.getCause().toString());
             qd.setEventVar("effect", e.getEffect());
             qd.setVar("cancel", e.isCanceled());
@@ -756,7 +750,7 @@ public class ScriptEvents extends ModuleListener
             }
             catch(Exception ex)
             {
-                KajetansMod.scripts.logger.printException(new SnuviException(ex, qd.getName(), "(power)"));
+                KajetansMod.scripts.logger.printException(ex, qd, qd.getActiveRealCodeLine());
             }
             try
             {
@@ -769,13 +763,13 @@ public class ScriptEvents extends ModuleListener
             }
             catch(Exception ex)
             {  
-                KajetansMod.scripts.logger.printException(new SnuviException(ex, qd.getName(), "(mana_cost)"));
+                KajetansMod.scripts.logger.printException(ex, qd, qd.getActiveRealCodeLine());
             }
             e.setCanceled(qd.getBooleanVar("cancel")); 
         });
     }
     
-    @SubscribeEvent
+    /*@SubscribeEvent
     public void QuestVillagerPickUpItem(ItemTossEvent e)
     {             
         EntityPlayer p = e.getPlayer();  
@@ -814,5 +808,5 @@ public class ScriptEvents extends ModuleListener
             }                  
             itemEnt.setDead();                
         }, 40);                    
-    }
+    }*/
 }

+ 2 - 4
src/main/java/me/km/snuviscript/ScriptInventoryHolder.java

@@ -29,9 +29,7 @@ public class ScriptInventoryHolder extends CustomContainer
     @Override
     public void onContainerClosed(EntityPlayer p) 
     {
-        if(!e.QuestCloseInventory(qd, inv, p))
-        {
-            super.onContainerClosed(p);
-        }
+        e.QuestCloseInventory(qd, inv, p);
+        super.onContainerClosed(p);
     }
 }

+ 4 - 3
src/main/java/me/km/snuviscript/ScriptVars.java

@@ -1,6 +1,7 @@
 package me.km.snuviscript;
 
 import me.hammerle.code.Script;
+import me.hammerle.math.Fraction;
 import me.km.api.Location;
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.entity.Entity;
@@ -17,13 +18,13 @@ public class ScriptVars
         IBlockState state = w.getBlockState(pos);
         qd.setEventVar("block_loc", new Location(w, pos));
         qd.setEventVar("block_type", state.getBlock().getRegistryName().toString());
-        qd.setEventVar("block_data", (double) state.getBlock().getMetaFromState(state));
+        qd.setEventVar("block_data", new Fraction(state.getBlock().getMetaFromState(state)));
     }
     
     public static void setPlayerVars(Script qd, EntityPlayer p)
     {
-        qd.setEventVar("player", p);
-        qd.setEventVar("player_name", p.getName());
+        qd.setVar("player", p);
+        qd.setVar("player_name", p.getName());
     }
     
     public static void setSecPlayer(Script qd, EntityPlayer p)

+ 6 - 1
src/main/java/me/km/utils/ReflectionUtils.java

@@ -231,7 +231,12 @@ public class ReflectionUtils
     
     public static int getAge(EntityItem item)
     {
-        return getInt(item, UUID_TO_PLAYER_MAP, 0);
+        return getInt(item, ENTITY_ITEM_AGE, 0);
+    }
+    
+    public static void setAge(EntityItem item, int age)
+    {
+        setInt(item, ENTITY_ITEM_AGE, age);
     }
     
     private final static Field BLOCK_MATERIAL = getField(Block.class, "field_149764_J", "blockMaterial");