Skip to content

Commit 48153c1

Browse files
committed
Add support for labelling horses by type (Donkey, Mule, Skeleton Horse)
1 parent fc461b7 commit 48153c1

File tree

3 files changed

+142
-68
lines changed

3 files changed

+142
-68
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@
5959
<dependency>
6060
<groupId>org.bukkit</groupId>
6161
<artifactId>bukkit</artifactId>
62-
<version>1.4.7-R1.0</version>
62+
<version>1.6.4-R1.0</version>
6363
</dependency>
6464
<dependency>
6565
<groupId>org.dynmap</groupId>
6666
<artifactId>dynmap-api</artifactId>
67-
<version>[0.60,)</version>
67+
<version>1.9</version>
6868
</dependency>
6969
</dependencies>
7070
<properties>

src/main/java/org/dynmap/mobs/DynmapMobsPlugin.java

Lines changed: 136 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
import java.io.IOException;
33
import java.io.InputStream;
44
import java.lang.reflect.Method;
5+
import java.util.ArrayList;
56
import java.util.HashMap;
67
import java.util.HashSet;
8+
import java.util.List;
79
import java.util.Map;
810
import java.util.Set;
911
import java.util.logging.Level;
@@ -18,9 +20,12 @@
1820
import org.bukkit.configuration.file.FileConfiguration;
1921
import org.bukkit.entity.AnimalTamer;
2022
import org.bukkit.entity.Entity;
23+
import org.bukkit.entity.Horse;
24+
import org.bukkit.entity.LivingEntity;
2125
import org.bukkit.entity.Ocelot;
2226
import org.bukkit.entity.Player;
2327
import org.bukkit.entity.Skeleton;
28+
import org.bukkit.entity.Horse.Variant;
2429
import org.bukkit.entity.Skeleton.SkeletonType;
2530
import org.bukkit.entity.Villager;
2631
import org.bukkit.entity.Villager.Profession;
@@ -64,6 +69,9 @@ public class DynmapMobsPlugin extends JavaPlugin {
6469
static String nmspackage;
6570
Method gethandle;
6671

72+
int updates_per_tick = 20;
73+
int vupdates_per_tick = 20;
74+
6775
HashMap<String, Integer> lookup_cache = new HashMap<String, Integer>();
6876
HashMap<String, Integer> vlookup_cache = new HashMap<String, Integer>();
6977

@@ -183,8 +191,7 @@ private static class MobMapping {
183191
new MobMapping("squid", "org.bukkit.entity.Squid", "Squid"),
184192
new MobMapping("villager", "org.bukkit.entity.Villager", "Villager"),
185193
new MobMapping("golem", "org.bukkit.entity.IronGolem", "Iron Golem"),
186-
new MobMapping("vanillahorse", "org.bukkit.entity.Animals", "Horse", "net.minecraft.server.EntityHorse")
187-
//TODO: once CB is fixed - new MobMapping("vanillahorse", "org.bukkit.entity.Horse", "Horse")
194+
new MobMapping("vanillahorse", "org.bukkit.entity.Horse", "Horse")
188195
};
189196
private MobMapping configvehicles[] = {
190197
// Explosive Minecart
@@ -210,47 +217,53 @@ public static void info(String msg) {
210217
public static void severe(String msg) {
211218
log.log(Level.SEVERE, msg);
212219
}
213-
214220

215221
private class MobUpdate implements Runnable {
222+
Map<Integer,Marker> newmap = new HashMap<Integer,Marker>(); /* Build new map */
223+
ArrayList<World> worldsToDo = null;
224+
List<LivingEntity> mobsToDo = null;
225+
int mobIndex = 0;
226+
World curWorld = null;
227+
216228
public void run() {
217-
if(!stop) {
218-
updateMobs();
219-
getServer().getScheduler().scheduleSyncDelayedTask(DynmapMobsPlugin.this, new MobUpdate(), updperiod);
229+
if(stop || (mobs == null) || (mobs.length == 0) || (set == null)) {
230+
return;
220231
}
221-
}
222-
}
223-
224-
private class VehicleUpdate implements Runnable {
225-
public void run() {
226-
if(!stop) {
227-
updateVehicles();
228-
getServer().getScheduler().scheduleSyncDelayedTask(DynmapMobsPlugin.this, new VehicleUpdate(), vupdperiod);
232+
// If needed, prime world list
233+
if (worldsToDo == null) {
234+
worldsToDo = new ArrayList<World>(getServer().getWorlds());
229235
}
230-
}
231-
}
232-
233-
private Map<Integer, Marker> mobicons = new HashMap<Integer, Marker>();
234-
private Map<Integer, Marker> vehicleicons = new HashMap<Integer, Marker>();
235-
236-
private int findNext(int idx, String mobid) {
237-
idx++;
238-
if ((idx < mobs.length) && mobs[idx].mobid.equals(mobid)) {
239-
return idx;
240-
}
241-
else {
242-
return mobs.length;
243-
}
244-
}
245-
/* Update mob population and position */
246-
private void updateMobs() {
247-
if((mobs == null) || (mobs.length == 0) || (set == null)) {
248-
return;
249-
}
250-
Map<Integer,Marker> newmap = new HashMap<Integer,Marker>(); /* Build new map */
251-
252-
for(World w : getServer().getWorlds()) {
253-
for(Entity le : w.getLivingEntities()) {
236+
while (mobsToDo == null) {
237+
if (worldsToDo.isEmpty()) {
238+
/* Now, review old map - anything left is gone */
239+
for(Marker oldm : mobicons.values()) {
240+
oldm.deleteMarker();
241+
}
242+
/* And replace with new map */
243+
mobicons = newmap;
244+
// Schedule next run
245+
getServer().getScheduler().scheduleSyncDelayedTask(DynmapMobsPlugin.this, new MobUpdate(), updperiod);
246+
return;
247+
}
248+
else {
249+
curWorld = worldsToDo.remove(0); // Get next world
250+
mobsToDo = curWorld.getLivingEntities(); // Get living entities
251+
mobIndex = 0;
252+
if ((mobsToDo != null) && mobsToDo.isEmpty()) {
253+
mobsToDo = null;
254+
}
255+
}
256+
}
257+
// Process up to limit per tick
258+
for (int cnt = 0; cnt < updates_per_tick; cnt++) {
259+
if (mobIndex >= mobsToDo.size()) {
260+
mobsToDo = null;
261+
break;
262+
}
263+
// Get next entity
264+
LivingEntity le = mobsToDo.get(mobIndex);
265+
mobIndex++;
266+
254267
int i;
255268

256269
/* See if entity is mob we care about */
@@ -354,10 +367,28 @@ else if(mobs[i].mobid.equals("villager")) {
354367
}
355368
}
356369
else if(mobs[i].mobid.equals("vanillahorse")) { /* Check for rider */
370+
Horse h = (Horse)le;
371+
Variant hv = h.getVariant();
372+
switch(hv) {
373+
case DONKEY:
374+
label = "Donkey";
375+
break;
376+
case MULE:
377+
label = "Mule";
378+
break;
379+
case UNDEAD_HORSE:
380+
label = "Undead Horse";
381+
break;
382+
case SKELETON_HORSE:
383+
label = "Skeleton Horse";
384+
break;
385+
default:
386+
break;
387+
}
357388
if(le.getPassenger() != null) { /* Has passenger? */
358389
Entity e = le.getPassenger();
359390
if (e instanceof Player) {
360-
label = mobs[i].label + " (" + ((Player)e).getName() + ")";
391+
label = label + " (" + ((Player)e).getName() + ")";
361392
}
362393
}
363394
}
@@ -381,7 +412,6 @@ else if(mobs[i].mobid.equals("vanillahorse")) { /* Check for rider */
381412
continue;
382413
}
383414
}
384-
385415
/* See if we already have marker */
386416
double x = Math.round(loc.getX() / res) * res;
387417
double y = Math.round(loc.getY() / res) * res;
@@ -394,35 +424,66 @@ else if(inc_coord) {
394424
label = label + " [" + (int)x + "," + (int)y + "," + (int)z + "]";
395425
}
396426
if(m == null) { /* Not found? Need new one */
397-
m = set.createMarker("mob"+le.getEntityId(), label, w.getName(), x, y, z, mobs[i].icon, false);
427+
m = set.createMarker("mob"+le.getEntityId(), label, curWorld.getName(), x, y, z, mobs[i].icon, false);
398428
}
399429
else { /* Else, update position if needed */
400-
m.setLocation(w.getName(), x, y, z);
430+
m.setLocation(curWorld.getName(), x, y, z);
401431
m.setLabel(label);
402432
m.setMarkerIcon(mobs[i].icon);
403433
}
404434
newmap.put(le.getEntityId(), m); /* Add to new map */
405435
}
436+
getServer().getScheduler().scheduleSyncDelayedTask(DynmapMobsPlugin.this, this, 1);
406437
}
407-
/* Now, review old map - anything left is gone */
408-
for(Marker oldm : mobicons.values()) {
409-
oldm.deleteMarker();
410-
}
411-
/* And replace with new map */
412-
mobicons = newmap;
413438
}
414439

415-
/* Update vehicle population and position */
416-
private void updateVehicles() {
417-
if((vehicles == null) || (vehicles.length == 0) || (vset == null)) {
418-
return;
419-
}
440+
private class VehicleUpdate implements Runnable {
420441
Map<Integer,Marker> newmap = new HashMap<Integer,Marker>(); /* Build new map */
421-
422-
for(World w : getServer().getWorlds()) {
423-
for(Entity le : w.getEntitiesByClasses(org.bukkit.entity.Vehicle.class)) {
424-
int i;
442+
ArrayList<World> worldsToDo = null;
443+
List<Entity> vehiclesToDo = null;
444+
int vehiclesIndex = 0;
445+
World curWorld = null;
446+
447+
public void run() {
448+
if(stop || (vehicles == null) || (vehicles.length == 0) || (vset == null)) {
449+
return;
450+
}
451+
// If needed, prime world list
452+
if (worldsToDo == null) {
453+
worldsToDo = new ArrayList<World>(getServer().getWorlds());
454+
}
455+
while (vehiclesToDo == null) {
456+
if (worldsToDo.isEmpty()) {
457+
/* Now, review old map - anything left is gone */
458+
for(Marker oldm : vehicleicons.values()) {
459+
oldm.deleteMarker();
460+
}
461+
/* And replace with new map */
462+
vehicleicons = newmap;
463+
// Schedule next run
464+
getServer().getScheduler().scheduleSyncDelayedTask(DynmapMobsPlugin.this, new VehicleUpdate(), vupdperiod);
465+
return;
466+
}
467+
else {
468+
curWorld = worldsToDo.remove(0); // Get next world
469+
vehiclesToDo = new ArrayList<Entity>(curWorld.getEntitiesByClasses(org.bukkit.entity.Vehicle.class)); // Get vehicles
470+
vehiclesIndex = 0;
471+
if ((vehiclesToDo != null) && vehiclesToDo.isEmpty()) {
472+
vehiclesToDo = null;
473+
}
474+
}
475+
}
476+
// Process up to limit per tick
477+
for (int cnt = 0; cnt < vupdates_per_tick; cnt++) {
478+
if (vehiclesIndex >= vehiclesToDo.size()) {
479+
vehiclesToDo = null;
480+
break;
481+
}
482+
// Get next entity
483+
Entity le = vehiclesToDo.get(vehiclesIndex);
484+
vehiclesIndex++;
425485

486+
int i;
426487
/* See if entity is vehicle we care about */
427488
String clsid = null;
428489
if(gethandle != null) {
@@ -468,7 +529,7 @@ else if(gethandle != null) {
468529
label = vehicles[i].label;
469530
}
470531
Location loc = le.getLocation();
471-
if(w.isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4) == false) {
532+
if(curWorld.isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4) == false) {
472533
continue;
473534
}
474535
Block blk = null;
@@ -484,7 +545,6 @@ else if(gethandle != null) {
484545
continue;
485546
}
486547
}
487-
488548
/* See if we already have marker */
489549
double x = Math.round(loc.getX() / res) * res;
490550
double y = Math.round(loc.getY() / res) * res;
@@ -496,22 +556,30 @@ else if(vinc_coord) {
496556
label = label + " [" + (int)x + "," + (int)y + "," + (int)z + "]";
497557
}
498558
if(m == null) { /* Not found? Need new one */
499-
m = vset.createMarker("vehicle"+le.getEntityId(), label, w.getName(), x, y, z, vehicles[i].icon, false);
559+
m = vset.createMarker("vehicle"+le.getEntityId(), label, curWorld.getName(), x, y, z, vehicles[i].icon, false);
500560
}
501561
else { /* Else, update position if needed */
502-
m.setLocation(w.getName(), x, y, z);
562+
m.setLocation(curWorld.getName(), x, y, z);
503563
m.setLabel(label);
504564
m.setMarkerIcon(vehicles[i].icon);
505565
}
506566
newmap.put(le.getEntityId(), m); /* Add to new map */
507567
}
568+
getServer().getScheduler().scheduleSyncDelayedTask(DynmapMobsPlugin.this, this, 1);
508569
}
509-
/* Now, review old map - anything left is gone */
510-
for(Marker oldm : vehicleicons.values()) {
511-
oldm.deleteMarker();
570+
}
571+
572+
private Map<Integer, Marker> mobicons = new HashMap<Integer, Marker>();
573+
private Map<Integer, Marker> vehicleicons = new HashMap<Integer, Marker>();
574+
575+
private int findNext(int idx, String mobid) {
576+
idx++;
577+
if ((idx < mobs.length) && mobs[idx].mobid.equals(mobid)) {
578+
return idx;
579+
}
580+
else {
581+
return mobs.length;
512582
}
513-
/* And replace with new map */
514-
vehicleicons = newmap;
515583
}
516584

517585
private class OurServerListener implements Listener {
@@ -672,6 +740,7 @@ private void activate() {
672740
double per = cfg.getDouble("update.period", 5.0);
673741
if(per < 2.0) per = 2.0;
674742
updperiod = (long)(per*20.0);
743+
updates_per_tick = cfg.getInt("update.mobs-per-tick", 20);
675744
stop = false;
676745
getServer().getScheduler().scheduleSyncDelayedTask(this, new MobUpdate(), updperiod);
677746
info("Enable layer for mobs");
@@ -738,6 +807,7 @@ private void activate() {
738807
double per = cfg.getDouble("update.vehicleperiod", 5.0);
739808
if(per < 2.0) per = 2.0;
740809
vupdperiod = (long)(per*20.0);
810+
vupdates_per_tick = cfg.getInt("update.vehicles-per-tick", 20);
741811
stop = false;
742812
getServer().getScheduler().scheduleSyncDelayedTask(this, new VehicleUpdate(), vupdperiod / 3);
743813
info("Enable layer for vehicles");

src/main/resources/config.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ update:
1111
hideifshadow: 4
1212
# Make markers hidden when they are under cover (#=sky light level,0=underground,15=open to sky(disable hide))
1313
hideifundercover: 15
14+
# Mob updates per tick (prevent lag spikes when large number of mobs)
15+
mobs-per-tick: 20
16+
# Vehicle updates per tick (prevent lag spikes when large number of vehicles)
17+
vehicles-per-tick: 20
1418

1519
mobs:
1620
# Include creepers

0 commit comments

Comments
 (0)