Permalink
Browse files

Adding the ability to track spawned mobs when chunks unload.

  • Loading branch information...
Glitchfinder committed Dec 31, 2012
1 parent 28b092a commit 905e92fa4d01d27a41b4b2ad80221224a982e0f8
@@ -438,10 +438,10 @@ public int getPowerLevelCap() {
public double getMagmaCubeXP() { return config.getDouble("Experience.Combat.Multiplier.Magma_Cube", 2.0); }
public double getEnderDragonXP() { return config.getDouble("Experience.Combat.Multiplier.Ender_Dragon", 8.0); }
public double getIronGolemXP() { return config.getDouble("Experience.Combat.Multiplier.Iron_Golem", 2.0); }
- public double getGiantXP() { return config.getDouble("Experience.Combat.Multiplier.Giant", 2.0); }
- public double getWitherXP() { return config.getDouble("Experience.Combat.Multiplier.Wither", 2.0); }
- public double getWitherSkeletonXP() { return config.getDouble("Experience.Combat.Multiplier.Wither_Skeleton", 2.0); }
- public double getWitchXP() { return config.getDouble("Experience.Combat.Multiplier.Witch", 2.0); }
+ public double getGiantXP() { return config.getDouble("Experience.Combat.Multiplier.Giant", 4.0); }
+ public double getWitherXP() { return config.getDouble("Experience.Combat.Multiplier.Wither", 7.0); }
+ public double getWitherSkeletonXP() { return config.getDouble("Experience.Combat.Multiplier.Wither_Skeleton", 4.0); }
+ public double getWitchXP() { return config.getDouble("Experience.Combat.Multiplier.Witch", 4.0); }
/* XP Formula Multiplier */
public int getFormulaMultiplierCurve() { return config.getInt("Experience.Formula.Curve_Modifier", 20); }
@@ -184,6 +184,8 @@ public void onEntityDeath(EntityDeathEvent event) {
entity.setFireTicks(0);
BleedTimer.remove(entity);
Archery.arrowRetrievalCheck(entity);
+ mcMMO.p.placeStore.removeSpawnedMob(((Entity) entity));
+ mcMMO.p.placeStore.removeSpawnedPet(((Entity) entity));
}
/**
@@ -196,7 +198,7 @@ public void onCreatureSpawn(CreatureSpawnEvent event) {
SpawnReason reason = event.getSpawnReason();
if ((reason.equals(SpawnReason.SPAWNER) || reason.equals(SpawnReason.SPAWNER_EGG)) && !Config.getInstance().getExperienceGainsMobspawnersEnabled()) {
- event.getEntity().setMetadata("mcmmoFromMobSpawner", new FixedMetadataValue(plugin, true));
+ mcMMO.p.placeStore.addSpawnedMob(((Entity) event.getEntity()));
}
}
@@ -397,7 +399,7 @@ public void onEntityTame(EntityTameEvent event) {
if(player.hasMetadata("NPC")) return; // Check if this player is a Citizens NPC
- if (Permissions.getInstance().taming(player) && !event.getEntity().hasMetadata("mcmmoSummoned")) {
+ if (Permissions.getInstance().taming(player) && !mcMMO.p.placeStore.isSpawnedPet((Entity) event.getEntity())) {
PlayerProfile profile = Users.getProfile(player);
EntityType type = event.getEntityType();
int xp = 0;
@@ -5,6 +5,7 @@
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
+import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.event.world.WorldSaveEvent;
@@ -46,4 +47,10 @@ public void onWorldSave(WorldSaveEvent event) {
public void onChunkUnload(ChunkUnloadEvent event) {
mcMMO.placeStore.chunkUnloaded(event.getChunk().getX(), event.getChunk().getZ(), event.getWorld());
}
+
+ @EventHandler
+ public void onChunkLoad(ChunkLoadEvent event) {
+ if(event.getChunk().getEntities().length > 0)
+ mcMMO.p.placeStore.loadChunk(event.getChunk().getX(), event.getChunk().getZ(), event.getWorld());
+ }
}
@@ -68,7 +68,7 @@ protected void spawnCreature() {
return;
LivingEntity entity = (LivingEntity) player.getWorld().spawnEntity(player.getLocation(), type);
- entity.setMetadata("mcmmoSummoned", new FixedMetadataValue(mcMMO.p, true));
+ mcMMO.p.placeStore.addSpawnedPet((Entity) entity);
((Tameable) entity).setOwner(player);
@@ -399,8 +399,8 @@ public static void startGainXp(Player attacker, PlayerProfile profile, LivingEnt
baseXP = 20 * configInstance.getPlayerVersusPlayerXP();
}
}
- else if (!target.hasMetadata("mcmmoFromMobSpawner")) {
- if (target instanceof Animals && !target.hasMetadata("mcmmoSummoned")) {
+ else if (!mcMMO.p.placeStore.isSpawnedMob(((Entity) target))) {
+ if (target instanceof Animals && !mcMMO.p.placeStore.isSpawnedPet((Entity) target)) {
baseXP = configInstance.getAnimalsXP();
}
else {
@@ -4,6 +4,7 @@
import org.bukkit.World;
import org.bukkit.block.Block;
+import org.bukkit.entity.Entity;
public interface ChunkManager {
public void closeAll();
@@ -165,4 +166,11 @@
* Delete any ChunkletStores that are empty
*/
public void cleanUp();
+
+ public boolean isSpawnedMob(Entity entity);
+ public boolean isSpawnedPet(Entity entity);
+ public void addSpawnedMob(Entity entity);
+ public void addSpawnedPet(Entity entity);
+ public void removeSpawnedMob(Entity entity);
+ public void removeSpawnedPet(Entity entity);
}
@@ -1,6 +1,8 @@
package com.gmail.nossr50.util.blockmeta.chunkmeta;
import java.io.Serializable;
+import java.util.List;
+import java.util.UUID;
import com.gmail.nossr50.util.blockmeta.ChunkletStore;
@@ -71,4 +73,15 @@
* @param otherStore Another ChunkletStore that this one should copy all data from
*/
public void copyFrom(ChunkletStore otherStore);
+
+ public boolean isSpawnedMob(UUID id);
+ public boolean isSpawnedPet(UUID id);
+ public void addSpawnedMob(UUID id);
+ public void addSpawnedPet(UUID id);
+ public void removeSpawnedMob(UUID id);
+ public void removeSpawnedPet(UUID id);
+ public void clearSpawnedMobs();
+ public void clearSpawnedPets();
+ public List<UUID> getSpawnedMobs();
+ public List<UUID> getSpawnedPets();
}
@@ -10,12 +10,16 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.block.Block;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.LivingEntity;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.ChunkletUnloader;
import com.gmail.nossr50.runnables.blockstoreconversion.BlockStoreConversionZDirectory;
@@ -26,6 +30,10 @@
public HashMap<String, ChunkStore> store = new HashMap<String, ChunkStore>();
public ArrayList<BlockStoreConversionZDirectory> converters = new ArrayList<BlockStoreConversionZDirectory>();
private HashMap<UUID, Boolean> oldData = new HashMap<UUID, Boolean>();
+ private List<Entity> spawnedMobs = new ArrayList<Entity>();
+ private List<Entity> spawnedPets = new ArrayList<Entity>();
+ private List<Entity> mobsToRemove = new ArrayList<Entity>();
+ private boolean safeToRemoveMobs = true;
@Override
public synchronized void closeAll() {
@@ -159,6 +167,23 @@ public synchronized void loadChunk(int cx, int cz, World world) {
if(in != null) {
store.put(world.getName() + "," + cx + "," + cz, in);
+
+ List mobs = in.getSpawnedMobs();
+ List pets = in.getSpawnedPets();
+
+ if(mobs.isEmpty() && pets.isEmpty())
+ return;
+
+ for(LivingEntity entity : world.getLivingEntities()) {
+ if(mobs.contains(entity.getUniqueId()))
+ addSpawnedMob((Entity) entity);
+
+ if(pets.contains(entity.getUniqueId()))
+ addSpawnedPet((Entity) entity);
+ }
+
+ in.clearSpawnedMobs();
+ in.clearSpawnedPets();
}
}
@@ -168,6 +193,26 @@ public synchronized void unloadChunk(int cx, int cz, World world) {
if(store.containsKey(world.getName() + "," + cx + "," + cz)) {
store.remove(world.getName() + "," + cx + "," + cz);
+
+ for(Entity entity : spawnedMobs) {
+ if(!isEntityInChunk(entity, cx, cz, world))
+ continue;
+
+ mobsToRemove.add(entity);
+ }
+
+ for(Entity entity : spawnedPets) {
+ if(!isEntityInChunk(entity, cx, cz, world))
+ continue;
+
+ mobsToRemove.add(entity);
+ }
+
+ if(safeToRemoveMobs) {
+ spawnedMobs.remove(mobsToRemove);
+ spawnedPets.remove(mobsToRemove);
+ mobsToRemove.clear();
+ }
}
}
@@ -176,16 +221,74 @@ public synchronized void saveChunk(int cx, int cz, World world) {
if(world == null)
return;
+ boolean unloaded = false;
+ if(!store.containsKey(world.getName() + "," + cx + "," + cz)) {
+ for(Entity entity : spawnedMobs) {
+ if(!isEntityInChunk(entity, cx, cz, world))
+ continue;
+
+ loadChunk(cx, cz, world);
+ unloaded = true;
+ break;
+ }
+
+ if(!unloaded) {
+ for(Entity entity : spawnedPets) {
+ if(!isEntityInChunk(entity, cx, cz, world))
+ continue;
+
+ loadChunk(cx, cz, world);
+ unloaded = true;
+ break;
+ }
+ }
+ }
+
+ if(!store.containsKey(world.getName() + "," + cx + "," + cz) && unloaded) {
+ ChunkStore cStore = ChunkStoreFactory.getChunkStore(world, cx, cz);
+ store.put(world.getName() + "," + cx + "," + cz, cStore);
+ }
+
if(store.containsKey(world.getName() + "," + cx + "," + cz)) {
ChunkStore out = store.get(world.getName() + "," + cx + "," + cz);
+ for(Entity entity : spawnedMobs) {
+ if(!isEntityInChunk(entity, cx, cz, world))
+ continue;
+
+ out.addSpawnedMob(entity.getUniqueId());
+ }
+
+ for(Entity entity : spawnedPets) {
+ if(!isEntityInChunk(entity, cx, cz, world))
+ continue;
+
+ out.addSpawnedPet(entity.getUniqueId());
+ }
+
if(!out.isDirty())
return;
writeChunkStore(world, cx, cz, out);
}
}
+ private boolean isEntityInChunk(Entity entity, int cx, int cz, World world) {
+ if(entity == null || world == null)
+ return false;
+
+ if(entity.getLocation().getChunk().getX() != cx)
+ return false;
+
+ if(entity.getLocation().getChunk().getZ() != cz)
+ return false;
+
+ if(entity.getWorld() != world)
+ return false;
+
+ return true;
+ }
+
@Override
public synchronized boolean isChunkLoaded(int cx, int cz, World world) {
if(world == null)
@@ -224,11 +327,35 @@ public synchronized void saveWorld(World world) {
cz = Integer.parseInt(info[2]);
}
catch(Exception e) {
- return;
+ continue;
}
saveChunk(cx, cz, world);
}
}
+
+ for(Entity entity : spawnedMobs) {
+ World entityWorld = entity.getWorld();
+
+ if(world != entityWorld)
+ continue;
+
+ int cx = entity.getLocation().getChunk().getX();
+ int cz = entity.getLocation().getChunk().getZ();
+
+ saveChunk(cx, cz, world);
+ }
+
+ for(Entity entity : spawnedPets) {
+ World entityWorld = entity.getWorld();
+
+ if(world != entityWorld)
+ continue;
+
+ int cx = entity.getLocation().getChunk().getX();
+ int cz = entity.getLocation().getChunk().getZ();
+
+ saveChunk(cx, cz, world);
+ }
}
@Override
@@ -250,11 +377,43 @@ public synchronized void unloadWorld(World world) {
cz = Integer.parseInt(info[2]);
}
catch(Exception e) {
- return;
+ continue;
}
unloadChunk(cx, cz, world);
}
}
+
+ safeToRemoveMobs = false;
+
+ for(Entity entity : spawnedMobs) {
+ World entityWorld = entity.getWorld();
+
+ if(world != entityWorld)
+ continue;
+
+ int cx = entity.getLocation().getChunk().getX();
+ int cz = entity.getLocation().getChunk().getZ();
+
+ unloadChunk(cx, cz, world);
+ }
+
+ for(Entity entity : spawnedPets) {
+ World entityWorld = entity.getWorld();
+
+ if(world != entityWorld)
+ continue;
+
+ int cx = entity.getLocation().getChunk().getX();
+ int cz = entity.getLocation().getChunk().getZ();
+
+ unloadChunk(cx, cz, world);
+ }
+
+ safeToRemoveMobs = true;
+
+ spawnedMobs.remove(mobsToRemove);
+ spawnedPets.remove(mobsToRemove);
+ mobsToRemove.clear();
}
@Override
@@ -415,4 +574,32 @@ public synchronized void convertChunk(File dataDir, int cx, int cz, World world,
converters.add(converter);
}
}
+
+ public boolean isSpawnedMob(Entity entity) {
+ return spawnedMobs.contains(entity);
+ }
+
+ public boolean isSpawnedPet(Entity entity) {
+ return spawnedPets.contains(entity);
+ }
+
+ public void addSpawnedMob(Entity entity) {
+ if(!isSpawnedMob(entity))
+ spawnedMobs.add(entity);
+ }
+
+ public void addSpawnedPet(Entity entity) {
+ if(!isSpawnedPet(entity))
+ spawnedPets.add(entity);
+ }
+
+ public void removeSpawnedMob(Entity entity) {
+ if(isSpawnedMob(entity))
+ spawnedMobs.remove(entity);
+ }
+
+ public void removeSpawnedPet(Entity entity) {
+ if(isSpawnedPet(entity))
+ spawnedPets.remove(entity);
+ }
}
Oops, something went wrong.

0 comments on commit 905e92f

Please sign in to comment.