Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Adding the ability to track spawned mobs when chunks unload.

  • Loading branch information...
commit 905e92fa4d01d27a41b4b2ad80221224a982e0f8 1 parent 28b092a
@Glitchfinder Glitchfinder authored
View
8 src/main/java/com/gmail/nossr50/config/Config.java
@@ -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); }
View
6 src/main/java/com/gmail/nossr50/listeners/EntityListener.java
@@ -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;
View
7 src/main/java/com/gmail/nossr50/listeners/WorldListener.java
@@ -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());
+ }
}
View
2  src/main/java/com/gmail/nossr50/skills/taming/CallOfTheWildEventHandler.java
@@ -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);
View
4 src/main/java/com/gmail/nossr50/util/Combat.java
@@ -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 {
View
8 src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/ChunkManager.java
@@ -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);
}
View
13 src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/ChunkStore.java
@@ -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();
}
View
191 src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/HashChunkManager.java
@@ -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,9 +221,51 @@ 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;
@@ -186,6 +273,22 @@ public synchronized void saveChunk(int cx, int cz, World world) {
}
}
+ 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);
+ }
}
View
8 src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/NullChunkManager.java
@@ -4,6 +4,7 @@
import org.bukkit.World;
import org.bukkit.block.Block;
+import org.bukkit.entity.Entity;
public class NullChunkManager implements ChunkManager {
@@ -86,4 +87,11 @@ public void setFalse(Block block) {}
@Override
public void cleanUp() {}
+
+ public boolean isSpawnedMob(Entity entity) {return false;}
+ public boolean isSpawnedPet(Entity entity) {return false;}
+ public void addSpawnedMob(Entity entity) {}
+ public void addSpawnedPet(Entity entity) {}
+ public void removeSpawnedMob(Entity entity) {}
+ public void removeSpawnedPet(Entity entity) {}
}
View
79 src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/PrimitiveChunkStore.java
@@ -3,6 +3,8 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.List;
import java.util.UUID;
import org.bukkit.World;
@@ -15,11 +17,13 @@
transient private boolean dirty = false;
/** X, Z, Y */
public boolean[][][] store;
- private static final int CURRENT_VERSION = 5;
+ private static final int CURRENT_VERSION = 6;
private static final int MAGIC_NUMBER = 0xEA5EDEBB;
private int cx;
private int cz;
private UUID worldUid;
+ private List spawnedMobs = new ArrayList<UUID>();
+ private List spawnedPets = new ArrayList<UUID>();
transient private int worldHeight;
transient private int xBitShifts;
transient private int zBitShifts;
@@ -100,6 +104,64 @@ public void copyFrom(ChunkletStore otherStore) {
dirty = true;
}
+ public boolean isSpawnedMob(UUID id) {
+ return spawnedMobs.contains(id);
+ }
+
+ public boolean isSpawnedPet(UUID id) {
+ return spawnedPets.contains(id);
+ }
+
+ public void addSpawnedMob(UUID id) {
+ if(!isSpawnedMob(id)) {
+ spawnedMobs.add(id);
+ dirty = true;
+ }
+ }
+
+ public void addSpawnedPet(UUID id) {
+ if(!isSpawnedPet(id)) {
+ spawnedPets.add(id);
+ dirty = true;
+ }
+ }
+
+ public void removeSpawnedMob(UUID id) {
+ if(isSpawnedMob(id)) {
+ spawnedMobs.remove(id);
+ dirty = true;
+ }
+ }
+
+ public void removeSpawnedPet(UUID id) {
+ if(isSpawnedPet(id)) {
+ spawnedPets.remove(id);
+ dirty = true;
+ }
+ }
+
+ public void clearSpawnedMobs() {
+ if(!spawnedMobs.isEmpty()) {
+ spawnedMobs.clear();
+ dirty = true;
+ }
+ }
+
+ public void clearSpawnedPets() {
+ if(!spawnedPets.isEmpty()) {
+ spawnedPets.clear();
+ dirty = true;
+ }
+ }
+
+ public List<UUID> getSpawnedMobs() {
+ return spawnedMobs;
+ }
+
+ public List<UUID> getSpawnedPets() {
+ return spawnedPets;
+ }
+
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeInt(MAGIC_NUMBER);
out.writeInt(CURRENT_VERSION);
@@ -110,6 +172,9 @@ private void writeObject(ObjectOutputStream out) throws IOException {
out.writeInt(cz);
out.writeObject(store);
+ out.writeObject(spawnedMobs);
+ out.writeObject(spawnedPets);
+
dirty = false;
}
@@ -139,9 +204,19 @@ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundE
store = (boolean[][][]) in.readObject();
if (fileVersionNumber < CURRENT_VERSION) {
- fixArray();
+ if(fileVersionNumber < 5)
+ fixArray();
+ if(fileVersionNumber < 6) {
+ spawnedMobs = new ArrayList<UUID>();
+ spawnedPets = new ArrayList<UUID>();
+ }
dirty = true;
}
+
+ if(fileVersionNumber >= 6) {
+ spawnedMobs = (ArrayList) in.readObject();
+ spawnedPets = (ArrayList) in.readObject();
+ }
}
private void fixArray() {
Please sign in to comment.
Something went wrong with that request. Please try again.