Ver código fonte

entity spawnn limits, access to item entities, removed strongholds to
prevent null pointer exceptions

Kajetan Johannes Hammerle 5 anos atrás
pai
commit
947e508ccd

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

@@ -72,7 +72,7 @@ public class Server {
 
         // scripts
         scripts = new Scripts(logger, scheduler);
-        scriptEvents = new ScriptEvents(scripts, server, perms);
+        scriptEvents = new ScriptEvents(scripts, server);
         MinecraftForge.EVENT_BUS.register(scriptEvents);
 
         // command manager

+ 0 - 1
src/main/java/me/km/entities/EntityItemProjectile.java

@@ -1,7 +1,6 @@
 package me.km.entities;
 
 import me.km.Server;
-import me.km.overrides.ModEntityPlayerMP;
 import net.minecraft.block.Blocks;
 import net.minecraft.entity.Entity;
 import net.minecraft.entity.LivingEntity;

+ 45 - 0
src/main/java/me/km/snuviscript/Limits.java

@@ -0,0 +1,45 @@
+package me.km.snuviscript;
+
+import java.util.HashMap;
+import net.minecraft.entity.EntityType;
+import net.minecraft.world.server.ServerWorld;
+
+public class Limits {
+    private final HashMap<EntityType, Integer> limits = new HashMap<>();
+    private final HashMap<EntityType, Integer> currentAmount = new HashMap<>();
+
+    public void setLimit(EntityType type, int limit) {
+        limits.put(type, limit);
+    }
+
+    public void removeLimit(EntityType type) {
+        limits.remove(type);
+    }
+
+    public void clearLimits() {
+        limits.clear();
+    }
+
+    public void tick(Iterable<ServerWorld> worlds) {
+        currentAmount.replaceAll((type, amount) -> 0);
+        for(ServerWorld w : worlds) {
+            w.getEntities().forEach(ent -> add(ent.getType()));
+        }
+    }
+
+    private void add(EntityType type) {
+        currentAmount.compute(type, (entType, amount) -> amount == null ? 1 : amount + 1);
+    }
+
+    public boolean isAllowedToSpawn(EntityType type) {
+        Integer limit = limits.get(type);
+        if(limit == null) {
+            return true;
+        }
+        Integer amount = currentAmount.get(type);
+        if(amount == null) {
+            return true;
+        }
+        return amount < limit;
+    }
+}

+ 2 - 0
src/main/java/me/km/snuviscript/MinecraftFunctions.java

@@ -48,6 +48,8 @@ public class MinecraftFunctions {
         ShopCommands.registerFunctions(sm);
         ErrorCommands.registerFunctions(sm);
         EnchantmentCommands.registerFunctions(sm);
+        ItemEntityCommands.registerFunctions(sm);
+        LimitCommands.registerFunctions(sm, scripts);
         Commands.registerFunctions(sm, scripts, perms, scheduler, server, commands);
     }
 }

+ 20 - 21
src/main/java/me/km/snuviscript/ScriptEvents.java

@@ -12,7 +12,6 @@ import me.km.entities.EntityHuman;
 import me.km.entities.EntityItemProjectile;
 import me.km.events.CommandEvent;
 import me.km.inventory.ModInventory;
-import me.km.permissions.Permissions;
 import me.km.utils.ExplosionUtils;
 import me.km.utils.Location;
 import net.minecraft.command.ICommandSource;
@@ -24,30 +23,20 @@ import net.minecraft.inventory.container.ClickType;
 import net.minecraft.item.ItemStack;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.management.PlayerList;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.BlockRayTraceResult;
-import net.minecraft.util.math.EntityRayTraceResult;
-import net.minecraft.util.math.RayTraceResult;
+import net.minecraft.util.math.*;
 import net.minecraft.util.text.ITextComponent;
 import net.minecraft.util.text.StringTextComponent;
 import net.minecraft.world.GameRules;
 import net.minecraftforge.event.ServerChatEvent;
