Browse Source

wip, ported all snuvi commands except humans, most snuvi events done

Kajetan Johannes Hammerle 3 years ago
parent
commit
20a15b44d4

+ 1 - 1
build.xml

@@ -8,7 +8,7 @@
         <javac includeantruntime="false" srcdir="src" destdir="build/classes">
             <classpath>
                 <fileset dir="lib">
-                    <include name="patched_1.17.1.jar"/>
+                    <include name="Paper-Server-reobf.jar"/>
                     <include name="SnuviScriptRecoded.jar"/>
                 </fileset>
             </classpath>

+ 180 - 3
src/me/hammerle/kp/Events.java

@@ -1,20 +1,61 @@
 package me.hammerle.kp;
 
 import org.bukkit.event.Listener;
-import org.bukkit.event.player.PlayerCommandPreprocessEvent;
-import org.bukkit.event.player.PlayerCommandSendEvent;
-import org.bukkit.event.player.PlayerLoginEvent;
+import org.bukkit.event.block.*;
+import org.bukkit.event.entity.*;
+import org.bukkit.event.inventory.*;
+import org.bukkit.event.player.*;
 import org.bukkit.event.server.ServerCommandEvent;
+import org.spigotmc.event.entity.EntityMountEvent;
+import io.papermc.paper.event.player.PlayerArmSwingEvent;
 import me.hammerle.kp.snuviscript.CommandManager;
 import me.hammerle.kp.snuviscript.MoveEvents;
+import me.hammerle.kp.snuviscript.ScriptEvents;
+import org.bukkit.Bukkit;
 import org.bukkit.entity.Player;
 import org.bukkit.event.EventHandler;
+import com.destroystokyo.paper.event.player.PlayerPostRespawnEvent;
 import com.destroystokyo.paper.event.server.ServerTickEndEvent;
 
 public class Events implements Listener {
+    private long lastMillis = 0;
+    private int lastSlot = -1;
+    private Player p;
+
+    @EventHandler
+    public void test(PlayerItemHeldEvent e) {
+        long diff = System.currentTimeMillis() - lastMillis;
+        if(diff < 300) {
+            KajetansPlugin.log("CAST " + e.getNewSlot());
+            lastMillis = 0;
+            e.getPlayer().getInventory().setHeldItemSlot(lastSlot);
+        }
+    }
+
+    @EventHandler
+    public void test2(PlayerSwapHandItemsEvent e) {
+        e.setCancelled(true);
+        lastSlot = e.getPlayer().getInventory().getHeldItemSlot();
+        e.getPlayer().getInventory().setHeldItemSlot(8);
+        lastMillis = System.currentTimeMillis();
+        p = e.getPlayer();
+    }
+
     @EventHandler
     public void onServerTick(ServerTickEndEvent e) {
         MoveEvents.tick();
+        for(Player p : Bukkit.getOnlinePlayers()) {
+            PlayerData.get(p).tick(p);
+        }
+
+        if(lastMillis != 0) {
+            long diff = System.currentTimeMillis() - lastMillis;
+            if(diff >= 500) {
+                KajetansPlugin.log("SWAP");
+                p.getInventory().setHeldItemSlot(lastSlot);
+                lastMillis = 0;
+            }
+        }
     }
 
     @EventHandler
@@ -34,6 +75,17 @@ public class Events implements Listener {
         Player p = e.getPlayer();
         CommandManager.clearPermissions(p);
         KajetansPlugin.scheduleTask(() -> PlayerData.get(p).login(p));
+        ScriptEvents.onPlayerLogin(e);
+    }
+
+    @EventHandler
+    public void onPlayerJoin(PlayerJoinEvent e) {
+        ScriptEvents.onPlayerJoin(e);
+    }
+
+    @EventHandler
+    public void onPlayerQuit(PlayerQuitEvent e) {
+        ScriptEvents.onPlayerQuit(e);
     }
 
     @EventHandler
@@ -43,4 +95,129 @@ public class Events implements Listener {
             CommandManager.send(e.getPlayer());
         });
     }
+
+    @EventHandler
+    public void onInventoryClick(InventoryClickEvent e) {
+        ScriptEvents.onInventoryClick(e);
+    }
+
+    @EventHandler
+    public void onInventoryClose(InventoryCloseEvent e) {
+        ScriptEvents.onInventoryClose(e);
+    }
+
+    @EventHandler
+    public void onToggleGlide(EntityToggleGlideEvent e) {
+        ScriptEvents.onGlideToggle(e);
+    }
+
+    @EventHandler
+    public void onPlayerRespawn(PlayerRespawnEvent e) {
+        ScriptEvents.onPlayerPreRespawn(e);
+    }
+
+    @EventHandler
+    public void onPlayerPostRespawn(PlayerPostRespawnEvent e) {
+        ScriptEvents.onPlayerPostRespawn(e);
+    }
+
+    @EventHandler
+    public void onEntityDamage(EntityDamageEvent e) {
+        ScriptEvents.onEntityDamage(e);
+    }
+
+    @EventHandler
+    public void onEntityRegainHealth(EntityRegainHealthEvent e) {
+        ScriptEvents.onEntityRegainHealth(e);
+    }
+
+    @EventHandler
+    public void onEntityDeath(EntityDeathEvent e) {
+        ScriptEvents.onEntityDeath(e);
+    }
+
+    @EventHandler
+    public void onProjectileHit(ProjectileHitEvent e) {
+        ScriptEvents.onProjectileHit(e);
+    }
+
+    @EventHandler
+    public void onBlockDropItemEvent(BlockDropItemEvent e) {
+        ScriptEvents.onBlockDropItemEvent(e);
+    }
+
+    @EventHandler
+    public void onBlockPlace(BlockPlaceEvent e) {
+        ScriptEvents.onBlockPlace(e);
+    }
+
+    @EventHandler
+    public void onBlockBreak(BlockBreakEvent e) {
+        ScriptEvents.onBlockBreak(e);
+    }
+
+    @EventHandler
+    public void onPlayerBucketFill(PlayerBucketFillEvent e) {
+        ScriptEvents.onPlayerBucket(e);
+    }
+
+    @EventHandler
+    public void onPlayerBucketEmpty(PlayerBucketEmptyEvent e) {
+        ScriptEvents.onPlayerBucket(e);
+    }
+
+    @EventHandler
+    public void onPlayerInteract(PlayerInteractEvent e) {
+        ScriptEvents.onPlayerInteract(e);
+    }
+
+    @EventHandler
+    public void onPlayerInteractEntity(PlayerInteractEntityEvent e) {
+        ScriptEvents.onPlayerInteractEntity(e);
+    }
+
+    @EventHandler
+    public void onPlayerArmSwing(PlayerArmSwingEvent e) {
+        ScriptEvents.onPlayerArmSwing(e);
+    }
+
+    @EventHandler
+    public void onPlayerItemConsume(PlayerItemConsumeEvent e) {
+        ScriptEvents.onPlayerItemConsume(e);
+    }
+
+    @EventHandler
+    public void onPlayerFish(PlayerFishEvent e) {
+        ScriptEvents.onPlayerFish(e);
+    }
+
+    @EventHandler
+    public void onCraftItem(CraftItemEvent e) {
+        ScriptEvents.onCraftItem(e);
+    }
+
+    @EventHandler
+    public void onPrepareItemCraft(PrepareItemCraftEvent e) {
+        ScriptEvents.onPrepareItemCraft(e);
+    }
+
+    @EventHandler
+    public void onPlayerDropItem(PlayerDropItemEvent e) {
+        ScriptEvents.onPlayerDropItem(e);
+    }
+
+    @EventHandler
+    public void onEntityPickupItem(EntityPickupItemEvent e) {
+        ScriptEvents.onEntityPickupItem(e);
+    }
+
+    @EventHandler
+    public void onEntityMount(EntityMountEvent e) {
+        ScriptEvents.onEntityMount(e);
+    }
+
+    @EventHandler
+    public void onPlayerChangedWorl(PlayerChangedWorldEvent e) {
+        ScriptEvents.onPlayerChangedWorl(e);
+    }
 }

+ 3 - 3
src/me/hammerle/kp/KajetansPlugin.java

