[Suggestion] Reduce Cooldown enchantment
min2222 opened this issue ยท 4 comments
how about make reduce cooldown(not attack cooldown) enchantment for 1.12.2? when enchantment level is increased, cooldown of item is decreased i guess it very useful
because many mod using cooldown system like this:
but sometime i wanna use it without cooldown in creative mod
so if you make this enchantment it will very useful
and last thank you for leading my suggenstion
i hope to you make this
Heya,
thanks for your Suggestion, let's be clear.
I do like the idea, but on the other hand I have some concerns in regards of Mod Interaction and balancing.
Some Mod Devs have their reasons to set the cooldown to a certain point.
That being said, which Items(maybe also modded) specifically did you have in mind while suggesting this Enchantment?
@min2222 wow such a overengineered mod.
This is so much overhead. I would never install that.
I looked into that and what i can tell you is you could have just reflection accessed the ServerCooldown tracker on a PlayerTickEvent (Filtering for server side) and just cleared the list and just send packets to the client that the cooldown got removed. Like this is a 1-2kb mod with maybe 50-60 lines of code.
And just to proof my point:
@Mod(modid = "example", version = "example", name = "example")
public class CooldownRemover
{
@EventHandler
public void onPreInit(FMLPreInitializationEvent event)
{
MinecraftForge.EVENT_BUS.register(this);
}
@SubscribeEvent
public void onPlayerTickEvent(PlayerTickEvent event)
{
if(event.phase == Phase.START || event.side.isClient())
{
return;//We want to do this after the player actions were done that way input packets were processed.
}
try
{
CooldownTracker tracker = event.player.getCooldownTracker();
Map<Item, ?> map = ReflectionHelper.getPrivateValue(CooldownTracker.class, tracker, "cooldowns", "field_185147_a");
if(map == null || map.isEmpty())
{
return;
}
for(Item item : map.keySet())
{
((EntityPlayerMP)event.player).connection.sendPacket(new SPacketCooldown(item, 0));
}
map.clear();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
And if you want to link that to a specific item, that is fine too just add the item into the check before the try.
The try Catch exists because i prefer not to use ASM because it is overkill. But you could use a Access Transformer to make all this public so no reflection would be needed.
And if we cut the very lengthy code into something compressed this results in almost have the size of the original i just rushed in 5 minutes.
@Mod(modid = "example", version = "example", name = "example")
public class CooldownRemover {
@EventHandler
public void onPreInit(FMLPreInitializationEvent event) {
MinecraftForge.EVENT_BUS.register(this);
}
@SubscribeEvent
public void onPlayerTickEvent(PlayerTickEvent event) {
if(event.phase == Phase.END && event.side.isServer()) {
try {
Map<Item, ?> map = ReflectionHelper.getPrivateValue(CooldownTracker.class, event.player.getCooldownTracker(), "cooldowns", "field_185147_a");
if(map != null && !map.isEmpty()) {
for(Iterator<Item> iter = map.keySet().iterator();iter.hasNext();iter.remove()) {
((EntityPlayerMP)event.player).connection.sendPacket(new SPacketCooldown(item, 0));
}
}
}
catch(Exception e) {}
}
}
}