-import net.minecraftforge.event.entity.EntityJoinWorldEvent;
-import net.minecraftforge.event.entity.EntityMobGriefingEvent;
-import net.minecraftforge.event.entity.EntityMountEvent;
-import net.minecraftforge.event.entity.ProjectileImpactEvent;
+import net.minecraftforge.event.TickEvent;
+import net.minecraftforge.event.entity.*;
 import net.minecraftforge.event.entity.item.ItemTossEvent;
 import net.minecraftforge.event.entity.living.*;
 import net.minecraftforge.event.entity.living.LivingEvent.LivingJumpEvent;
-import net.minecraftforge.event.entity.player.EntityItemPickupEvent;
-import net.minecraftforge.event.entity.player.FillBucketEvent;
-import net.minecraftforge.event.entity.player.ItemFishedEvent;
-import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+import net.minecraftforge.event.entity.player.*;
 import net.minecraftforge.event.world.BlockEvent;
 import net.minecraftforge.event.world.ExplosionEvent;
-import net.minecraftforge.eventbus.api.Event;
-import net.minecraftforge.eventbus.api.EventPriority;
-import net.minecraftforge.eventbus.api.SubscribeEvent;
+import net.minecraftforge.eventbus.api.*;
 import net.minecraftforge.event.entity.player.PlayerEvent;
 import net.minecraftforge.eventbus.api.Event.Result;
 
