From a478428721cadfbaf4b1700496ab4ff4731c3409 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Wed, 2 Sep 2020 16:46:11 -0400 Subject: [PATCH] Custom entity spawns --- .../java/com/volmit/iris/IrisDataManager.java | 7 +- .../java/com/volmit/iris/ProjectManager.java | 35 ++- .../iris/gen/ContextualChunkGenerator.java | 9 + .../volmit/iris/gen/IrisChunkGenerator.java | 88 ++++++ .../volmit/iris/gen/layer/GenLayerUpdate.java | 2 +- .../iris/object/IrisAttributeModifier.java | 9 + .../com/volmit/iris/object/IrisBiome.java | 5 + .../com/volmit/iris/object/IrisDimension.java | 5 + .../com/volmit/iris/object/IrisEntity.java | 270 ++++++++++++++++++ .../volmit/iris/object/IrisEntitySpawn.java | 91 ++++++ .../java/com/volmit/iris/object/IrisLoot.java | 25 ++ .../volmit/iris/object/IrisPotionEffect.java | 107 +++++++ .../com/volmit/iris/object/IrisRegion.java | 7 +- .../com/volmit/iris/object/IrisStructure.java | 5 + .../volmit/iris/object/IrisStructureTile.java | 5 + .../volmit/iris/util/RegistryListEntity.java | 14 + 16 files changed, 680 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/volmit/iris/object/IrisEntity.java create mode 100644 src/main/java/com/volmit/iris/object/IrisEntitySpawn.java create mode 100644 src/main/java/com/volmit/iris/object/IrisPotionEffect.java create mode 100644 src/main/java/com/volmit/iris/util/RegistryListEntity.java diff --git a/src/main/java/com/volmit/iris/IrisDataManager.java b/src/main/java/com/volmit/iris/IrisDataManager.java index d67742ab0..6f538229d 100644 --- a/src/main/java/com/volmit/iris/IrisDataManager.java +++ b/src/main/java/com/volmit/iris/IrisDataManager.java @@ -9,6 +9,7 @@ import com.google.gson.Gson; import com.volmit.iris.object.IrisBiome; import com.volmit.iris.object.IrisBiomeDecorator; import com.volmit.iris.object.IrisDimension; +import com.volmit.iris.object.IrisEntity; import com.volmit.iris.object.IrisGenerator; import com.volmit.iris.object.IrisLootTable; import com.volmit.iris.object.IrisNoiseGenerator; @@ -34,6 +35,7 @@ public class IrisDataManager private ResourceLoader dimensionLoader; private ResourceLoader generatorLoader; private ResourceLoader structureLoader; + private ResourceLoader entityLoader; private ObjectResourceLoader objectLoader; public void hotloaded() @@ -46,6 +48,7 @@ public class IrisDataManager File packs = this.packs.getName().equals("packs") ? this.packs : dataFolder; packs.mkdirs(); this.lootLoader = new ResourceLoader<>(packs, "loot", "Loot", IrisLootTable.class); + this.entityLoader = new ResourceLoader<>(packs, "entities", "Entity", IrisEntity.class); this.regionLoader = new ResourceLoader<>(packs, "regions", "Region", IrisRegion.class); this.biomeLoader = new ResourceLoader<>(packs, "biomes", "Biome", IrisBiome.class); this.dimensionLoader = new ResourceLoader<>(packs, "dimensions", "Dimension", IrisDimension.class); @@ -83,6 +86,7 @@ public class IrisDataManager lootLoader.clearCache(); regionLoader.clearCache(); dimensionLoader.clearCache(); + entityLoader.clearCache(); generatorLoader.clearCache(); structureLoader.clearCache(); } @@ -166,15 +170,16 @@ public class IrisDataManager biomeLoader.preferFolder(name); lootLoader.preferFolder(name); regionLoader.preferFolder(name); + entityLoader.preferFolder(name); dimensionLoader.preferFolder(name); generatorLoader.preferFolder(name); structureLoader.preferFolder(name); - Iris.info("Preferred Folder: " + name); } public void clearLists() { lootLoader.clearList(); + entityLoader.clearList(); biomeLoader.clearList(); regionLoader.clearList(); dimensionLoader.clearList(); diff --git a/src/main/java/com/volmit/iris/ProjectManager.java b/src/main/java/com/volmit/iris/ProjectManager.java index f03373b2e..dad7ddcc7 100644 --- a/src/main/java/com/volmit/iris/ProjectManager.java +++ b/src/main/java/com/volmit/iris/ProjectManager.java @@ -34,6 +34,7 @@ import com.volmit.iris.object.IrisBiome; import com.volmit.iris.object.IrisBiomeGeneratorLink; import com.volmit.iris.object.IrisBiomeMutation; import com.volmit.iris.object.IrisDimension; +import com.volmit.iris.object.IrisEntity; import com.volmit.iris.object.IrisGenerator; import com.volmit.iris.object.IrisLootTable; import com.volmit.iris.object.IrisNoiseGenerator; @@ -65,6 +66,7 @@ import com.volmit.iris.util.MortarSender; import com.volmit.iris.util.O; import com.volmit.iris.util.RegistryListBiome; import com.volmit.iris.util.RegistryListDimension; +import com.volmit.iris.util.RegistryListEntity; import com.volmit.iris.util.RegistryListFont; import com.volmit.iris.util.RegistryListGenerator; import com.volmit.iris.util.RegistryListLoot; @@ -359,7 +361,7 @@ public class ProjectManager World world = Bukkit.createWorld(new WorldCreator("iris/" + UUID.randomUUID()).seed(1337).generator(gx).generateStructures(false).type(WorldType.NORMAL).environment(d.getEnvironment())); Iris.linkMultiverseCore.removeFromConfig(world); - + done.set(true); sender.sendMessage("Generating 100%"); @@ -829,6 +831,7 @@ public class ProjectManager JSONArray schemas = new JSONArray(); TaskGroup g = tx.startWork(); g.queue(() -> ex(schemas, IrisDimension.class, dat, "/dimensions/*.json")); + g.queue(() -> ex(schemas, IrisEntity.class, dat, "/entities/*.json")); g.queue(() -> ex(schemas, IrisBiome.class, dat, "/biomes/*.json")); g.queue(() -> ex(schemas, IrisRegion.class, dat, "/regions/*.json")); g.queue(() -> ex(schemas, IrisGenerator.class, dat, "/generators/*.json")); @@ -955,6 +958,11 @@ public class ProjectManager prop.put("enum", new JSONArray(getBiomeList(dat))); } + if(k.isAnnotationPresent(RegistryListEntity.class)) + { + prop.put("enum", new JSONArray(getEntityList(dat))); + } + if(k.isAnnotationPresent(RegistryListFont.class)) { prop.put("enum", new JSONArray(getFontList())); @@ -1116,6 +1124,26 @@ public class ProjectManager continue; } + if(k.isAnnotationPresent(RegistryListEntity.class)) + { + String name = "enent" + t.type().getSimpleName().toLowerCase(); + if(!def.containsKey(name)) + { + JSONObject deff = new JSONObject(); + deff.put("type", tx); + deff.put("enum", new JSONArray(getEntityList(dat))); + def.put(name, deff); + } + + JSONObject items = new JSONObject(); + items.put("$ref", "#/definitions/" + name); + prop.put("items", items); + prop.put("description", k.getAnnotation(Desc.class).value()); + prop.put("type", tp); + properties.put(k.getName(), prop); + continue; + } + if(k.isAnnotationPresent(RegistryListFont.class)) { String name = "enfong" + t.type().getSimpleName().toLowerCase(); @@ -1367,6 +1395,11 @@ public class ProjectManager return data.getBiomeLoader().getPossibleKeys(); } + private String[] getEntityList(IrisDataManager data) + { + return data.getEntityLoader().getPossibleKeys(); + } + private String[] getLootList(IrisDataManager data) { return data.getLootLoader().getPossibleKeys(); diff --git a/src/main/java/com/volmit/iris/gen/ContextualChunkGenerator.java b/src/main/java/com/volmit/iris/gen/ContextualChunkGenerator.java index 8649d4083..9d5ada65c 100644 --- a/src/main/java/com/volmit/iris/gen/ContextualChunkGenerator.java +++ b/src/main/java/com/volmit/iris/gen/ContextualChunkGenerator.java @@ -16,6 +16,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockDropItemEvent; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntitySpawnEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerTeleportEvent; @@ -205,6 +206,14 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements onTick(ticks++); } + @EventHandler(priority = EventPriority.MONITOR) + public void on(EntitySpawnEvent e) + { + onSpawn(e); + } + + protected abstract void onSpawn(EntitySpawnEvent e); + @EventHandler(priority = EventPriority.MONITOR) public void on(BlockBreakEvent e) { diff --git a/src/main/java/com/volmit/iris/gen/IrisChunkGenerator.java b/src/main/java/com/volmit/iris/gen/IrisChunkGenerator.java index ae6ccb112..8772f9a08 100644 --- a/src/main/java/com/volmit/iris/gen/IrisChunkGenerator.java +++ b/src/main/java/com/volmit/iris/gen/IrisChunkGenerator.java @@ -12,6 +12,7 @@ import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.entity.Player; import org.bukkit.event.block.BlockDropItemEvent; +import org.bukkit.event.entity.EntitySpawnEvent; import org.bukkit.inventory.ItemStack; import com.volmit.iris.Iris; @@ -24,8 +25,10 @@ import com.volmit.iris.object.IrisBiome; import com.volmit.iris.object.IrisBlockDrops; import com.volmit.iris.object.IrisDimension; import com.volmit.iris.object.IrisEffect; +import com.volmit.iris.object.IrisEntitySpawn; import com.volmit.iris.object.IrisRegion; import com.volmit.iris.util.Form; +import com.volmit.iris.util.IrisStructureResult; import com.volmit.iris.util.KList; import com.volmit.iris.util.KMap; import com.volmit.iris.util.PrecisionStopwatch; @@ -42,6 +45,7 @@ public class IrisChunkGenerator extends PostBlockChunkGenerator implements IrisC private IrisBiome hb = null; private IrisRegion hr = null; private KMap b = new KMap<>(); + private boolean spawnable = false; public IrisChunkGenerator(String dimensionName, int threads) { @@ -122,6 +126,7 @@ public class IrisChunkGenerator extends PostBlockChunkGenerator implements IrisC @Override public void onTick(int ticks) { + spawnable = true; super.onTick(ticks); for(Player i : getWorld().getPlayers()) { @@ -429,4 +434,87 @@ public class IrisChunkGenerator extends PostBlockChunkGenerator implements IrisC } } } + + @Override + protected void onSpawn(EntitySpawnEvent e) + { + if(spawnable) + { + int x = e.getEntity().getLocation().getBlockX(); + int y = e.getEntity().getLocation().getBlockY(); + int z = e.getEntity().getLocation().getBlockZ(); + IrisDimension dim = getDimension(); + IrisRegion region = sampleRegion(x, z); + IrisBiome above = sampleTrueBiome(x, z); + IrisBiome below = sampleTrueBiome(x, y, z); + + if(above.getLoadKey().equals(below.getLoadKey())) + { + below = null; + } + + IrisStructureResult res = getStructure(x, y, z); + + if(res != null && res.getTile() != null) + { + if(trySpawn(res.getTile().getEntitySpawns(), e)) + { + return; + } + } + + if(res != null && res.getStructure() != null) + { + if(trySpawn(res.getStructure().getEntitySpawns(), e)) + { + return; + } + } + + if(below != null) + { + if(trySpawn(below.getEntitySpawns(), e)) + { + return; + } + } + + if(trySpawn(above.getEntitySpawns(), e)) + { + return; + } + + if(trySpawn(region.getEntitySpawns(), e)) + { + return; + } + + if(trySpawn(dim.getEntitySpawns(), e)) + { + return; + } + } + } + + private boolean trySpawn(KList s, EntitySpawnEvent e) + { + for(IrisEntitySpawn i : s) + { + spawnable = false; + + if(i.on(this, e.getLocation(), e.getEntityType(), e) != null) + { + e.setCancelled(true); + e.getEntity().remove(); + return true; + } + + else + { + spawnable = true; + } + } + + return false; + } } diff --git a/src/main/java/com/volmit/iris/gen/layer/GenLayerUpdate.java b/src/main/java/com/volmit/iris/gen/layer/GenLayerUpdate.java index d0d1dd0c9..4456dc97e 100644 --- a/src/main/java/com/volmit/iris/gen/layer/GenLayerUpdate.java +++ b/src/main/java/com/volmit/iris/gen/layer/GenLayerUpdate.java @@ -184,7 +184,7 @@ public class GenLayerUpdate extends BlockPopulator } } - private void scramble(Inventory inventory, RNG rng) + public void scramble(Inventory inventory, RNG rng) { KList v = new KList<>(); diff --git a/src/main/java/com/volmit/iris/object/IrisAttributeModifier.java b/src/main/java/com/volmit/iris/object/IrisAttributeModifier.java index 5834971d5..09c210b93 100644 --- a/src/main/java/com/volmit/iris/object/IrisAttributeModifier.java +++ b/src/main/java/com/volmit/iris/object/IrisAttributeModifier.java @@ -1,5 +1,6 @@ package com.volmit.iris.object; +import org.bukkit.attribute.Attributable; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; import org.bukkit.attribute.AttributeModifier.Operation; @@ -60,6 +61,14 @@ public class IrisAttributeModifier } } + public void apply(RNG rng, Attributable meta) + { + if(rng.nextDouble() < getChance()) + { + meta.getAttribute(getAttribute()).addModifier(new AttributeModifier(getName(), getAmount(rng), getOperation())); + } + } + public double getAmount(RNG rng) { return rng.d(getMinAmount(), getMaxAmount()); diff --git a/src/main/java/com/volmit/iris/object/IrisBiome.java b/src/main/java/com/volmit/iris/object/IrisBiome.java index 0d30afa7a..deb3e3132 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/object/IrisBiome.java @@ -42,6 +42,11 @@ public class IrisBiome extends IrisRegistrant implements IRare @ArrayType(min = 1, type = IrisTextPlacement.class) private KList text = new KList<>(); + @DontObfuscate + @Desc("Entity spawns to override or add to this biome") + @ArrayType(min = 1, type = IrisEntitySpawn.class) + private KList entitySpawns = new KList<>(); + @ArrayType(min = 1, type = IrisEffect.class) @DontObfuscate @Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play arround the player even if where the effect was played is no longer in the biome the player is in.") diff --git a/src/main/java/com/volmit/iris/object/IrisDimension.java b/src/main/java/com/volmit/iris/object/IrisDimension.java index 0f87c132c..9ef86e5fd 100644 --- a/src/main/java/com/volmit/iris/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/object/IrisDimension.java @@ -51,6 +51,11 @@ public class IrisDimension extends IrisRegistrant @ArrayType(min = 1, type = IrisTextPlacement.class) private KList text = new KList<>(); + @DontObfuscate + @Desc("Entity spawns to override or add to this dimension") + @ArrayType(min = 1, type = IrisEntitySpawn.class) + private KList entitySpawns = new KList<>(); + @DontObfuscate @Desc("Reference loot tables in this area") private IrisLootReference loot = new IrisLootReference(); diff --git a/src/main/java/com/volmit/iris/object/IrisEntity.java b/src/main/java/com/volmit/iris/object/IrisEntity.java new file mode 100644 index 000000000..facd758d8 --- /dev/null +++ b/src/main/java/com/volmit/iris/object/IrisEntity.java @@ -0,0 +1,270 @@ +package com.volmit.iris.object; + +import java.util.Collection; +import java.util.Random; + +import org.bukkit.Location; +import org.bukkit.NamespacedKey; +import org.bukkit.attribute.Attributable; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Mob; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.loot.LootContext; +import org.bukkit.loot.LootTable; +import org.bukkit.loot.Lootable; + +import com.volmit.iris.Iris; +import com.volmit.iris.gen.IrisChunkGenerator; +import com.volmit.iris.util.ArrayType; +import com.volmit.iris.util.C; +import com.volmit.iris.util.Desc; +import com.volmit.iris.util.DontObfuscate; +import com.volmit.iris.util.KList; +import com.volmit.iris.util.RNG; +import com.volmit.iris.util.Required; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@DontObfuscate +@Desc("Represents an iris entity.") +@Data +@EqualsAndHashCode(callSuper = false) +public class IrisEntity extends IrisRegistrant +{ + @Required + @DontObfuscate + @Desc("The type of entity to spawn") + private EntityType type = EntityType.PIG; + + @DontObfuscate + @Desc("The custom name of this entity") + private String customName = ""; + + @DontObfuscate + @Desc("Should the name on this entity be visible even if you arent looking at it.") + private boolean customNameVisible = false; + + @DontObfuscate + @Desc("If this entity type is a mob, should it be aware of it's surroundings & interact with the world.") + private boolean aware = true; + + @DontObfuscate + @Desc("If this entity type is a creature, should it have ai goals.") + private boolean ai = true; + + @DontObfuscate + @Desc("Should this entity be glowing") + private boolean glowing = false; + + @DontObfuscate + @Desc("Should gravity apply to this entity") + private boolean gravity = true; + + @DontObfuscate + @Desc("When an entity is invulnerable it can only be damaged by players increative mode.") + private boolean invulnerable = false; + + @DontObfuscate + @Desc("When an entity is silent it will not produce any sound.") + private boolean silent = false; + + @DontObfuscate + @Desc("Should this entity be allowed to pickup items") + private boolean pickupItems = false; + + @DontObfuscate + @Desc("Should this entity be removed when far away") + private boolean removable = true; + + @DontObfuscate + @Desc("Entity helmet equipment") + private IrisLoot helmet = null; + + @DontObfuscate + @Desc("Entity chestplate equipment") + private IrisLoot chestplate = null; + + @DontObfuscate + @Desc("Entity boots equipment") + private IrisLoot boots = null; + + @DontObfuscate + @Desc("Entity leggings equipment") + private IrisLoot leggings = null; + + @DontObfuscate + @Desc("Entity main hand equipment") + private IrisLoot mainHand = null; + + @DontObfuscate + @Desc("Entity off hand equipment") + private IrisLoot offHand = null; + + @DontObfuscate + @Desc("Make other entities ride this entity") + @ArrayType(min = 1, type = IrisEntity.class) + private KList passengers = new KList<>(); + + @DontObfuscate + @Desc("Attribute modifiers for this entity") + @ArrayType(min = 1, type = IrisAttributeModifier.class) + private KList attributes = new KList<>(); + + @DontObfuscate + @Desc("Loot tables for drops") + private IrisLootReference loot = new IrisLootReference(); + + @DontObfuscate + @Desc("Potion effects to add to this entity") + @ArrayType(min = 1, type = IrisPotionEffect.class) + private KList potionEffects = new KList<>(); + + @DontObfuscate + @Desc("If specified, this entity will be leashed by this entity. I.e. THIS ENTITY Leashed by SPECIFIED. This has no effect on EnderDragons, Withers, Players, or Bats.Non-living entities excluding leashes will not persist as leashholders.") + private IrisEntity leashHolder = null; + + public Entity spawn(IrisChunkGenerator gen, Location at) + { + return spawn(gen, at, new RNG(at.hashCode())); + } + + public Entity spawn(IrisChunkGenerator gen, Location at, RNG rng) + { + Entity e = at.getWorld().spawnEntity(at, getType()); + e.setCustomName(getCustomName() != null ? C.translateAlternateColorCodes('&', getCustomName()) : null); + e.setCustomNameVisible(isCustomNameVisible()); + e.setGlowing(isGlowing()); + e.setGravity(isGravity()); + e.setInvulnerable(isInvulnerable()); + e.setSilent(isSilent()); + + int gg = 0; + for(IrisEntity i : passengers) + { + e.addPassenger(i.spawn(gen, at, rng.nextParallelRNG(234858 + gg++))); + } + + if(e instanceof Attributable) + { + Attributable a = (Attributable) e; + + for(IrisAttributeModifier i : getAttributes()) + { + i.apply(rng, a); + } + } + + if(e instanceof Lootable) + { + Lootable l = (Lootable) e; + + if(getLoot().getTables().isNotEmpty()) + { + l.setLootTable(new LootTable() + { + @Override + public NamespacedKey getKey() + { + return new NamespacedKey(Iris.instance, "loot-" + IrisEntity.this.hashCode()); + } + + @Override + public Collection populateLoot(Random random, LootContext context) + { + KList items = new KList<>(); + + for(int t = 0; t < gen.getDimension().getLootTries(); t++) + { + int b = 4; + for(String fi : getLoot().getTables()) + { + IrisLootTable i = gen.getData().getLootLoader().load(fi); + b++; + items.addAll(i.getLoot(gen.isDev(), rng.nextParallelRNG(345911 * -t), InventorySlotType.STORAGE, at.getBlockX(), at.getBlockY(), at.getBlockZ(), t + b + b, b)); + } + } + + return items; + } + + @Override + public void fillInventory(Inventory inventory, Random random, LootContext context) + { + for(ItemStack i : populateLoot(random, context)) + { + inventory.addItem(i); + } + + gen.getGlUpdate().scramble(inventory, rng); + } + }); + } + } + + if(e instanceof LivingEntity) + { + LivingEntity l = (LivingEntity) e; + l.setAI(isAi()); + l.setCanPickupItems(isPickupItems()); + + if(getLeashHolder() != null) + { + l.setLeashHolder(getLeashHolder().spawn(gen, at, rng.nextParallelRNG(234548))); + } + + l.setRemoveWhenFarAway(isRemovable()); + + for(IrisPotionEffect i : getPotionEffects()) + { + i.apply(l); + } + + if(getHelmet() != null && rng.i(1, getHelmet().getRarity()) == 1) + { + l.getEquipment().setHelmet(getHelmet().get(gen.isDev(), rng)); + } + + if(getChestplate() != null && rng.i(1, getChestplate().getRarity()) == 1) + { + l.getEquipment().setChestplate(getChestplate().get(gen.isDev(), rng)); + } + + if(getLeggings() != null && rng.i(1, getLeggings().getRarity()) == 1) + { + l.getEquipment().setLeggings(getLeggings().get(gen.isDev(), rng)); + } + + if(getBoots() != null && rng.i(1, getBoots().getRarity()) == 1) + { + l.getEquipment().setBoots(getBoots().get(gen.isDev(), rng)); + } + + if(getMainHand() != null && rng.i(1, getMainHand().getRarity()) == 1) + { + l.getEquipment().setItemInMainHand(getMainHand().get(gen.isDev(), rng)); + } + + if(getOffHand() != null && rng.i(1, getOffHand().getRarity()) == 1) + { + l.getEquipment().setItemInOffHand(getOffHand().get(gen.isDev(), rng)); + } + } + + if(e instanceof Mob) + { + Mob m = (Mob) e; + m.setAware(isAware()); + } + + return e; + } + + public IrisEntity() + { + + } +} diff --git a/src/main/java/com/volmit/iris/object/IrisEntitySpawn.java b/src/main/java/com/volmit/iris/object/IrisEntitySpawn.java new file mode 100644 index 000000000..3498e0b1e --- /dev/null +++ b/src/main/java/com/volmit/iris/object/IrisEntitySpawn.java @@ -0,0 +1,91 @@ +package com.volmit.iris.object; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.event.entity.EntitySpawnEvent; + +import com.volmit.iris.gen.IrisChunkGenerator; +import com.volmit.iris.gen.atomics.AtomicCache; +import com.volmit.iris.util.Desc; +import com.volmit.iris.util.DontObfuscate; +import com.volmit.iris.util.MinNumber; +import com.volmit.iris.util.RNG; +import com.volmit.iris.util.RegistryListEntity; +import com.volmit.iris.util.Required; + +import lombok.Data; + +@Desc("Represents an entity spawn") +@Data +public class IrisEntitySpawn +{ + @RegistryListEntity + @Required + @DontObfuscate + @Desc("The entity") + private String entity = ""; + + @Required + @DontObfuscate + @Desc("If the following entity type spawns, spawn this entity. Set to unknown for any entity spawn") + private EntityType trigger = EntityType.UNKNOWN; + + @DontObfuscate + @Desc("If the source is triggered, cancel spawning the original entity instead of ADDING a new entity.") + private boolean cancelSourceSpawn = false; + + @MinNumber(1) + @DontObfuscate + @Desc("The 1 in RARITY chance for this entity to spawn") + private int rarity = 1; + + private AtomicCache rng = new AtomicCache<>(); + private AtomicCache ent = new AtomicCache<>(); + + public Entity on(IrisChunkGenerator g, Location at, EntityType t, EntitySpawnEvent ee) + { + if(!trigger.equals(EntityType.UNKNOWN)) + { + if(!trigger.equals(t)) + { + return null; + } + } + + Entity e = spawn(g, at); + + if(e != null && isCancelSourceSpawn()) + { + ee.setCancelled(true); + ee.getEntity().remove(); + } + + return e; + } + + public IrisEntity getRealEntity(IrisChunkGenerator g) + { + return ent.aquire(() -> g.getData().getEntityLoader().load(getEntity())); + } + + public Entity spawn(IrisChunkGenerator g, Location at) + { + if(getRealEntity(g) == null) + { + return null; + } + + if(rng.aquire(() -> new RNG(g.getWorld().getSeed() + 4)).i(1, getRarity()) == 1) + { + return getRealEntity(g).spawn(g, at, rng.aquire(() -> new RNG(g.getWorld().getSeed() + 4))); + } + + return null; + } + + public IrisEntitySpawn() + { + + } +} diff --git a/src/main/java/com/volmit/iris/object/IrisLoot.java b/src/main/java/com/volmit/iris/object/IrisLoot.java index f143c47e4..052374791 100644 --- a/src/main/java/com/volmit/iris/object/IrisLoot.java +++ b/src/main/java/com/volmit/iris/object/IrisLoot.java @@ -1,10 +1,15 @@ package com.volmit.iris.object; +import java.awt.Color; + +import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.material.Colorable; import com.volmit.iris.Iris; import com.volmit.iris.gen.atomics.AtomicCache; @@ -96,6 +101,14 @@ public class IrisLoot @Desc("This is the item or block type. Does not accept minecraft:*. Only materials such as DIAMOND_SWORD or DIRT.") private String type = ""; + @DontObfuscate + @Desc("The dye color") + private DyeColor dyeColor = null; + + @DontObfuscate + @Desc("The leather armor color") + private String leatherColor = null; + private transient AtomicCache chance = new AtomicCache<>(); public IrisLoot() @@ -171,6 +184,18 @@ public class IrisLoot } m.setLore(lore); + + if(getLeatherColor() != null && m instanceof LeatherArmorMeta) + { + Color c = Color.decode(getLeatherColor()); + ((LeatherArmorMeta) m).setColor(org.bukkit.Color.fromRGB(c.getRed(), c.getGreen(), c.getBlue())); + } + + if(getDyeColor() != null && m instanceof Colorable) + { + ((Colorable) m).setColor(getDyeColor()); + } + is.setItemMeta(m); return is; } diff --git a/src/main/java/com/volmit/iris/object/IrisPotionEffect.java b/src/main/java/com/volmit/iris/object/IrisPotionEffect.java new file mode 100644 index 000000000..9be20c5df --- /dev/null +++ b/src/main/java/com/volmit/iris/object/IrisPotionEffect.java @@ -0,0 +1,107 @@ +package com.volmit.iris.object; + +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import com.volmit.iris.Iris; +import com.volmit.iris.gen.atomics.AtomicCache; +import com.volmit.iris.util.Desc; +import com.volmit.iris.util.DontObfuscate; +import com.volmit.iris.util.MaxNumber; +import com.volmit.iris.util.MinNumber; +import com.volmit.iris.util.Required; + +import lombok.Data; + +@Desc("An iris potion effect") +@Data +public class IrisPotionEffect +{ + @Required + @DontObfuscate + @Desc("The potion effect to apply in this area") + private String potionEffect = ""; + + @Required + @MinNumber(-1) + @MaxNumber(1024) + @DontObfuscate + @Desc("The Potion Strength or -1 to disable") + private int strength = -1; + + @Required + @MinNumber(1) + @DontObfuscate + @Desc("The time the potion will last for") + private int ticks = 200; + + @DontObfuscate + @Desc("Is the effect ambient") + private boolean ambient = false; + + @DontObfuscate + @Desc("Is the effect showing particles") + private boolean particles = true; + + private transient AtomicCache pt = new AtomicCache<>(); + + public IrisPotionEffect() + { + + } + + public PotionEffectType getRealType() + { + return pt.aquire(() -> + { + PotionEffectType t = PotionEffectType.LUCK; + + if(getPotionEffect().isEmpty()) + { + return t; + } + + try + { + for(PotionEffectType i : PotionEffectType.values()) + { + if(i.getName().toUpperCase().replaceAll("\\Q \\E", "_").equals(getPotionEffect())) + { + t = i; + + return t; + } + } + } + + catch(Throwable e) + { + + } + + Iris.warn("Unknown Potion Effect Type: " + getPotionEffect()); + + return t; + }); + } + + public void apply(LivingEntity p) + { + if(strength > -1) + { + if(p.hasPotionEffect(getRealType())) + { + PotionEffect e = p.getPotionEffect(getRealType()); + if(e.getAmplifier() > strength) + { + return; + } + + p.removePotionEffect(getRealType()); + } + + p.addPotionEffect(new PotionEffect(getRealType(), ticks, strength, ambient, particles, false)); + } + } +} diff --git a/src/main/java/com/volmit/iris/object/IrisRegion.java b/src/main/java/com/volmit/iris/object/IrisRegion.java index 0d5bf688f..9578e6386 100644 --- a/src/main/java/com/volmit/iris/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/object/IrisRegion.java @@ -35,7 +35,12 @@ public class IrisRegion extends IrisRegistrant implements IRare @DontObfuscate @Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play arround the player even if where the effect was played is no longer in the biome the player is in.") private KList effects = new KList<>(); - + + @DontObfuscate + @Desc("Entity spawns to override or add to this region") + @ArrayType(min = 1, type = IrisEntitySpawn.class) + private KList entitySpawns = new KList<>(); + @MinNumber(1) @MaxNumber(256) @DontObfuscate diff --git a/src/main/java/com/volmit/iris/object/IrisStructure.java b/src/main/java/com/volmit/iris/object/IrisStructure.java index 8d7558824..72d2c9dcf 100644 --- a/src/main/java/com/volmit/iris/object/IrisStructure.java +++ b/src/main/java/com/volmit/iris/object/IrisStructure.java @@ -27,6 +27,11 @@ public class IrisStructure extends IrisRegistrant @Desc("This is the human readable name for this structure. Such as Red Dungeon or Tropical Village.") private String name = "A Structure Type"; + @DontObfuscate + @Desc("Entity spawns to override or add to this structure") + @ArrayType(min = 1, type = IrisEntitySpawn.class) + private KList entitySpawns = new KList<>(); + @DontObfuscate @Desc("Wall style noise") private IrisGeneratorStyle wallStyle = NoiseStyle.STATIC.style(); diff --git a/src/main/java/com/volmit/iris/object/IrisStructureTile.java b/src/main/java/com/volmit/iris/object/IrisStructureTile.java index 4aa1811e4..e65308c46 100644 --- a/src/main/java/com/volmit/iris/object/IrisStructureTile.java +++ b/src/main/java/com/volmit/iris/object/IrisStructureTile.java @@ -24,6 +24,11 @@ public class IrisStructureTile @Desc("Reference loot tables in this area") private IrisLootReference loot = new IrisLootReference(); + @DontObfuscate + @Desc("Entity spawns to override or add to this structure tile") + @ArrayType(min = 1, type = IrisEntitySpawn.class) + private KList entitySpawns = new KList<>(); + @DontObfuscate @Desc("The place mode for this tile") private ObjectPlaceMode placeMode = ObjectPlaceMode.CENTER_HEIGHT; diff --git a/src/main/java/com/volmit/iris/util/RegistryListEntity.java b/src/main/java/com/volmit/iris/util/RegistryListEntity.java new file mode 100644 index 000000000..37ecbdae4 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/RegistryListEntity.java @@ -0,0 +1,14 @@ +package com.volmit.iris.util; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target({PARAMETER, TYPE, FIELD}) +public @interface RegistryListEntity +{ + +}