Anti-Camping Features
javacraft opened this issue ยท 11 comments
Greetings mung3r:
First, thank you for this plugin and I don't mean that lightheartedly. We have suffered through the demise of several mob economy-related plugins over the past 15 months - Mob Drops, MobBounty, Mobs4Cash, OtherDrops, etc. We already maintain a slew of in-house versions for plugins that were abandoned by their developers over the year or that just didn't want to be flexible enough. I was happy to find your plugin and the flexibility and ease in which it offers the ability to customize mob drops. So, once again thank you for maintaining this plugin and eliminating the need for me to have yet another in-house plugin project :)
That said, we have a need to limit custom drops from mob spawners. While we don't discourage spawner farms, we try to motive our players to make cash in more productive and community-orient ways. Thus, I was very happy to see that ecoCreature had anti-camping features. Unfortunately, they have some shortcomings.
CampingByDistance obviously is limited by range. Thus it is possible for players to draw mobs farther than the set radius and still get custom drops. That in itself is not a problem; the problem is that naturally spawned mobs are also affected by CampRadius. This has become particularly evident with Withered Skeletons many of which naturally spawn near Blaze spawners and if killed in place will not result in any drops because they are too close to a spawner. This forces our players to go through extra measures drawing skeletons away from spawners in hope of getting their much coveted skulls.
CampingByEntity solves this problem to degree as ecoCreature will still reward players with drops from naturally occurring mobs. However, this mode prevents ALL drops from spawned mobs. We have OverrideDrops set to false and had expected that in such cases ecoCreature would not drop any additional rewards such as configured cash or item rewards but would still allow natural drops. Unfortunately, this is not the case. This behavior essentially limits a spawner as an XP farm.
I believe the simplest solution to solving both shortcomings is to tag spawned mobs regardless of whether CampingByDistance or CampingByEntity is set. When a critter is killed and is not tagged continue processing drops. If the mob is tagged and CampingByDistance is on, evaluate range and proceed from there. This allows naturally occurring mobs to still drop rewards even if they are on top of a spawner.
Add an additional configuration item - NaturalCampDrops - to control whether natural drops are allowed while camping. When killed critters do not meet any camping criteria, process drops per ecoCreature configurations. However, if a camping criteria is met then allow natural drops if NaturalCampDrops is true or prevent all drops if NaturalCampDrops is false.
If you have any additional questions or comments, please don't hesitate to contact me.
Best regards,
Frelling
Clear and well written. I don't think this would take much effort to correct.
Thanks for your interest in the plugin and the kind words.
There is one issue to consider. It appears that mobs have a different entity ID after a chunk load and unload. Implications are that the hash used to tag mobs could grow without bound for the life of the server between restarts.
I support this! We on our server are experiencing the same issue as javacraft explains in his text.
Can we expect this or a similar feature to be implemented soon?
Thanks for this awesome Plugin!
Greetings Philipp
Greeting mug3r:
My apologies for the lagged reply, I was away on business travel. Given what you said about different entity ids, I am assuming that your approach is to maintain a separate hash of entity flags. Rather than rolling your own, I suggest that you use Bukkit Metadata API. This should assure that tags remains associated with their corresponding entities regardless of what happens behind the scenes.
Unfortunately, I'm once again busy with our server and the latest 1.4.5 Beta release, so this sample snippet will have to do.
#
# Sample snippet of an entity listener that marks spawner mobs with metadata falg
#
public class EntityListener implements Listener {
public static final String SPAWN_TAG_MDID = "ecoCreature.spawned";
private FixedMetadataValue spawnerTag;
public EntityListener( JavaPlugin myPlugin ) {
this.spawnerTag = new FixedMetadataValue( myPlugin, true );
}
...
@EventHandler(priority = EventPriority.MONITOR)
public void onCreatureSpawn( CreatureSpawnEvent evt ) {
if ( evt.isCancelled() )
return;
if ( evt.getSpawnReason() == SpawnReason.SPAWNER ) {
evt.getEntity().setMetadata( SPAWN_TAG_MDID, spawnerTag );
}
...
}
}
From there its a matter of just creating a utility function to check if an entity is sourced from a spawner. For example, a method as follows would suffice.
public boolean isSpawned( Entity ent ) {
return ent.hasMetadata( EntityListener.SPAWN_TAG_MDID )
}
This is a very simple check. If your metadata tag is multi-valued, then it needs to be retrieved and have its value checked (the above assumes that if present the tag is true and if not the tag is false). Furthermore, it is possible that another plugin may have the exact metadata id, in which case, the sourcing plugin reference needs to be checked. Fortunately, a name space collision within metadata tables can be minimized if you treat them like permission labels - unique enough to retain identity, yet short enough to avoid lengthy string comparisons/hashes.
The only caveat is that metadata does not persist between server sessions.
Wow, I learned something new today - thanks! I'm anxious to implement this so expect to see the changes very shortly.
On another related note, after re-reading this issue, I realized that the OverrideDrops problem you encountered is similar to issue #90 which has been addressed. In any case, I'm going to implement the tagging since it's a cleaner method of tracking spawner mobs.
Couple hundred Zombies and Skeletons later, here are my findings:
With either CampingByDistance or CampingByEntity enabled, mobs will drop their default loot IF AND ONLY IF there is no corresponding mob reward configuration defined in default.yml. If a reward configuration is defined - say a monetary reward - mobs will not drop anything at all if they are considered camped.
Given OverrideDrops set to false, the expectation is that camped mobs drop their default loot, but no additional loot defined by ecoCreature. If OverrideDrops was set to true, it is expected that camped mobs would drop nothing at all. Obviously, what should/shouldn't happen can be subjective, but in general plugins should be additive in the features they provide unless specifically configured otherwise.
ecoCreatures sort of straddling both sides of the issue. Without any reward configurations, ecoCreatures allows natural drops regardless of whether anti-camping features are enabled. When a reward configuration is set, the default drop behavior is prevented regardless of the OverrideDrops setting. This should only occur if OverrideDrops is true.
I've observed this with the release on BukkitDev and repo build.
Alright, I will run ecoCreature through its paces with the beta build. I did see that issue was noted as resolved in the repo source, but I only used what was published on BukkitDev (v0.2.1); although I could have mistakenly used an older version. I'll report back and let you know what I find out.
I'm happy I was able to further some knowledge :)
I decided to put together this truth table using the latest dev/beta build that includes the commit in the last comment. Hopefully, this will shed some light on how the different drop config settings work.
Works as expected. With ClearCampDrops set to false, spawned mobs now drop their natural drops but no additional rewards. When set to true, nothing drops from spawned mobs. Thank you for see this implemented.
Best,
Frelling