@@ -62,12 +51,10 @@ public class ScriptEvents {
 
     private final Scripts scripts;
     private final MinecraftServer server;
-    private final Permissions perms;
 
-    public ScriptEvents(Scripts scripts, MinecraftServer server, Permissions perms) {
+    public ScriptEvents(Scripts scripts, MinecraftServer server) {
         this.scripts = scripts;
         this.server = server;
-        this.perms = perms;
     }
 
     private void handleEvent(Event e, String event, Consumer<Script> before, Consumer<Script> after) {
@@ -610,7 +597,7 @@ public class ScriptEvents {
             sc.setVar("location", new Location(e.getWorld(), e.getExplosion().getPosition()));
         }, null);
     }
-    
+
     @SubscribeEvent
     public void onExplosion(ExplosionEvent.Detonate e) {
         ExplosionUtils.explosion(e.getExplosion(), e.getWorld());
@@ -657,11 +644,23 @@ public class ScriptEvents {
 
     @SubscribeEvent(receiveCanceled = true)
     public void onEntityJoinWorld(EntityJoinWorldEvent e) {
+        Entity ent = e.getEntity();
+        if(!scripts.getEntityLimits().isAllowedToSpawn(ent.getType())) {
+            e.setCanceled(true);
+            return;
+        }
         handleEvent(e, "entity_join", (sc) -> {
-            ScriptVars.setEntityVars(sc, e.getEntity());
+            ScriptVars.setEntityVars(sc, ent);
         }, null);
     }
 
+    @SubscribeEvent
+    public void onServerTick(TickEvent.ServerTickEvent e) {
+        if(e.phase == TickEvent.Phase.END) {
+            scripts.getEntityLimits().tick(server.getWorlds());
+        }
+    }
+
     @SubscribeEvent(receiveCanceled = true)
     public void onAnimalTame(AnimalTameEvent e) {
         handleEvent(e, "animal_tame", (sc) -> {

+ 6 - 0
src/main/java/me/km/snuviscript/Scripts.java

@@ -22,6 +22,8 @@ public class Scripts {
     private final HashMap<UUID, Integer> playerScript = new HashMap<>();
     private final HashMap<Integer, List<UUID>> registeredPlayers = new HashMap<>();
     private final HashSet<String> scriptCommands = new HashSet<>();
+    
+    private final Limits entityLimits = new Limits();
 
     public Scripts(ISnuviLogger logger, ISnuviScheduler scheduler) {
         this.logger = logger;
@@ -40,6 +42,10 @@ public class Scripts {
         return logger;
     }
 
+    public Limits getEntityLimits() {
+        return entityLimits;
+    }
+
     // -------------------------------------------------------------------------
     // custom commands
     // -------------------------------------------------------------------------

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

@@ -288,6 +288,7 @@ public class EntityCommands {
         });
         sm.registerFunction("entity.gettype", (sc, in) -> ((Entity) in[0].get(sc)).getType().getRegistryName().getPath());
         sm.registerFunction("entity.issneaking", (sc, in) -> ((Entity) in[0].get(sc)).isCrouching());
+        sm.registerFunction("entity.issneaking", (sc, in) -> ((Entity) in[0].get(sc)).isCrouching());
         sm.registerFunction("sheep.issheared", (sc, in) -> ((SheepEntity) in[0].get(sc)).getSheared());
         sm.registerFunction("sheep.getcolor", (sc, in) -> ((SheepEntity) in[0].get(sc)).getFleeceColor().getName());
         sm.registerConsumer("creeper.explode", (sc, in) -> ((CreeperEntity) in[0].get(sc)).ignite());

+ 19 - 0
src/main/java/me/km/snuviscript/commands/ItemEntityCommands.java

@@ -0,0 +1,19 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.utils.Location;
+import net.minecraft.entity.item.ItemEntity;
+import net.minecraft.item.ItemStack;
+
+public class ItemEntityCommands {
+    public static void registerFunctions(ScriptManager sm) {
+        sm.registerFunction("item.entity.get", (sc, in) -> ((ItemEntity) in[0].get(sc)).getItem());
+        sm.registerConsumer("item.entity.set", (sc, in) -> {
+            ((ItemEntity) in[0].get(sc)).setItem((ItemStack) in[1].get(sc));
+        });
+        sm.registerFunction("item.entity.new", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            return new ItemEntity(l.getWorld().getWorld(), l.getX(), l.getY(), l.getZ(), (ItemStack) in[1].get(sc));
+        });
+    }
+}

+ 23 - 0
src/main/java/me/km/snuviscript/commands/LimitCommands.java

@@ -0,0 +1,23 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.snuviscript.Scripts;
+import net.minecraft.entity.EntityType;
+
+public class LimitCommands {
+    public static void registerFunctions(ScriptManager sm, Scripts scripts) {
+        sm.registerConsumer("limit.clear", (sc, in) -> {
+            scripts.getEntityLimits().clearLimits();
+        });
+        sm.registerConsumer("limit.set", (sc, in) -> {
+            scripts.getEntityLimits().setLimit(getType(in[0].getString(sc)), in[1].getInt(sc));
+        });
+        sm.registerConsumer("limit.remove", (sc, in) -> {
+            scripts.getEntityLimits().removeLimit(getType(in[0].getString(sc)));
+        });
+    }
+
+    private static EntityType getType(String type) {
+        return EntityType.byKey(type).get();
+    }
+}

+ 10 - 0
src/main/java/me/km/snuviscript/commands/LivingCommands.java

@@ -2,7 +2,9 @@ package me.km.snuviscript.commands;
 
 import java.util.UUID;
 import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.utils.ReflectionUtils;
 import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.MobEntity;
 import net.minecraft.entity.SharedMonsterAttributes;
 import net.minecraft.entity.ai.attributes.AttributeModifier;
 import net.minecraft.entity.ai.attributes.IAttribute;
@@ -33,5 +35,13 @@ public class LivingCommands {
                 return ((LivingEntity) in[0].get(sc)).getAttribute(attribute).getBaseValue();
             });
         }
+        sm.registerConsumer("living.removeai", (sc, in) -> {
+            LivingEntity ent = (LivingEntity) in[0].get(sc);
+            if(ent instanceof MobEntity) {
+                MobEntity mob = (MobEntity) in[0].get(sc);
+                ReflectionUtils.getGoals(mob.goalSelector).clear();
+                ReflectionUtils.getGoals(mob.targetSelector).clear();
+            }
+        });
     }
 }

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

@@ -6,9 +6,12 @@ import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Map;
+import java.util.Set;
 import java.util.function.Function;
 import net.minecraft.command.Commands;
 import net.minecraft.entity.Entity;
+import net.minecraft.entity.ai.goal.GoalSelector;
+import net.minecraft.entity.ai.goal.PrioritizedGoal;
 import net.minecraft.entity.item.ItemEntity;
 import net.minecraft.entity.player.PlayerAbilities;
 import net.minecraft.entity.player.ServerPlayerEntity;
@@ -22,9 +25,12 @@ import net.minecraft.world.GameRules;
 import net.minecraft.world.GameType;
 import net.minecraft.world.IWorld;
 import net.minecraft.world.World;
+import net.minecraft.world.biome.Biome;
 import net.minecraft.world.biome.provider.BiomeProvider;
 import net.minecraft.world.biome.provider.BiomeProviderType;
 import net.minecraft.world.biome.provider.IBiomeProviderSettings;
+import net.minecraft.world.gen.feature.IFeatureConfig;
+import net.minecraft.world.gen.feature.structure.Structure;
 import net.minecraft.world.storage.WorldInfo;
 import net.minecraftforge.common.DimensionManager;
 import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
@@ -263,4 +269,22 @@ public class ReflectionUtils {
     public static void setGameType(PlayerInteractionManager m, GameType type) {
         setFieldValue(m, GAME_TYPE, type);
     }
+    
+    // -----------------------------------------------------------------------------------
+    // biome map
+    // -----------------------------------------------------------------------------------
+    private final static Field BIOME_STRUCTURE = getField(Biome.class, "field_201874_aj");
+
+    public static Map<Structure<?>, IFeatureConfig> getBiomeStructures(Biome b) {
+        return getFieldValue(Map.class, b, BIOME_STRUCTURE);
+    }
+    
+    // -----------------------------------------------------------------------------------
+    // for clearing ai
+    // -----------------------------------------------------------------------------------
+    private final static Field GOALS = getField(GoalSelector.class, "field_220892_d");
+
+    public static Set<PrioritizedGoal> getGoals(GoalSelector gs) {
+        return getFieldValue(Set.class, gs, GOALS);
+    }
 }

+ 11 - 0
src/main/java/me/km/world/ModWorldGeneration.java

@@ -1,6 +1,8 @@
 package me.km.world;
 
+import java.util.Map;
 import me.km.blocks.ModBlocks;
+import me.km.utils.ReflectionUtils;
 import net.minecraft.block.Block;
 import net.minecraft.block.Blocks;
 import net.minecraft.world.biome.Biome;
@@ -9,7 +11,11 @@ import net.minecraft.world.gen.GenerationStage;
 import net.minecraft.world.gen.feature.ConfiguredFeature;
 import net.minecraft.world.gen.feature.DecoratedFeatureConfig;
 import net.minecraft.world.gen.feature.Feature;
+import net.minecraft.world.gen.feature.IFeatureConfig;
+import net.minecraft.world.gen.feature.NoFeatureConfig;
 import net.minecraft.world.gen.feature.OreFeatureConfig;
+import net.minecraft.world.gen.feature.structure.StrongholdStructure;
+import net.minecraft.world.gen.feature.structure.Structure;
 import net.minecraft.world.gen.placement.CountRangeConfig;
 import net.minecraft.world.gen.placement.Placement;
 import net.minecraftforge.registries.ForgeRegistries;
@@ -17,11 +23,16 @@ import net.minecraftforge.registries.ForgeRegistries;
 public class ModWorldGeneration {
     public static void register() {
         // search for all biomes which generate ore
+        StrongholdStructure patch = new StrongholdStructure(NoFeatureConfig::deserialize);
         for(Biome biome : ForgeRegistries.BIOMES.getValues()) {
             if(!(biome instanceof NetherBiome)) {
                 biome.getCarvers(GenerationStage.Carving.AIR).clear();
                 biome.getCarvers(GenerationStage.Carving.LIQUID).clear();
             }
+            Map<Structure<?>, IFeatureConfig> map = ReflectionUtils.getBiomeStructures(biome);
+            if(map.remove(Feature.STRONGHOLD) != null) {
+                System.out.println("removing stronghold from " + biome.getTranslationKey());
+            }
             for(ConfiguredFeature f : biome.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES)) {
                 if(!(f.config instanceof DecoratedFeatureConfig)) {
                     continue;