NoGrind
NoGrind
A customizable mob farm remover.
Are you running a server with an economy? Sick of your players HAVING to have a mob spawner just to keep up with the jonses? This plugin removes all mob drops unless players themselves use a sword or a projectile to kill a mob.
Unlike other plugins that accomplish this, this plugin doesn't just track the last hit, and doesn't stop music discs from dropping.
How it works:
When players hit a creature with a sword, or with a projectile, the plugin tags and tracks the entity that was hit for a period of time, which is configurable by the server host (via the config file). If the mob dies within this window of time, it will drop items and experience normally. If the mob is not tagged and tracked by the plugin as being hit, it will drop nothing.
Why did I make this?
The server I work for has been using another anti mob farm plugin for some time. We had the following annoyances with it, all of which, my plugin addresses:
- Mobs killed by Flaming Aspect damage immediately after a strike would not yield drops.
- Some did not allow drops from kills with arrows.
- Some did not distinguish between kills with arrows from players, mobs, dispensors.
- Mobs killed by fall damage after a knockback would not yield drops.
Since each of these required a duration-based combat tagging system, I decided that it would be best to write my own, this made it quite a departure from how our previous plugin worked. This addressed each of our issues with it, so we decided to use it on our server before dispenser-farms became a problem. Since we were using it for our server, and it only took about half an hour to write, I figured I would share it with bukkit.
This sounds inefficient, you say?
I can assure you that this is highly efficient. Combat tags are sorted into a single queue, and only a single Asynchronous event is running at a time, no matter how many mobs are in the queue. The queue itself will not overflow, and cleans itself up in the order that mobs were struck. If a mob is removed prematurely, the plugin will be able to carry on happily as though nothing happened.
The timer system will not take up much memory, nor will it take up much CPU at all. This is a very lightweight method of handling this. Though it isn't as simplistic or lightweight as other plugins that do the same thing, the difference in performance is negligible, while the benefits of NoGrind are clear.
Regrettably, there are known bugs:
- Monsters damaged by potions will not be combat tagged. This is a bukkit bug.
Future Additions:
I will be writing two optional modules for this plugin.
Module #1: Will allow server administrators to change what mobs drop, and the likelihood of the items dropping through customization of loot tables on a per-monster, per world basis.
Module #2: Will interface with economy plugins to permit mobs to drop money, or to give money directly to the player.
I will be writing several configurable options for this plugin:
- Options to configure the amount of experience you get from each mob, modifiers for worlds, etc.
- Experience per hit instead of on death (Optional)
- Experience given to player directly, instead of dropped (Optional)
Source code
Source is available on github and bukkit.
it also does not work in 1.8! thats such an awesome and simple plugin i wonder if it could get updated by anyone again sometime :)
it dont work for 1.7.10
Anyone know if this still works?
How can this work? Most grinders weaken mobs to one hit kills, so that players can kill them and get the XP. So, the mobs will still be hit by a player right before they die!
@toxuin
This plugin was a fork for the NoFarm plugin, you should check that one out and ask him for your Pull Request.
@Darkhand81
My modification of NoGrind is a really small part of the entire plugin and does not modify it in the way it could make it a totally new and different plugin. I hope someday TerXII will come back to us and accept my pull request on GitHub...:)
@toxuin
Wow thanks puksa! You should start a project here on dev.bukkit.org as an official fork. :)
FINALLY! I updated this plugin for potion support!
Here's a link to always-latest-version.
@toxuin
Thanks for updating puksa!
Are potions handled now? I noticed DamageCause.PROJECTILE in the code but am not sure if potions are covered in that. Are potions handled separately?
I hopefuly ported this to the new event system. Please test. https://github.com/toxuin/NoGrind
I sent author a pull-request, but he seems to be dead.
Any thoughts on updating for MC 1.2.3? In particular I'm looking for a way to prevent XP grinders...but I'm not sure this plugin would help with that.
@TerXIII
With R4, there are now damage events triggered for healing and harming with potions. Will supporting potions take an update to nogrind or are they automatically handled now?
Thanks!
@o0AzzA0o
Potions are not recognized by bukkit damage hooks yet. Until then, there's nothing I can really do for you.
@Beatkidz
there is worse then that i have players throwing health pots at 20 mobs at time and getting 433 lvls in like 1 min np at all. I need to find a fix hoping this was it but looks like dead end till bukkit fixes
Can you make your plug-in check the mobs health before the combat tag. I have a problem with players making farms where mobs fall 23 blocks down then it only takes 1 punch to kill them. hitting exp levels of 85 in 5 minutes in some cases.
@LanToaster
It already should.
Can you expand the Config so a player can use any Item or Not Item in the hand to tag a Mob?
Except this, the Plugin sounds amazing.
@andune
Thank you for this bug report. I will fix this as soon as humanly possible. Expect an update in an hour. I'm sorry I didn't get back to this sooner, but I'm in the middle of a full reinstall of my system. I wound up with a system restore failing after a power outage, and I've just now got windows booting, but more than a bit of my windows system files are now... less than adequately working.
Anyway, that bit that you noticed, is an embarrassing hanging-over from a previous methodology of dealing with the loop, which I forgot to fix before pushing the release. Thanks again for taking a once-over of my source.
Also note, you can change your configure() method to be just one line and thereby remove a lot of unnecessary code in your NoGrind class:
Here, 5 being the default. Just rename to file config.cfg to config.yml and modify the format to be "combatTagSeconds: 5". Bukkit does all the work for you.
@TerXIII
I appreciate you making this plugin available, I used to use the other plugin but had to remove it due to too many player complaints of the sort that this plugin solves. I've reviewed your code and am happy with the implementation being reasonably efficient on a smallish server (of which mine is). On a larger server (40+), I could see HashMaps being superior to the ArrayList .equals() loops. But I digress.
I write here to inform you of a bug in tagExpire(). While looping, you call .remove() on the arrays, meaning the array count shifts and then you increment your count variable. So assume 5 elements, count=0. The first element is found to be expired and thus removed, now there are 4 elements (0-3) and your count is incremented to 1. Next loop you are checking element 1, which used to be element 2. The old element 1 has moved to 0 and is not checked. Thus every loop you are only checking every other element of the array. (of course eventually they will all get removed, although your (tt-ct) will eventually go negative, which you account for in startTimer - but all that extra work is less efficient than just iterating without this bug in the first place :) )..
Assuming that the arrays are always stacked in order (which I believe they are from looking at the rest of the code), you could simple not use the count variable and always work with element 0 (since you're basically .remove()'ing every element until element 0 is no longer one scheduled to be removed).