Skip to content

Commit

Permalink
Individual golden apple cooldown (#446)
Browse files Browse the repository at this point in the history
  • Loading branch information
I-Al-Istannen authored Aug 9, 2020
1 parent 0efd9dc commit faebd51
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

import kernitus.plugin.OldCombatMechanics.OCMMain;
import kernitus.plugin.OldCombatMechanics.utilities.Messenger;
import org.bukkit.*;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Statistic;
import org.bukkit.World;
import org.bukkit.advancement.Advancement;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.LivingEntity;
Expand All @@ -19,7 +24,16 @@
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;

import java.util.*;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.UUID;

import static kernitus.plugin.OldCombatMechanics.versions.materials.MaterialRegistry.ENCHANTED_GOLDEN_APPLE;

Expand All @@ -31,8 +45,8 @@ public class ModuleGoldenApple extends Module {
private List<PotionEffect> enchantedGoldenAppleEffects, goldenAppleEffects;
private ShapedRecipe enchantedAppleRecipe;

private Map<UUID, Long> lastEaten;
private long cooldown;
private Map<UUID, LastEaten> lastEaten;
private Cooldown cooldown;

public ModuleGoldenApple(OCMMain plugin){
super(plugin, "old-golden-apples");
Expand All @@ -41,12 +55,12 @@ public ModuleGoldenApple(OCMMain plugin){
@SuppressWarnings("deprecated")
@Override
public void reload(){
cooldown = module().getInt("cooldown");
if(cooldown > 0) {
if (lastEaten == null) lastEaten = new HashMap<>();
} else{
lastEaten = null; // disable tracking eating times
}
cooldown = new Cooldown(
module().getLong("cooldown.normal"),
module().getLong("cooldown.enchanted"),
module().getBoolean("cooldown.is-shared")
);
lastEaten = new HashMap<>();

enchantedGoldenAppleEffects = getPotionEffects("napple");
goldenAppleEffects = getPotionEffects("gapple");
Expand Down Expand Up @@ -111,14 +125,12 @@ public void onItemConsume(PlayerItemConsumeEvent e){
e.setCancelled(true);

// Check if the cooldown has expired yet
if(lastEaten != null) {
final long currentTime = System.currentTimeMillis() / 1000;
final UUID uuid = p.getUniqueId();
if (lastEaten.containsKey(uuid) && currentTime - lastEaten.get(uuid) < cooldown)
return;
lastEaten.putIfAbsent(p.getUniqueId(), new LastEaten());

lastEaten.put(uuid, currentTime);
if(cooldown.isOnCooldown(item, lastEaten.get(p.getUniqueId()))){
return;
}
lastEaten.get(p.getUniqueId()).setForItem(item);

final ItemStack originalItem = e.getItem();
final PlayerInventory inv = p.getInventory();
Expand Down Expand Up @@ -160,17 +172,18 @@ else if(mainHand.getType() == Material.GOLDEN_APPLE || ENCHANTED_GOLDEN_APPLE.is
p.incrementStatistic(Statistic.USE_ITEM, consumedMaterial);

// Call the event as .incrementStatistic doesn't seem to, and other plugins may rely on it
PlayerStatisticIncrementEvent psie = new PlayerStatisticIncrementEvent(p,Statistic.USE_ITEM,initialValue,initialValue+1,consumedMaterial);
PlayerStatisticIncrementEvent psie = new PlayerStatisticIncrementEvent(p, Statistic.USE_ITEM, initialValue, initialValue + 1, consumedMaterial);
Bukkit.getServer().getPluginManager().callEvent(psie);

try {
try{
NamespacedKey nsk = NamespacedKey.minecraft("husbandry/balanced_diet");
Advancement advancement = Bukkit.getAdvancement(nsk);

// Award advancement criterion for having eaten gapple, as incrementing statistic or calling event doesn't seem to
if (advancement != null)
if(advancement != null)
p.getAdvancementProgress(advancement).awardCriteria(consumedMaterial.name().toLowerCase());
} catch (NoClassDefFoundError ignored){} // Pre 1.12 does not have advancements
} catch(NoClassDefFoundError ignored){
} // Pre 1.12 does not have advancements
}

private List<PotionEffect> getPotionEffects(String apple){
Expand Down Expand Up @@ -211,4 +224,58 @@ private void applyEffects(LivingEntity target, List<PotionEffect> effects){
public void onPlayerQuit(PlayerQuitEvent e){
if(lastEaten != null) lastEaten.remove(e.getPlayer().getUniqueId());
}

private static class LastEaten {
private Instant lastNormalEaten;
private Instant lastEnchantedEaten;

private Optional<Instant> getForItem(ItemStack item){
return ENCHANTED_GOLDEN_APPLE.isSame(item)
? Optional.ofNullable(lastEnchantedEaten)
: Optional.ofNullable(lastNormalEaten);
}

private Optional<Instant> getNewestEatTime(){
if(lastEnchantedEaten == null){
return Optional.ofNullable(lastNormalEaten);
}
if(lastNormalEaten == null){
return Optional.of(lastEnchantedEaten);
}
return Optional.of(
lastNormalEaten.compareTo(lastEnchantedEaten) < 0 ? lastEnchantedEaten : lastNormalEaten
);
}

private void setForItem(ItemStack item){
if(ENCHANTED_GOLDEN_APPLE.isSame(item)){
lastEnchantedEaten = Instant.now();
} else {
lastNormalEaten = Instant.now();
}
}
}

private static class Cooldown {
private final long normal;
private final long enchanted;
private final boolean sharedCooldown;

Cooldown(long normal, long enchanted, boolean sharedCooldown){
this.normal = normal;
this.enchanted = enchanted;
this.sharedCooldown = sharedCooldown;
}

private long getCooldownForItem(ItemStack item){
return ENCHANTED_GOLDEN_APPLE.isSame(item) ? enchanted : normal;
}

boolean isOnCooldown(ItemStack item, LastEaten lastEaten){
return (sharedCooldown ? lastEaten.getNewestEatTime() : lastEaten.getForItem(item))
.map(it -> ChronoUnit.SECONDS.between(it, Instant.now()))
.map(it -> it < getCooldownForItem(item))
.orElse(false);
}
}
}
22 changes: 20 additions & 2 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,25 @@ old-golden-apples:
enabled: true
worlds: []
# Cooldown between eating the apples, in seconds
cooldown: 0
cooldown:
# The cooldown for normal golden apples
normal: 0
# The cooldown for enchanted golden apples
enchanted: 0
# Whether the two apple types share a cooldown.
# If this is true:
# 1. Eating any apple resets both cooldowns
# 2. Each apple type can only be eaten when its cooldown time is over
# This means that when you eat *any* apple you start two parallel cooldowns: One for enchanted and one
# for normal apples. Each type can only be eaten when its cooldown is over.
# Once any apple is eaten, both cooldowns are restarted, so you can not eat either type again
# before its full cooldown is over.
# 3. To have the plugin treat normal and enchanted golden apples as having the same cooldown,
# then set the same cooldown time and enable shared mode. (This was the old mode)
# If this is false:
# Eating an enchanted apple will prevent any *enchanted* apple type from being eaten before the cooldown is over
# Eating a normal apple will prevent any *normal* apple type from being eaten before the normal cooldown is over
is-shared: false
# If you want to allow enchanted golden apple crafting
enchanted-golden-apple-crafting: true
# Enabling this makes the potion effects gained by eating golden apples
Expand Down Expand Up @@ -460,4 +478,4 @@ debug:
enabled: false

# DO NOT CHANGE THIS NUMBER AS IT WILL RESET YOUR CONFIG
config-version: 43
config-version: 44

0 comments on commit faebd51

Please sign in to comment.