@@ -106,12 +106,12 @@ public class KajetansPlugin extends JavaPlugin implements ISnuviScheduler {
         ScoreboardCommands.registerFunctions();
         ParticleCommands.registerFunctions();
         SoundCommands.registerFunctions();
-        //InventoryCommands.registerFunctions(sm);
-        //DataCommands.registerFunctions(sm, scheduler);
+        InventoryCommands.registerFunctions();
+        DataCommands.registerFunctions();
         ReadCommands.registerFunctions();
         TextCommands.registerFunctions();
         BanCommands.registerFunctions();
-        //ShopCommands.registerFunctions(sm);
+        ShopCommands.registerFunctions();
         ErrorCommands.registerFunctions();
         EnchantmentCommands.registerFunctions();
         ItemEntityCommands.registerFunctions();

+ 18 - 22
src/me/hammerle/kp/NMS.java

@@ -16,6 +16,7 @@ import org.bukkit.craftbukkit.v1_17_R1.entity.CraftFirework;
 import org.bukkit.craftbukkit.v1_17_R1.entity.CraftItem;
 import org.bukkit.craftbukkit.v1_17_R1.entity.CraftLargeFireball;
 import org.bukkit.craftbukkit.v1_17_R1.entity.CraftWitherSkull;
+import org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory;
 import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
 import org.bukkit.entity.Entity;
 import org.bukkit.entity.LargeFireball;
@@ -41,6 +42,10 @@ import net.minecraft.world.entity.projectile.EntityWitherSkull;
 public class NMS {
     private final static HashMap<String, DamageSource> DAMAGE_SOURCES = new HashMap<>();
 
+    public static DamageSource getCurrentDamageSource() {
+        return CraftEventFactory.currentDamageCause;
+    }
+
     public static EntityPlayer map(Player p) {
         return ((CraftPlayer) p).getHandle();
     }
@@ -170,14 +175,9 @@ public class NMS {
         return c.toString();
     }
 
-    public static ItemStack parseItemStack(String stack) {
-        try {
-            NBTTagCompound c = MojangsonParser.parse(stack);
-            return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.a(c));
-        } catch(Exception ex) {
-            ex.printStackTrace();
-        }
-        return null;
+    public static ItemStack parseItemStack(String stack) throws Exception {
+        NBTTagCompound c = MojangsonParser.parse(stack);
+        return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.a(c));
     }
 
     public static String toString(Entity ent) {
@@ -186,20 +186,16 @@ public class NMS {
         return c.toString();
     }
 
-    public static Entity parseEntity(String stack, Location l) {
-        try {
-            NBTTagCompound c = MojangsonParser.parse(stack);
-            var nmsWorld = map(l.getWorld());
-            net.minecraft.world.entity.Entity ent =
-                    net.minecraft.world.entity.EntityTypes.a(c, nmsWorld, e -> {
-                        e.a_(UUID.randomUUID());
-                        e.setLocation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch());
-                        return nmsWorld.addEntity(e) ? e : null;
-                    });
-            return map(ent);
-        } catch(Exception ex) {
-        }
-        return null;
+    public static Entity parseEntity(String stack, Location l) throws Exception {
+        NBTTagCompound c = MojangsonParser.parse(stack);
+        var nmsWorld = map(l.getWorld());
+        net.minecraft.world.entity.Entity ent =
+                net.minecraft.world.entity.EntityTypes.a(c, nmsWorld, e -> {
+                    e.a_(UUID.randomUUID());
+                    e.setLocation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch());
+                    return nmsWorld.addEntity(e) ? e : null;
+                });
+        return map(ent);
     }
 
     private static BlockPosition convert(Location l) {

+ 49 - 1
src/me/hammerle/kp/PlayerData.java

@@ -1,6 +1,8 @@
 package me.hammerle.kp;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
 import org.bukkit.Bukkit;
 import org.bukkit.entity.Player;
 import org.bukkit.metadata.FixedMetadataValue;
@@ -10,6 +12,7 @@ import org.bukkit.scoreboard.Objective;
 import org.bukkit.scoreboard.RenderType;
 import org.bukkit.scoreboard.Score;
 import org.bukkit.scoreboard.Scoreboard;
+import me.hammerle.kp.snuviscript.ScriptEvents;
 import net.kyori.adventure.text.Component;
 
 public class PlayerData {
@@ -18,6 +21,8 @@ public class PlayerData {
 
     private Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
     private Objective objective;
+    private HashMap<String, Object> data = new HashMap<>();
+    private ConcurrentHashMap<String, Integer> timers = new ConcurrentHashMap<>();
 
     private PlayerData(Player p) {
         objective = scoreboard.registerNewObjective("kajetansplugin", "dummy",
@@ -62,7 +67,7 @@ public class PlayerData {
         }
     }
 
-    public void clear() {
+    public void clearTexts() {
         for(String name : scoreboard.getEntries()) {
             objective.getScore(name).resetScore();
         }
@@ -76,6 +81,49 @@ public class PlayerData {
         objective.getScore(text).resetScore();
     }
 
+    public void setData(String name, Object o) {
+        if(o == null) {
+            data.remove(name);
+            return;
+        }
+        data.put(name, o);
+    }
+
+    public Object getData(String name) {
+        return data.get(name);
+    }
+
+    public void setTimer(String name, int time) {
+        if(time <= 0) {
+            timers.remove(name);
+            return;
+        }
+        timers.put(name, time);
+    }
+
+    public int getTimer(String name) {
+        return timers.getOrDefault(name, -1);
+    }
+
+    public void clearData() {
+        data.clear();
+        timers.clear();
+    }
+
+    public void tick(Player p) {
+        timers.entrySet().removeIf(entry -> {
+            int time = entry.getValue() - 1;
+            if(time <= 0) {
+                if(time == 0) {
+                    ScriptEvents.onPlayerDataTick(p, entry.getKey());
+                }
+                return true;
+            }
+            entry.setValue(time);
+            return false;
+        });
+    }
+
     public static PlayerData get(Player p) {
         List<MetadataValue> list = p.getMetadata(TAG);
         if(list == null || list.isEmpty()) {

+ 0 - 164
src/me/hammerle/kp/overrides/ModEntityPlayerMP.java

@@ -1,164 +0,0 @@
-/*package me.km.overrides;
-
-import com.mojang.authlib.GameProfile;
-import java.util.HashMap;
-import me.hammerle.snuviscript.code.ISnuviScheduler;
-import me.km.Server;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.entity.player.ServerPlayerEntity;
-import net.minecraft.network.play.server.SPlayerListItemPacket;
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.server.management.PlayerInteractionManager;
-import net.minecraft.util.text.ITextComponent;
-import net.minecraft.util.text.StringTextComponent;
-import net.minecraft.world.GameRules;
-import net.minecraft.world.server.ServerWorld;
-
-public class ModEntityPlayerMP extends ServerPlayerEntity {
-
-    private final PlayerScoreboard board;
-    private int id = -1;
-    private final HashMap<String, Integer> timedData;
-    private final HashMap<String, Object> data;
-    private StringTextComponent tabDisplayName = null;
-    private boolean elytra = false;
-
-    private boolean isIterating = false;
-
-    public ModEntityPlayerMP(MinecraftServer ms, ServerWorld w, GameProfile gp,
-            PlayerInteractionManager pim) {
-        super(ms, w, gp, pim);
-        this.board = new PlayerScoreboard();
-        this.timedData = new HashMap<>();
-        this.data = new HashMap<>();
-    }
-
-    public PlayerScoreboard getScoreboard() {
-        return board;
-    }
-
-    public ModEntityPlayerMP(MinecraftServer ms, ServerWorld w, GameProfile gp,
-            PlayerInteractionManager pim, ModEntityPlayerMP old) {
-        super(ms, w, gp, pim);
-        this.board = old.board;
-        this.timedData = old.timedData;
-        this.data = old.data;
-        this.id = old.id;
-    }
-
-    @Override
-    public void tick() {
-        super.tick();
-        board.update(this);
-        tickData();
-        if(ticksElytraFlying == 1) {
-            elytra = true;
-            Server.scriptEvents.onPlayerStartElytra(this);
-        }
-        if(ticksElytraFlying == 0 && elytra) {
-            elytra = false;
-            Server.scriptEvents.onPlayerStopElytra(this);
-        }
-    }
-
-    public void setTabListDisplayName(String name, ISnuviScheduler scheduler) {
-        tabDisplayName = new StringTextComponent(name);
-        scheduler.scheduleTask("setTabListDisplayName", () -> {
-            server.getPlayerList().sendPacketToAllPlayers(new SPlayerListItemPacket(
-                    SPlayerListItemPacket.Action.UPDATE_DISPLAY_NAME, this));
-        }, 5);
-    }
-
-    @Override
-    public ITextComponent getTabListDisplayName() {
-        return tabDisplayName;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    private void tickData() {
-        isIterating = true;
-        timedData.entrySet().removeIf(entry -> {
-            int time = entry.getValue() - 1;
-            if(time <= 0) {
-                if(time == 0) {
-                    Server.scriptEvents.onPlayerDataTick(this, entry.getKey());
-                }
-                return true;
-            }
-            entry.setValue(time);
-            return false;
-        });
-        isIterating = false;
-    }
-
-    public void setVar(String varname, Object value) {
-        data.put(varname, value);
-    }
-
-    public Object getVar(String varname) {
-        return data.get(varname);
-    }
-
-    public void setTimer(String varname, int time, ISnuviScheduler scheduler) {
-        if(isIterating) {
-            scheduler.scheduleTask("setTimer", () -> timedData.put(varname, time));
-        } else {
-            timedData.put(varname, time);
-        }
-    }
-
-    public int getTimer(String varname) {
-        return timedData.getOrDefault(varname, -1);
-    }
-
-    public void clearData(ISnuviScheduler scheduler) {
-        if(isIterating) {
-            scheduler.scheduleTask("clearData", () -> timedData.clear());
-        } else {
-            timedData.clear();
-        }
-        data.clear();
-    }
-
-    @Override
-    protected int getPermissionLevel() {
-        return 999;
-    }
-
-    @Override
-    public void setSneaking(boolean keyDownIn) {
-        Server.scriptEvents.onSneak(attackingPlayer, keyDownIn);
-        super.setSneaking(keyDownIn);
-    }
-
-    @Override
-    protected int getExperiencePoints(PlayerEntity player) {
-        if(!this.world.getGameRules().getBoolean(GameRules.KEEP_INVENTORY) && !this.isSpectator()) {
-            int level = experienceLevel;
-            int total = 0;
-            if(level >= 32) {
-                level -= 31;
-                total += level * 112 + 9 * (level + 1) * level / 2;
-                level = 31;
-            }
-            if(level >= 17) {
-                level -= 16;
-                total += level * 37 + 5 * (level + 1) * level / 2;
-                level = 16;
-            }
-            total += level * 7 + 2 * level * (level - 1) / 2;
-            total += Math.round(experience * xpBarCap());
-            return total;
-        } else {
-            return 0;
-        }
-    }
-}
-*/

+ 0 - 89
src/me/hammerle/kp/overrides/PlayerScoreboard.java

@@ -1,89 +0,0 @@
-/*package me.km.overrides;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import net.minecraft.entity.player.ServerPlayerEntity;
-import net.minecraft.network.play.server.SDisplayObjectivePacket;
-import net.minecraft.network.play.server.SScoreboardObjectivePacket;
-import net.minecraft.network.play.server.SUpdateScorePacket;
-import net.minecraft.scoreboard.ScoreCriteria;
-import net.minecraft.scoreboard.ScoreCriteria.RenderType;
-import net.minecraft.scoreboard.ScoreObjective;
-import net.minecraft.scoreboard.Scoreboard;
-import net.minecraft.scoreboard.ServerScoreboard.Action;
-import net.minecraft.util.text.StringTextComponent;
-
-public class PlayerScoreboard {
-    private final HashMap<Integer, String> elements = new HashMap<>();
-    private final HashSet<Integer> toRemove = new HashSet<>();
-    private final HashMap<Integer, String> toAdd = new HashMap<>();
-
-    private final Scoreboard board = new Scoreboard();
-    private final ScoreObjective o;
-    private boolean changeNeeded = true;
-
-    private boolean init = true;
-
-    public PlayerScoreboard() {
-        o = new ScoreObjective(board, "ScoreBoardAPI", ScoreCriteria.DUMMY, new StringTextComponent("§6---------------"), RenderType.INTEGER);
-    }
-
-    public void addText(int id, String text) {
-        String s = elements.get(id);
-        if(s != null && !s.equals(text)) {
-            toRemove.add(id);
-            toAdd.put(id, text);
-            changeNeeded = true;
-        } else if(s == null) {
-            toAdd.put(id, text);
-            changeNeeded = true;
-        }
-    }
-
-    public void removeText(int id) {
-        if(elements.containsKey(id)) {
-            toRemove.add(id);
-            changeNeeded = true;
-        }
-    }
-
-    public void clear(ServerPlayerEntity p) {
-        elements.keySet().forEach(i -> toRemove.add(i));
-        changeNeeded = true;
-        update(p);
-    }
-
-    public boolean update(ServerPlayerEntity p) {
-        if(!changeNeeded) {
-            return false;
-        }
-        if(init) {
-            init = false;
-            p.connection.sendPacket(new SScoreboardObjectivePacket(o, 0));
-        }
-
-        if(!toRemove.isEmpty()) {
-            toRemove.forEach(i -> {
-                String s = elements.remove(i);
-                if(s != null) {
-                    p.connection.sendPacket(new SUpdateScorePacket(Action.REMOVE, o.getName(), s, -1));
-                }
-            });
-            toRemove.clear();
-        }
-
-        if(!toAdd.isEmpty()) {
-            toAdd.entrySet().stream().forEach((e) -> {
-                elements.put(e.getKey(), e.getValue());
-                p.connection.sendPacket(new SUpdateScorePacket(Action.CHANGE, o.getName(), e.getValue(), e.getKey()));
-            });
-            toAdd.clear();
-        }
-
-        changeNeeded = false;
-        // displaying objective in sidebar
-        p.connection.sendPacket(new SDisplayObjectivePacket(1, o));
-        return false;
-    }
-}
-*/

+ 0 - 100
src/me/hammerle/kp/snuviscript/FakeMerchant.java

@@ -1,100 +0,0 @@
-/*package me.km.snuviscript;
-
-import me.km.entities.ModEntities;
-import net.minecraft.entity.Entity;
-import net.minecraft.entity.merchant.IMerchant;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.MerchantOffer;
-import net.minecraft.item.MerchantOffers;
-import net.minecraft.nbt.CompoundNBT;
-import net.minecraft.network.IPacket;
-import net.minecraft.util.SoundEvent;
-import net.minecraft.util.SoundEvents;
-import net.minecraft.world.World;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.api.distmarker.OnlyIn;
-
-public class FakeMerchant extends Entity implements IMerchant {
-    private PlayerEntity customer = null;
-    private final MerchantOffers offers = new MerchantOffers();
-
-    public FakeMerchant() {
-        super(ModEntities.NOBODY, null);
-    }
-
-    @Override
-    public PlayerEntity getCustomer() {
-        return this.customer;
-    }
-
-    @Override
-    public void setCustomer(PlayerEntity p) {
-        if (p != null) {
-            world = p.world;
-            setPosition(p.getPosX(), p.getPosY(), p.getPosZ());
-        }
-        this.customer = p;
-    }
-
-    @Override
-    public MerchantOffers getOffers() {
-        return this.offers;
-    }
-
-    @OnlyIn(Dist.CLIENT)
-    @Override
-    public void setClientSideOffers(MerchantOffers offers) {
-    }
-
-    @Override
-    public void onTrade(MerchantOffer offer) {
-        offer.increaseUses();
-    }
-
-    @Override
-    public void verifySellingItem(ItemStack stack) {
-    }
-
-    @Override
-    public World getWorld() {
-        return world;
-    }
-
-    @Override
-    public int getXp() {
-        return 0;
-    }
-
-    @Override
-    public void setXP(int xp) {
-    }
-
-    @Override
-    public SoundEvent getYesSound() {
-        return SoundEvents.ENTITY_VILLAGER_YES;
-    }
-
-    @Override
-    protected void registerData() {
-    }
-
-    @Override
-    protected void readAdditional(CompoundNBT cnbt) {
-    }
-
-    @Override
-    protected void writeAdditional(CompoundNBT cnbt) {
-    }
-
-    @Override
-    public IPacket<?> createSpawnPacket() {
-        return null;
-    }
-
-    @Override
-    public boolean hasXPBar() {
-        return false;
-    }
-}
-*/

+ 335 - 458
src/me/hammerle/kp/snuviscript/ScriptEvents.java

@@ -1,574 +1,451 @@
 package me.hammerle.kp.snuviscript;
 
+import java.util.Arrays;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import com.destroystokyo.paper.event.player.PlayerPostRespawnEvent;
+import org.bukkit.block.Block;
 import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Item;
+import org.bukkit.entity.LivingEntity;
 import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.block.*;
+import org.bukkit.event.entity.*;
+import org.bukkit.event.inventory.*;
+import org.bukkit.event.player.*;
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.spigotmc.event.entity.EntityMountEvent;
+import io.papermc.paper.event.player.PlayerArmSwingEvent;
 import me.hammerle.kp.KajetansPlugin;
+import me.hammerle.kp.NMS;
+import me.hammerle.snuviscript.code.Script;
+import me.hammerle.snuviscript.code.SnuviUtils;
+import me.hammerle.snuviscript.inputprovider.Variable;
+import net.kyori.adventure.text.Component;
 
 public class ScriptEvents {
-    /*private static class WrappedBool {
-        public boolean wrapped;
+    private static class WrappedBool {
+        public boolean wrapped = false;
     }
-    
+
+    private static void setEntity(Script sc, Entity ent) {
+        sc.setVar("entity", ent);
+    }
+
     private static void setLiving(Script sc, LivingEntity ent) {
         sc.setVar("living_entity", ent);
     }
-    
+
     private static void setItem(Script sc, ItemStack stack) {
         sc.setVar("item", stack);
     }
-    
-    private static void setPlayer(Script sc, PlayerEntity p) {
-        sc.setVar("player", p);
+
+    private static void setItem(Script sc, Item stack) {
+        sc.setVar("item_entity", stack);
     }
-    
-    @SuppressWarnings("")
-    private static void setBlock(Script sc, World w, BlockPos pos, BlockState state) {
-        sc.setVar("block_loc", new Location(w, pos));
-        sc.setVar("block_type", state.getBlock().getRegistryName().toString());
-        sc.setVar("block", state.getBlock());
+
+    private static void setPlayer(Script sc, Player p) {
+        sc.setVar("player", p);
     }
-    
-    @SuppressWarnings("")
-    private static void setBlock(Script sc, World w, BlockPos pos) {
-        BlockState state = w.getBlockState(pos);
-        sc.setVar("block_loc", new Location(w, pos));
-        sc.setVar("block_type", state.getBlock().getRegistryName().toString());
-        sc.setVar("block", state.getBlock());
+
+    private static void setCancel(Script sc, boolean b) {
+        sc.setVar("cancel", b);
     }
-    
-    private static void setEntity(Script sc, Entity ent) {
-        sc.setVar("entity", ent);
+
+    private static void setHand(Script sc, EquipmentSlot hand) {
+        sc.setVar("hand", hand);
     }
-    
-    private static void nothing(Script sc) {}
-    
-    private void handleEvent(Event e, String event, Consumer<Script> before,
-            Consumer<Script> after) {
-        if(e.isCancelable()) {
-            scripts.getScriptManager().callEvent(event, sc -> {
-                before.accept(sc);
-                sc.setVar("cancel", e.isCanceled());
-            }, sc -> {
-                after.accept(sc);
-                handleVar(sc, event, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
-            });
-        } else {
-            scripts.getScriptManager().callEvent(event, before, after);
+
+    private static void setCancelled(Cancellable c, Script sc) {
+        Variable v = sc.getVar("cancel");
+        if(v == null) {
+            return;
         }
-    }
-    
-    private void handleEvent(Event e, String event, Consumer<Script> before) {
-        handleEvent(e, event, before, ScriptEvents::nothing);
-    }
-    
-    private void handleEvent(String event, Consumer<Script> before, Consumer<Script> after) {
-        scripts.getScriptManager().callEvent(event, before, after);
-    }
-    
-    private void handleEvent(String event, Consumer<Script> before) {
-        handleEvent(event, before, ScriptEvents::nothing);
-    }
-    
-    private void handleVar(Script sc, String event, String name, Consumer<Variable> c) {
         try {
-            ifVarNotNull(sc, name, c);
+            c.setCancelled(v.getBoolean(sc));
         } catch(Exception ex) {
-            scripts.getLogger().print(String.format("invalid var in '%s' event", event), ex, null,
-                    sc.getName(), sc, sc.getStackTrace());
         }
     }
-    
-    private void ifVarNotNull(Script sc, String name, Consumer<Variable> c) {
-        Variable v = sc.getVar(name);
-        if(v != null) {
-            c.accept(v);
-        }
+
+    private static void setBlock(Script sc, Block b) {
+        sc.setVar("block", b);
     }
-    
-    private void simpleCancel(Script sc, Event e, String name) {
+
+    private static void nothing(Script sc) {}
+
+    private static void handleEvent(Cancellable e, String name, Consumer<Script> c) {
+        KajetansPlugin.scriptManager.callEvent(name, sc -> {
+            c.accept(sc);
+            setCancel(sc, e.isCancelled());
+        }, sc -> {
+            setCancelled(e, sc);
+        });
+    }
+
+    private static void handleEvent(String name, Consumer<Script> c) {
+        KajetansPlugin.scriptManager.callEvent(name, c, ScriptEvents::nothing);
+    }
+
+    private static void handleVar(Script sc, String event, String name, Consumer<Variable> c) {
         try {
-            ifVarNotNull(sc, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
+            Variable v = sc.getVar(name);
+            if(v != null) {
+                c.accept(v);
+            }
         } catch(Exception ex) {
-            scripts.getLogger().print(String.format("invalid var in '%s' event", name), ex, null,
+            KajetansPlugin.logger.print(String.format("invalid var in '%s' event", event), ex, null,
                     sc.getName(), sc, sc.getStackTrace());
         }
     }
-    
-    public void onPlayerDataTick(PlayerEntity p, String var) {
-        handleEvent("player_data_tick", sc -> {
+
+    public static void onPlayerDataTick(Player p, String var) {
+        KajetansPlugin.scriptManager.callEvent("player_data_tick", sc -> {
             setPlayer(sc, p);
             sc.setVar("var", var);
-        });
+        }, ScriptEvents::nothing);
     }
-    
-    public void onPlayerStartElytra(PlayerEntity p) {
-        handleEvent("player_elytra_start", sc -> {
+
+    public static void onGlideToggle(EntityToggleGlideEvent e) {
+        if(!(e.getEntity() instanceof Player)) {
+            return;
+        }
+        Player p = (Player) e.getEntity();
+        if(e.isGliding()) {
+            handleEvent("player_elytra_start", sc -> {
+                setPlayer(sc, p);
+            });
+        } else {
+            handleEvent("player_elytra_stop", sc -> {
+                setPlayer(sc, p);
+            });
+        }
+    }
+
+    public static void onPlayerMove(Player p, int id) {
+        handleEvent("player_move", sc -> {
             setPlayer(sc, p);
+            sc.setVar("id", (double) id);
         });
     }
-    
-    public void onPlayerStopElytra(PlayerEntity p) {
-        handleEvent("player_elytra_stop", sc -> {
+
+    private static void onSnuviClick(Player p, Inventory inv, Component title, int slot) {
+        handleEvent("snuvi_click", sc -> {
             setPlayer(sc, p);
+            sc.setVar("inv", inv);
+            sc.setVar("inv_title", title);
+            sc.setVar("inv_slot", (double) slot);
         });
-    }*/
-
-    public static void onPlayerMove(Player p, int id) {
-        //handleEvent("player_move", sc -> {
-        //    setPlayer(sc, p);
-        //    sc.setVar("id", (double) id);
-        //});
     }
 
-    /*public boolean onInventoryClick(Script script, ITextComponent text, ModInventory inv, int slot,
-            ClickType click, PlayerEntity p) {
-        scripts.getScriptManager().callEvent("inv_click", script, sc -> {
+    public static void onInventoryClick(InventoryClickEvent e) {
+        if(!(e.getWhoClicked() instanceof Player)) {
+            return;
+        }
+        Player p = (Player) e.getWhoClicked();
+        Inventory clicked = e.getClickedInventory();
+        int slot = e.getSlot();
+
+        if(clicked != null && clicked.getHolder() instanceof SnuviInventoryHolder) {
+            SnuviInventoryHolder holder = (SnuviInventoryHolder) clicked.getHolder();
+            switch(holder.getSlotType(slot)) {
+                case BLOCKED:
+                    e.setCancelled(true);
+                    return;
+                case NORMAL:
+                    break;
+                case CLICK_EVENT_1:
+                case CLICK_EVENT_2:
+                    e.setCancelled(true);
+                    onSnuviClick(p, e.getClickedInventory(), e.getView().title(), slot);
+                    return;
+            }
+        }
+        String click = e.getClick().toString();
+        String action = e.getAction().toString();
+        handleEvent(e, "inv_click", sc -> {
             setPlayer(sc, p);
-            sc.setVar("inv", inv);
-            sc.setVar("inv_id", (double) inv.getModId());
-            sc.setVar("inv_name", text.getString());
+            sc.setVar("inv", e.getInventory());
+            sc.setVar("inv_clicked", e.getClickedInventory());
+            sc.setVar("inv_name", e.getView().title());
             sc.setVar("inv_slot", (double) slot);
-            sc.setVar("click_type", click.toString());
-            setItem(sc, inv.getStackInSlot(slot));
-            sc.setVar("cancel", false);
-        }, ScriptEvents::nothing);
-        Variable v = script.getVar("cancel");
-        return v != null && v.getBoolean(script);
+            sc.setVar("click", click);
+            sc.setVar("action", action);
+        });
     }
-    
-    public void onInventoryClose(Script script, ITextComponent text, ModInventory inv,
-            PlayerEntity p) {
-        scripts.getScriptManager().callEvent("inv_close", script, sc -> {
+
+    public static void onInventoryClose(InventoryCloseEvent e) {
+        if(!(e.getPlayer() instanceof Player)) {
+            return;
+        }
+        Player p = (Player) e.getPlayer();
+        handleEvent("inv_close", sc -> {
             setPlayer(sc, p);
-            sc.setVar("inv", inv);
-            sc.setVar("inv_id", (double) inv.getModId());
-            sc.setVar("inv_name", text.getString());
-        }, ScriptEvents::nothing);
+            sc.setVar("inv", e.getInventory());
+            sc.setVar("inv_name", e.getView().title());
+        });
     }
-    
-    public void onHumanHurt(Entity attacker, EntityHuman h) {
+
+    /*public void onHumanHurt(Entity attacker, EntityHuman h) {
         handleEvent("human_hurt", sc -> {
             setEntity(sc, attacker);
             sc.setVar("human", h);
         });
-    }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onPlayerPostRespawn(PlayerEvent.PlayerRespawnEvent e) {
+    }*/
+
+    public static void onPlayerPreRespawn(PlayerRespawnEvent e) {
         handleEvent("player_post_respawn", sc -> setPlayer(sc, e.getPlayer()));
     }
-    
-    public void onPlayerPreRespawn(PlayerEntity p) {
-        handleEvent("player_pre_respawn", sc -> setPlayer(sc, p));
-    }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onLivingDamage(LivingDamageEvent e) {
-        handleEvent(e, "living_damage", (sc) -> {
-            setLiving(sc, e.getEntityLiving());
-            sc.setVar("damage_source", e.getSource());
-            sc.setVar("damage_amount", (double) e.getAmount());
-        }, (sc) -> {
-            handleVar(sc, "living_damage", "damage_amount", v -> e.setAmount(v.getFloat(sc)));
-        });
+
+    public static void onPlayerPostRespawn(PlayerPostRespawnEvent e) {
+        handleEvent("player_pre_respawn", sc -> setPlayer(sc, e.getPlayer()));
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onLivingHurt(LivingHurtEvent e) {
-        if(e.getSource().getDamageType().equals("fireworks")) {
-            e.setCanceled(true);
+
+    private static Block getBlock(EntityDamageEvent e) {
+        if(e instanceof EntityDamageByBlockEvent) {
+            EntityDamageByBlockEvent eb = (EntityDamageByBlockEvent) e;
+            return eb.getDamager();
         }
-        handleEvent(e, "living_hurt", (sc) -> {
-            setLiving(sc, e.getEntityLiving());
-            sc.setVar("damage_source", e.getSource());
-            sc.setVar("damage_amount", (double) e.getAmount());
-        }, (sc) -> {
-            handleVar(sc, "living_hurt", "damage_amount", v -> e.setAmount(v.getFloat(sc)));
-        });
+        return null;
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onLivingAttacked(LivingAttackEvent e) {
-        handleEvent(e, "living_pre_hurt", (sc) -> {
-            setLiving(sc, e.getEntityLiving());
-            sc.setVar("damage_source", e.getSource());
-            sc.setVar("damage_amount", (double) e.getAmount());
-        });
+
+    private static Entity getEntity(EntityDamageEvent e) {
+        if(e instanceof EntityDamageByEntityEvent) {
+            EntityDamageByEntityEvent ee = (EntityDamageByEntityEvent) e;
+            return ee.getDamager();
+        }
+        return null;
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onLivingHeal(LivingHealEvent e) {
-        handleEvent(e, "living_heal", (sc) -> {
-            setLiving(sc, e.getEntityLiving());
-            sc.setVar("heal_amount", (double) e.getAmount());
-        }, (sc) -> {
-            handleVar(sc, "living_heal", "heal_amount", v -> e.setAmount(v.getFloat(sc)));
+
+    public static void onEntityDamage(EntityDamageEvent e) {
+        String cause = e.getCause().toString();
+        Block damagerBlock = getBlock(e);
+        Entity damagerEntity = getEntity(e);
+        handleEvent("entity_damage", (sc) -> {
+            setEntity(sc, e.getEntity());
+            sc.setVar("vanilla_cause", NMS.getCurrentDamageSource());
+            sc.setVar("cause", cause);
+            sc.setVar("damager_block", damagerBlock);
+            sc.setVar("damager_entity", damagerEntity);
+            sc.setVar("raw_damage", e.getDamage());
+            sc.setVar("damage", e.getFinalDamage());
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onLivingDeath(LivingDeathEvent e) {
-        handleEvent(e, "living_death", (sc) -> {
-            setLiving(sc, e.getEntityLiving());
-            sc.setVar("damage_source", e.getSource());
+
+    public static void onEntityRegainHealth(EntityRegainHealthEvent e) {
+        KajetansPlugin.scriptManager.callEvent("entity_heal", sc -> {
+            setEntity(sc, e.getEntity());
+            sc.setVar("heal_amount", e.getAmount());
+            sc.setVar("heal_reason", e.getRegainReason().toString());
+            setCancel(sc, e.isCancelled());
+        }, sc -> {
+            setCancelled(e, sc);
+            handleVar(sc, "entity_heal", "heal_amount", v -> e.setAmount(v.getDouble(sc)));
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onLivingDrop(LivingDropsEvent e) {
-        handleEvent(e, "living_drop", (sc) -> {
-            setLiving(sc, e.getEntityLiving());
+
+    public static void onEntityDeath(EntityDeathEvent e) {
+        KajetansPlugin.scriptManager.callEvent("living_death", sc -> {
+            setLiving(sc, e.getEntity());
+            sc.setVar("vanilla_cause", NMS.getCurrentDamageSource());
             sc.setVar("drops", e.getDrops());
-            sc.setVar("damage_source", e.getSource());
-            sc.setVar("looting", (double) e.getLootingLevel());
-        });
-    }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onLivingExperienceDrop(LivingExperienceDropEvent e) {
-        handleEvent(e, "living_experience_drop", (sc) -> {
-            setLiving(sc, e.getEntityLiving());
-            sc.setVar("experience", (double) e.getDroppedExperience());
-        }, (sc) -> {
-            handleVar(sc, "living_experience_drop", "experience",
-                    v -> e.setDroppedExperience(v.getInt(sc)));
+            sc.setVar("experience", e.getDrops());
+            setCancel(sc, e.isCancelled());
+        }, sc -> {
+            setCancelled(e, sc);
+            handleVar(sc, "living_death", "experience", v -> e.setDroppedExp(v.getInt(sc)));
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onProjectileHit(ProjectileImpactEvent e) {
-        final Entity hitEntity;
-        final Location loc;
-    
-        RayTraceResult ray = e.getRayTraceResult();
-        switch(ray.getType()) {
-            case ENTITY:
-                hitEntity = ((EntityRayTraceResult) e.getRayTraceResult()).getEntity();
-                loc = null;
-                break;
-            case BLOCK:
-                loc = new Location(e.getEntity().world,
-                        ((BlockRayTraceResult) e.getRayTraceResult()).getPos());
-                hitEntity = null;
-                break;
-            default:
-                return;
-        }
-    
+
+    public static void onProjectileHit(ProjectileHitEvent e) {
         handleEvent(e, "projectile_hit", (sc) -> {
             sc.setVar("projectile", e.getEntity());
-            sc.setVar("entity_hit", hitEntity);
-            sc.setVar("loc_hit", loc);
-            sc.setVar("shooter", Utils.getEntityFromProjectile(e.getEntity()));
+            sc.setVar("entity_hit", e.getHitEntity());
+            sc.setVar("block_hit", e.getHitBlock());
+            sc.setVar("shooter", e.getEntity().getShooter());
         });
     }
-    
-    public void onEntityItemProjectileHit(EntityItemProjectile ent, LivingEntity liv,
-            ItemStack stack, Entity hitEntity, BlockPos pos) {
-        Location loc = (pos == null) ? null : new Location(ent.world, pos);
-        handleEvent("item_hit", (sc) -> {
-            sc.setVar("projectile", ent);
-            setItem(sc, stack);
-            sc.setVar("entity_hit", hitEntity);
-            sc.setVar("loc_hit", loc);
-            sc.setVar("shooter", liv);
+
+    public static void onBlockDropItemEvent(BlockDropItemEvent e) {
+        final Block b = e.getBlockState().getBlock();
+        handleEvent(e, "block_drop", sc -> {
+            setPlayer(sc, e.getPlayer());
+            sc.setVar("drops", e.getItems());
+            setBlock(sc, b);
         });
     }
-    
-    @Override
-    public List<ItemStack> onBlockHarvest(BlockState state, ServerWorld w, BlockPos pos,
-            TileEntity tileEnt, Entity ent, ItemStack stack) {
-        LootContext.Builder loot = new LootContext.Builder(w).withRandom(w.getRandom())
-                .withParameter(LootParameters.field_237457_g_, Vector3d.copyCentered(pos))
-                .withParameter(LootParameters.TOOL, stack == null ? ItemStack.EMPTY : stack)
-                .withNullableParameter(LootParameters.THIS_ENTITY, ent)
-                .withNullableParameter(LootParameters.BLOCK_ENTITY, tileEnt);
-        List<ItemStack> list = state.getDrops(loot);
-        try {
-            final Block b = state.getBlock();
-            final String name = b.getRegistryName().toString();
-            scripts.getScriptManager().callEvent("block_drop", sc -> {
-                sc.setVar("drops", list);
-                sc.setVar("block_type", name);
-                sc.setVar("block", b);
-                sc.setVar("location", new Location(w, pos));
-                setEntity(sc, ent);
-                setItem(sc, stack);
-            }, ScriptEvents::nothing);
-        } catch(Exception ex) {
-            ex.printStackTrace();
-        }
-        return list;
-    }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onBlockBreak(BlockEvent.BreakEvent e) {
-        handleEvent("block_break", (sc) -> {
+
+    public static void onBlockBreak(BlockBreakEvent e) {
+        handleEvent(e, "block_break", (sc) -> {
             setPlayer(sc, e.getPlayer());
-            setBlock(sc, (World) e.getWorld(), e.getPos(), e.getState());
-            sc.setVar("cancel", e.isCanceled());
-        }, (sc) -> {
-            simpleCancel(sc, e, "block_break");
+            setBlock(sc, e.getBlock());
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onBlockPlace(BlockEvent.EntityPlaceEvent e) {
-        if(!(e.getEntity() instanceof PlayerEntity)) {
-            return;
-        }
-        PlayerEntity p = (PlayerEntity) e.getEntity();
-        handleEvent("block_place", (sc) -> {
-            setPlayer(sc, p);
-            sc.setVar("block_type_after", e.getPlacedBlock().getBlock().getRegistryName());
-            setBlock(sc, (World) e.getWorld(), e.getPos(), e.getState());
-            sc.setVar("cancel", e.isCanceled());
-        }, (sc) -> {
-            simpleCancel(sc, e, "block_place");
+
+    public static void onBlockPlace(BlockPlaceEvent e) {
+        handleEvent(e, "block_place", (sc) -> {
+            setPlayer(sc, e.getPlayer());
+            setBlock(sc, e.getBlockPlaced());
+            setHand(sc, e.getHand());
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent e) {
-        PlayerEntity p = e.getPlayer();
-        if(p == null) {
-            return;
-        }
-        PlayerList list = server.getPlayerList();
-        boolean banned = list.getBannedPlayers().isBanned(p.getGameProfile());
-        boolean whitelisted = list.getWhitelistedPlayers().isWhitelisted(p.getGameProfile());
+
+    public static void onPlayerLogin(PlayerLoginEvent e) {
+        String result = e.getResult().toString();
         handleEvent("player_login", (sc) -> {
-            setPlayer(sc, p);
-            sc.setVar("is_banned", banned);
-            sc.setVar("is_whitelisted", whitelisted);
+            setPlayer(sc, e.getPlayer());
+            sc.setVar("result", result);
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onPlayerLogout(PlayerEvent.PlayerLoggedOutEvent e) {
-        PlayerEntity p = e.getPlayer();
-        if(p == null || e.getPlayer().ticksExisted < 20) {
-            return;
-        }
-        handleEvent("player_logout", sc -> setPlayer(sc, p));
+
+    public static void onPlayerJoin(PlayerJoinEvent e) {
+        KajetansPlugin.scriptManager.callEvent("player_join", sc -> {
+            setPlayer(sc, e.getPlayer());
+            sc.setVar("message", e.joinMessage());
+        }, sc -> {
+            handleVar(sc, "player_join", "message", v -> e.joinMessage((Component) v.get(sc)));
+        });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onBucketFill(FillBucketEvent e) {
-        handleEvent("bucket_use", (sc) -> {
+
+    public static void onPlayerQuit(PlayerQuitEvent e) {
+        KajetansPlugin.scriptManager.callEvent("player_quit", sc -> {
             setPlayer(sc, e.getPlayer());
-            RayTraceResult ray = e.getTarget();
-            if(ray != null && ray instanceof BlockRayTraceResult
-                    && ray.getType() == RayTraceResult.Type.BLOCK) {
-                sc.setVar("has_block", true);
-                ScriptEvents.setBlock(sc, e.getWorld(), ((BlockRayTraceResult) ray).getPos());
-            } else {
-                sc.setVar("has_block", false);
-            }
-            sc.setVar("cancel", e.isCanceled());
-        }, (sc) -> {
-            simpleCancel(sc, e, "bucket_use");
+            sc.setVar("message", e.quitMessage());
+        }, sc -> {
+            handleVar(sc, "player_quit", "message", v -> e.quitMessage((Component) v.get(sc)));
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onRightClickBlock(PlayerInteractEvent.RightClickBlock e) {
-        handleEvent("block_click", (sc) -> {
+
+    public static void onPlayerBucket(PlayerBucketEvent e) {
+        handleEvent(e, "bucket_use", (sc) -> {
             setPlayer(sc, e.getPlayer());
-            sc.setVar("action", "right");
-            sc.setVar("hand", e.getHand().name());
-            ScriptEvents.setBlock(sc, e.getWorld(), e.getPos());
-            sc.setVar("cancel", e.isCanceled());
-        }, (sc) -> {
-            handleVar(sc, "block_click", "cancel", v -> {
-                boolean b = v.getBoolean(sc);
-                e.setCanceled(b);
-                if(!b) {
-                    e.setUseBlock(Result.DEFAULT);
-                    e.setUseItem(Result.DEFAULT);
-                }
-            });
+            setBlock(sc, e.getBlockClicked());
+            sc.setVar("bucket", e.getBucket());
+            setHand(sc, e.getHand());
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onLeftClickBlock(PlayerInteractEvent.LeftClickBlock e) {
+
+    public static void onPlayerInteract(PlayerInteractEvent e) {
         handleEvent("block_click", (sc) -> {
             setPlayer(sc, e.getPlayer());
-            sc.setVar("action", "left");
-            sc.setVar("hand", e.getHand().name());
-            ScriptEvents.setBlock(sc, e.getWorld(), e.getPos());
-            sc.setVar("cancel", e.isCanceled());
-        }, (sc) -> {
-            handleVar(sc, "block_click", "cancel", v -> {
-                boolean b = v.getBoolean(sc);
-                e.setCanceled(b);
-                if(!b) {
-                    e.setUseBlock(Result.DEFAULT);
-                    e.setUseItem(Result.DEFAULT);
-                }
-            });
+            setBlock(sc, e.getClickedBlock());
+            setHand(sc, e.getHand());
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onEntityClick(PlayerInteractEvent.EntityInteract e) {
+
+    public static void onPlayerInteractEntity(PlayerInteractEntityEvent e) {
         handleEvent("entity_click", (sc) -> {
             setPlayer(sc, e.getPlayer());
-            sc.setVar("hand", e.getHand().name());
-            setEntity(sc, e.getTarget());
-            sc.setVar("cancel", e.isCanceled());
-        }, (sc) -> {
-            simpleCancel(sc, e, "entity_click");
+            setEntity(sc, e.getRightClicked());
+            setHand(sc, e.getHand());
         });
     }
-    
-    public void onEmptyLeftClick(PlayerEntity p) {
-        handleEvent("left_click_air", sc -> setPlayer(sc, p));
-    }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onItemClick(PlayerInteractEvent.RightClickItem e) {
-        handleEvent("item_air_click", (sc) -> {
+
+    public static void onPlayerArmSwing(PlayerArmSwingEvent e) {
+        handleEvent("arm_swing", sc -> {
             setPlayer(sc, e.getPlayer());
-            setItem(sc, e.getItemStack());
-            sc.setVar("hand", e.getHand().toString());
-            sc.setVar("cancel", e.isCanceled());
-        }, (sc) -> {
-            simpleCancel(sc, e, "item_air_click");
+            setHand(sc, e.getHand());
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onItemUseStart(LivingEntityUseItemEvent.Start e) {
-        handleEvent(e, "item_use_start", (sc) -> {
-            setLiving(sc, e.getEntityLiving());
-            sc.setVar("duration", (double) e.getDuration());
+
+    public static void onPlayerItemConsume(PlayerItemConsumeEvent e) {
+        handleEvent(e, "item_consume", (sc) -> {
+            setPlayer(sc, e.getPlayer());
             setItem(sc, e.getItem());
-        }, (sc) -> {
-            handleVar(sc, "item_use_start", "duration", v -> e.setDuration(v.getInt(sc)));
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onConsuming(LivingEntityUseItemEvent.Finish e) {
-        handleEvent(e, "item_use_finish", (sc) -> {
-            setLiving(sc, e.getEntityLiving());
-            setItem(sc, e.getItem());
-            sc.setVar("result", e.getResultStack());
-        }, (sc) -> {
-            handleVar(sc, "item_use_finish", "result", v -> {
-                ItemStack stack = (ItemStack) v.get(sc);
-                if(stack == null) {
-                    e.setResultStack(ItemStack.EMPTY);
-                } else {
-                    e.setResultStack(stack);
-                }
-            });
+
+    public static void onPlayerFish(PlayerFishEvent e) {
+        KajetansPlugin.scriptManager.callEvent("fishing", sc -> {
+            setPlayer(sc, e.getPlayer());
+            setEntity(sc, e.getCaught());
+            sc.setVar("experience", e.getExpToDrop());
+            setCancel(sc, e.isCancelled());
+        }, sc -> {
+            setCancelled(e, sc);
+            handleVar(sc, "fishing", "experience", v -> e.setExpToDrop(v.getInt(sc)));
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onFishing(ItemFishedEvent e) {
-        handleEvent("fishing", (sc) -> {
-            setPlayer(sc, e.getPlayer());
-            sc.setVar("drops", e.getDrops());
-            sc.setVar("hook", e.getHookEntity());
-            sc.setVar("rod_damage", (double) e.getRodDamage());
-            sc.setVar("cancel", e.isCanceled());
-        }, (sc) -> {
-            simpleCancel(sc, e, "fishing");
-            handleVar(sc, "fishing", "rod_damage", v -> e.damageRodBy(v.getInt(sc)));
+
+    public static void onCraftItem(CraftItemEvent e) {
+        if(!(e.getWhoClicked() instanceof Player)) {
+            return;
+        }
+        Player p = (Player) e.getWhoClicked();
+        handleEvent(e, "craft", sc -> {
+            setPlayer(sc, p);
+            setItem(sc, e.getInventory().getResult());
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onCrafting(PlayerEvent.ItemCraftedEvent e) {
-        handleEvent("craft", (sc) -> {
-            setPlayer(sc, e.getPlayer());
-            setItem(sc, e.getCrafting());
+
+    public static void onPrepareItemCraft(PrepareItemCraftEvent e) {
+        KajetansPlugin.scriptManager.callEvent("pre_craft", sc -> {
+            sc.setVar("players", e.getViewers());
+            setItem(sc, e.getInventory().getResult());
+        }, sc -> {
+            handleVar(sc, "pre_craft", "item",
+                    v -> e.getInventory().setResult((ItemStack) v.get(sc)));
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onItemDrop(ItemTossEvent e) {
-        handleEvent("player_toss", (sc) -> {
+
+    public static void onPlayerDropItem(PlayerDropItemEvent e) {
+        handleEvent(e, "player_toss", (sc) -> {
             setPlayer(sc, e.getPlayer());
-            setItem(sc, e.getEntityItem().getItem());
-            sc.setVar("cancel", e.isCanceled());
-        }, (sc) -> {
-            simpleCancel(sc, e, "player_toss");
+            setItem(sc, e.getItemDrop());
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onItemPickup(EntityItemPickupEvent e) {
-        handleEvent("player_pickup", (sc) -> {
-            setPlayer(sc, e.getPlayer());
-            setEntity(sc, e.getItem());
-            setItem(sc, e.getItem().getItem());
-            sc.setVar("cancel", e.isCanceled());
-        }, (sc) -> {
-            simpleCancel(sc, e, "player_pickup");
+
+    public static void onEntityPickupItem(EntityPickupItemEvent e) {
+        handleEvent(e, "living_pickup", (sc) -> {
+            setLiving(sc, e.getEntity());
+            setItem(sc, e.getItem());
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onEntityMount(EntityMountEvent e) {
-        Entity ent = e.getEntityBeingMounted();
-        if(ent instanceof AbstractHorseEntity) {
-            for(PlayerEntity p : ent.getEntityWorld().getPlayers()) {
-                if(p.openContainer == null
-                        || !(p.openContainer instanceof HorseInventoryContainer)) {
-                    continue;
-                }
-                p.closeScreen();
-            }
-        }
+
+    public static void onEntityMount(EntityMountEvent e) {
         handleEvent(e, "entity_mount", (sc) -> {
-            sc.setVar("mounting", e.isMounting());
-            setEntity(sc, ent);
-            sc.setVar("rider", e.getEntityMounting());
+            setEntity(sc, e.getEntity());
+            sc.setVar("mount", e.getMount());
         });
     }
-    
-    @SubscribeEvent(receiveCanceled = true)
-    public void onPlayerUsePortal(PlayerEvent.PlayerChangedDimensionEvent e) {
-        handleEvent("portal", (sc) -> {
+
+    public static void onPlayerChangedWorl(PlayerChangedWorldEvent e) {
+        handleEvent("player_change_world", (sc) -> {
             setPlayer(sc, e.getPlayer());
-            sc.setVar("from", e.getFrom().getRegistryName().getPath());
-            sc.setVar("to", e.getTo().getRegistryName().getPath());
+            sc.setVar("from", e.getFrom());
         });
-    }*/
+    }
 
     public static boolean onCommand(Player p, String command) {
-        //handleEvent("command", (sc) -> {
-        //    setPlayer(sc, e.getPlayer());
-        //    sc.setVar("command", e.getName());
-        //    sc.setVar("cancel", e.isCanceled());
-        //}, (sc) -> {
-        //    handleVar(sc, "command", "cancel", v -> e.setCanceled(v.getBoolean(sc)));
-        //});
-        return false;
+        WrappedBool wr = new WrappedBool();
+        KajetansPlugin.scriptManager.callEvent("command", sc -> {
+            sc.setVar("player", p);
+            sc.setVar("command", command);
+            setCancel(sc, wr.wrapped);
+        }, sc -> {
+            Variable v = sc.getVar("cancel");
+            if(v == null) {
+                return;
+            }
+            try {
+                wr.wrapped = v.getBoolean(sc);
+            } catch(Exception ex) {
+            }
+        });
+        return wr.wrapped;
     }
 
     public static void onCustomCommand(Player p, String command, String[] args) {
-        KajetansPlugin.log("Custom Command: " + command);
-        for(String s : args) {
-            KajetansPlugin.log(s);
-        }
-        //handleEvent("custom_command", (sc) -> {
-        //    setPlayer(sc, p);
-        //    sc.setVar("command", command);
-        //    if(args.length == 0) {
-        //        sc.setVar("args", new ArrayList<>());
-        //        sc.setVar("text_args", new ArrayList<>());
-        //    } else {
-        //        sc.setVar("args", Arrays.stream(args).map(s -> SnuviUtils.convert(s))
-        //                .collect(Collectors.toList()));
-        //        sc.setVar("text_args", Arrays.stream(args).collect(Collectors.toList()));
-        //    }
-        //});
+        handleEvent("custom_command", (sc) -> {
+            setPlayer(sc, p);
+            sc.setVar("command", command);
+            sc.setVar("args", Arrays.stream(args).map(s -> SnuviUtils.convert(s))
+                    .collect(Collectors.toList()));
+            sc.setVar("text_args", Arrays.stream(args).collect(Collectors.toList()));
+        });
     }
 
     /*public void onFunctionKey(ServerPlayerEntity p, int key) {
@@ -583,7 +460,7 @@ public class ScriptEvents {
         handleEvent("chat", (sc) -> {
             setPlayer(sc, e.getPlayer());
             sc.setVar("message", e.getMessage());
-            sc.setVar("cancel", e.isCanceled());
+            setCancel(sc, e.isCanceled());
         }, (sc) -> {
             handleVar(sc, "chat", "message",
                     v -> e.setComponent(new StringTextComponent(v.getString(sc))));
@@ -738,7 +615,7 @@ public class ScriptEvents {
             } else {
                 System.out.println("Entity is null");
             }
-            sc.setVar("cancel", b);
+            setCancel(sc, b);
         }, (sc) -> {
             handleVar(sc, "mob_griefing", "cancel", (v) -> {
                 e.setResult(v.getBoolean(sc) ? Result.DENY : Result.ALLOW);
@@ -810,7 +687,7 @@ public class ScriptEvents {
             sc.setVar("type", name);
             sc.setVar("drag_type", (double) dragType);
             sc.setVar("click_type", ct.toString());
-            sc.setVar("cancel", b.wrapped);
+            setCancel(sc, b.wrapped);
         }, sc -> {
             handleVar(sc, "container_click", "cancel", v -> b.wrapped = v.getBoolean(sc));
         });
@@ -823,7 +700,7 @@ public class ScriptEvents {
             setLiving(sc, e.getEntityLiving());
             sc.setVar("location", new Location(e.getEntityLiving().getEntityWorld(), e.getTargetX(),
                     e.getTargetY(), e.getTargetZ(), 0.0f, 0.0f));
-            sc.setVar("cancel", e.isCanceled());
+            setCancel(sc, e.isCanceled());
         }, (sc) -> {
             simpleCancel(sc, e, "ender_teleport");
         });

+ 66 - 0
src/me/hammerle/kp/snuviscript/SnuviInventoryHolder.java

@@ -0,0 +1,66 @@
+package me.hammerle.kp.snuviscript;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.inventory.ItemStack;
+import net.kyori.adventure.text.Component;
+
+public class SnuviInventoryHolder implements InventoryHolder {
+    public enum SnuviSlotType {
+        BLOCKED, NORMAL, CLICK_EVENT_1, CLICK_EVENT_2
+    }
+
+    private static int ids = 0;
+
+    private final SnuviSlotType[] types;
+    private Inventory inventory;
+    private int id = ids++;
+
+    public static Inventory create(String info, Component title) {
+        int allSlots = info.length();
+        allSlots = Math.min(9 * 6, allSlots);
+        int slots = allSlots + 9 - (allSlots % 9);
+        SnuviSlotType[] types = new SnuviSlotType[slots];
+        SnuviSlotType[] values = SnuviSlotType.values();
+        for(int i = 0; i < allSlots; i++) {
+            int id = Character.getNumericValue(info.charAt(i));
+            if(id > 3 || id < 0) {
+                id = 0;
+            }
+            types[i] = values[id];
+        }
+        for(int i = allSlots; i < slots; i++) {
+            types[i] = SnuviSlotType.BLOCKED;
+        }
+        SnuviInventoryHolder holder = new SnuviInventoryHolder(types);
+        Inventory inv = Bukkit.createInventory(holder, slots, title);
+        ItemStack stack = new ItemStack(Material.BLACK_STAINED_GLASS_PANE);
+        stack.editMeta(meta -> meta.displayName(Component.text("")));
+        for(int i = 0; i < slots; i++) {
+            if(types[i] != SnuviSlotType.NORMAL) {
+                inv.setItem(i, stack);
+            }
+        }
+        holder.inventory = inv;
+        return inv;
+    }
+
+    private SnuviInventoryHolder(SnuviSlotType[] types) {
+        this.types = types;
+    }
+
+    public SnuviSlotType getSlotType(int i) {
+        return types[i];
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    @Override
+    public Inventory getInventory() {
+        return inventory;
+    }
+}

+ 2 - 0
src/me/hammerle/kp/snuviscript/commands/BlockCommands.java

@@ -40,6 +40,8 @@ public class BlockCommands {
                 in) -> ((Tag<Material>) in[1].get(sc)).isTagged(((Block) in[0].get(sc)).getType()));
         KajetansPlugin.scriptManager.registerFunction("block.gettype",
                 (sc, in) -> ((Block) in[0].get(sc)).getType());
+        KajetansPlugin.scriptManager.registerFunction("block.getlocation",
+                (sc, in) -> ((Block) in[0].get(sc)).getLocation());
         KajetansPlugin.scriptManager.registerFunction("block.isair",
                 (sc, in) -> ((Location) in[0].get(sc)).getBlock().getType() == Material.AIR);
         KajetansPlugin.scriptManager.registerFunction("block.countair", (sc, in) -> {

+ 25 - 16
src/me/hammerle/kp/snuviscript/commands/DataCommands.java

@@ -1,26 +1,35 @@
-/*package me.km.snuviscript.commands;
+package me.hammerle.kp.snuviscript.commands;
 
-import me.hammerle.snuviscript.code.ScriptManager;
-import me.km.overrides.ModEntityPlayerMP;
-import me.km.scheduler.SnuviScheduler;
+import org.bukkit.entity.Player;
+import me.hammerle.kp.KajetansPlugin;
+import me.hammerle.kp.PlayerData;
 
 public class DataCommands {
-    public static void registerFunctions(ScriptManager sm, SnuviScheduler scheduler) {
-        sm.registerConsumer("data.set", (sc, in) -> {
-            ((ModEntityPlayerMP) in[0].get(sc)).setVar(in[1].getString(sc), in[2].get(sc));
+    public static void registerFunctions() {
+        KajetansPlugin.scriptManager.registerConsumer("data.set", (sc, in) -> {
+            Player p = (Player) in[0].get(sc);
+            PlayerData data = PlayerData.get(p);
+            data.setData(in[1].getString(sc), in[2].get(sc));
         });
-        sm.registerConsumer("data.settimer", (sc, in) -> {
-            ((ModEntityPlayerMP) in[0].get(sc)).setTimer(in[1].getString(sc), in[2].getInt(sc), scheduler);
+        KajetansPlugin.scriptManager.registerConsumer("data.settimer", (sc, in) -> {
+            Player p = (Player) in[0].get(sc);
+            PlayerData data = PlayerData.get(p);
+            data.setTimer(in[1].getString(sc), in[2].getInt(sc));
         });
-        sm.registerFunction("data.get", (sc, in) -> {
-            return ((ModEntityPlayerMP) in[0].get(sc)).getVar(in[1].getString(sc));
+        KajetansPlugin.scriptManager.registerFunction("data.get", (sc, in) -> {
+            Player p = (Player) in[0].get(sc);
+            PlayerData data = PlayerData.get(p);
+            return data.getData(in[1].getString(sc));
         });
-        sm.registerFunction("data.gettimer", (sc, in) -> {
-            return (double) ((ModEntityPlayerMP) in[0].get(sc)).getTimer(in[1].getString(sc));
+        KajetansPlugin.scriptManager.registerFunction("data.get", (sc, in) -> {
+            Player p = (Player) in[0].get(sc);
+            PlayerData data = PlayerData.get(p);
+            return (double) data.getTimer(in[1].getString(sc));
         });
-        sm.registerConsumer("data.clear", (sc, in) -> {
-            ((ModEntityPlayerMP) in[0].get(sc)).clearData(scheduler);
+        KajetansPlugin.scriptManager.registerConsumer("data.clear", (sc, in) -> {
+            Player p = (Player) in[0].get(sc);
+            PlayerData data = PlayerData.get(p);
+            data.clearData();
         });
     }
 }
-*/

+ 48 - 43
src/me/hammerle/kp/snuviscript/commands/InventoryCommands.java

@@ -1,54 +1,59 @@
-/*package me.km.snuviscript.commands;
+package me.hammerle.kp.snuviscript.commands;
 
-import me.hammerle.snuviscript.code.ScriptManager;
-import me.km.inventory.CustomContainer;
-import me.km.inventory.ModInventory;
-import me.km.utils.Location;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.entity.player.ServerPlayerEntity;
-import net.minecraft.inventory.IInventory;
-import net.minecraft.item.ItemStack;
-import net.minecraft.tileentity.ChestTileEntity;
+import org.bukkit.Location;
+import org.bukkit.block.Block;
+import org.bukkit.block.Chest;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemFlag;
+import org.bukkit.inventory.ItemStack;
+import me.hammerle.kp.KajetansPlugin;
+import me.hammerle.kp.snuviscript.SnuviInventoryHolder;
+import me.hammerle.kp.snuviscript.SnuviInventoryHolder.SnuviSlotType;
+import net.kyori.adventure.text.Component;
 
 public class InventoryCommands {
-    public static void registerFunctions(ScriptManager sm) {
-        sm.registerFunction("inv.new", (sc, in) -> new ModInventory(in[0].getString(sc)));
-        sm.registerFunction("inv.getid",
-                (sc, in) -> (double) ((ModInventory) in[0].get(sc)).getModId());
-        sm.registerFunction("inv.loadchest", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            ChestTileEntity chest = (ChestTileEntity) l.getWorld().getTileEntity(l.getBlockPos());
-            int size = chest.getSizeInventory();
-            if(size % 9 != 0) {
-                size /= 9;
-                size++;
-                size *= 9;
-            }
-            ModInventory inv = new ModInventory(size);
-            for(int i = 0; i < chest.getSizeInventory(); i++) {
-                inv.setInventorySlotContents(i, chest.getStackInSlot(i).copy());
+    public static void registerFunctions() {
+        KajetansPlugin.scriptManager.registerFunction("inv.new", (sc, in) -> SnuviInventoryHolder
+                .create(in[0].getString(sc), (Component) in[1].get(sc)));
+        KajetansPlugin.scriptManager.registerFunction("inv.getid", (sc, in) -> {
+            Inventory inv = (Inventory) in[0].get(sc);
+            if(inv.getHolder() instanceof SnuviInventoryHolder) {
+                return (double) ((SnuviInventoryHolder) inv.getHolder()).getId();
             }
-            return inv;
+            return -1;
         });
-        sm.registerConsumer("inv.setitem", (sc, in) -> {
-            ((IInventory) in[0].get(sc)).setInventorySlotContents(in[1].getInt(sc),
-                    (ItemStack) in[2].get(sc));
+        KajetansPlugin.scriptManager.registerFunction("inv.loadchest", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            Block b = l.getBlock();
+            if(b instanceof Chest) {
+                Chest chest = (Chest) b;
+                return chest.getBlockInventory();
+            }
+            return null;
         });
-        sm.registerFunction("inv.getitem",
-                (sc, in) -> ((IInventory) in[0].get(sc)).getStackInSlot(in[1].getInt(sc)));
-        sm.registerFunction("inv.getsize",
-                (sc, in) -> (double) ((IInventory) in[0].get(sc)).getSizeInventory());
-        sm.registerConsumer("inv.open", (sc, in) -> {
-            CustomContainer.openForPlayer((ServerPlayerEntity) in[1].get(sc),
-                    (ModInventory) in[0].get(sc), in[2].getString(sc), sc);
+        KajetansPlugin.scriptManager.registerConsumer("inv.setitem", (sc, in) -> {
+            Inventory inv = (Inventory) in[0].get(sc);
+            int index = in[1].getInt(sc);
+            ItemStack stack = (ItemStack) in[2].get(sc);
+            if(inv.getHolder() instanceof SnuviInventoryHolder
+                    && ((SnuviInventoryHolder) inv.getHolder())
+                            .getSlotType(index) != SnuviSlotType.NORMAL) {
+                stack = stack.clone();
+                stack.addItemFlags(ItemFlag.HIDE_DESTROYS);
+            }
+            inv.setItem(index, stack);
         });
-        sm.registerConsumer("inv.close", (sc, in) -> {
-            ((PlayerEntity) in[0].get(sc)).closeScreen();
+        KajetansPlugin.scriptManager.registerFunction("inv.getitem",
+                (sc, in) -> ((Inventory) in[0].get(sc)).getItem(in[1].getInt(sc)));
+        KajetansPlugin.scriptManager.registerFunction("inv.getsize",
+                (sc, in) -> (double) ((Inventory) in[0].get(sc)).getSize());
+        KajetansPlugin.scriptManager.registerConsumer("inv.open", (sc, in) -> {
+            ((Player) in[1].get(sc)).openInventory((Inventory) in[0].get(sc));
         });
-        sm.registerConsumer("inv.update", (sc, in) -> {
-            ServerPlayerEntity p = (ServerPlayerEntity) in[0].get(sc);
-            p.sendAllContents(p.openContainer, p.openContainer.getInventory());
+        KajetansPlugin.scriptManager.registerConsumer("inv.close", (sc, in) -> {
+            ((Player) in[0].get(sc)).closeInventory(InventoryCloseEvent.Reason.PLUGIN);
         });
     }
 }
-*/

+ 1 - 1
src/me/hammerle/kp/snuviscript/commands/ScoreboardCommands.java

@@ -53,7 +53,7 @@ public class ScoreboardCommands {
             CommandUtils.doForGroup(in[0].get(sc), sc, cs -> {
                 Player p = (Player) cs;
                 PlayerData data = PlayerData.get(p);
-                data.clear();
+                data.clearTexts();
             });
         });
     }

+ 32 - 22
src/me/hammerle/kp/snuviscript/commands/ShopCommands.java

@@ -1,36 +1,46 @@
-/*package me.km.snuviscript.commands;
+package me.hammerle.kp.snuviscript.commands;
 
-import me.hammerle.snuviscript.code.ScriptManager;
-import me.km.snuviscript.FakeMerchant;
-import net.minecraft.entity.player.ServerPlayerEntity;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.MerchantOffer;
-import net.minecraft.util.text.StringTextComponent;
+import java.util.ArrayList;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.Merchant;
+import org.bukkit.inventory.MerchantRecipe;
+import me.hammerle.kp.KajetansPlugin;
+import net.kyori.adventure.text.Component;
 
 public class ShopCommands {
-    public static void registerFunctions(ScriptManager sm) {
-        sm.registerFunction("shop.new", (sc, in) -> new FakeMerchant());
-        sm.registerConsumer("shop.addoffer", (sc, in) -> {
-            FakeMerchant npc = (FakeMerchant) in[0].get(sc);
+    public static void registerFunctions() {
+        KajetansPlugin.scriptManager.registerFunction("shop.new",
+                (sc, in) -> Bukkit.createMerchant((Component) in[0].get(sc)));
+        KajetansPlugin.scriptManager.registerConsumer("shop.addoffer", (sc, in) -> {
+            Merchant npc = (Merchant) in[0].get(sc);
             ItemStack buy = (ItemStack) in[1].get(sc);
             ItemStack sell = (ItemStack) in[2].get(sc);
             int maxUses = (in.length >= 4) ? in[3].getInt(sc) : Integer.MAX_VALUE;
-            npc.getOffers().add(new MerchantOffer(buy, sell, maxUses, 0, 1.0f));
+            MerchantRecipe recipe = new MerchantRecipe(sell, maxUses);
+            recipe.addIngredient(buy);
+            ArrayList<MerchantRecipe> recipes = new ArrayList<>(npc.getRecipes());
+            recipes.add(recipe);
+            npc.setRecipes(recipes);
         });
-        sm.registerConsumer("shop.adddoubleoffer", (sc, in) -> {
-            FakeMerchant npc = (FakeMerchant) in[0].get(sc);
+        KajetansPlugin.scriptManager.registerConsumer("shop.adddoubleoffer", (sc, in) -> {
+            Merchant npc = (Merchant) in[0].get(sc);
             ItemStack buyA = (ItemStack) in[1].get(sc);
             ItemStack buyB = (ItemStack) in[2].get(sc);
             ItemStack sell = (ItemStack) in[3].get(sc);
             int maxUses = (in.length >= 5) ? in[4].getInt(sc) : Integer.MAX_VALUE;
-            npc.getOffers().add(new MerchantOffer(buyA, buyB, sell, maxUses, 0, 1.0f));
+            MerchantRecipe recipe = new MerchantRecipe(sell, maxUses);
+            recipe.addIngredient(buyA);
+            recipe.addIngredient(buyB);
+            ArrayList<MerchantRecipe> recipes = new ArrayList<>(npc.getRecipes());
+            recipes.add(recipe);
+            npc.setRecipes(recipes);
         });
-        sm.registerConsumer("shop.open", (sc, in) -> {
-            FakeMerchant npc = (FakeMerchant) in[0].get(sc);
-            ServerPlayerEntity p = (ServerPlayerEntity) in[1].get(sc);
-            String name = in[2].getString(sc);
-            npc.setCustomer(p);
-            npc.openMerchantContainer(p, new StringTextComponent(name), 1);
+        KajetansPlugin.scriptManager.registerConsumer("shop.open", (sc, in) -> {
+            Merchant npc = (Merchant) in[0].get(sc);
+            Player p = (Player) in[1].get(sc);
+            p.openMerchant(npc, false);
         });
     }
-}*/
+}