package de.tobiyas.racesandclasses.entitystatusmanager.silence; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.UUID; import de.tobiyas.racesandclasses.traitcontainer.interfaces.markerinterfaces.MagicSpellTrait; import de.tobiyas.racesandclasses.traitcontainer.interfaces.markerinterfaces.TraitWithCost; public class SilenceAndKickManager { /** * The map of people that are silenced -> when they are silenced. */ private Map<UUID,Long> silenceMap = new HashMap<>(); /** * The map of people that are silenced -> when they are silenced. */ private Map<UUID,Set<MagicSpellTrait>> currentlyCastingMap = new HashMap<>(); /** * Notifies that the player starts channeling. * @param entityID to start. * @param spell to start. */ public void startsChannel(UUID entityID, MagicSpellTrait spell){ double channelTime = spell.getChannelingTime(); if(channelTime > 0) { Set<MagicSpellTrait> traits = currentlyCastingMap.get(entityID); if(traits == null) { traits = new HashSet<>(); currentlyCastingMap.put(entityID, traits); } traits.add(spell); } } /** * Ends the current Channel. * @param id to remove. */ public void endChannel(UUID entityID, TraitWithCost trait){ Set<MagicSpellTrait> traits = currentlyCastingMap.get(entityID); if(traits == null) return; traits.remove(traits); } /** * If the Entity is channeling. * @param entityID that is channeling. * @return true if is channeling. */ public boolean isChanneling(UUID entityID){ Set<MagicSpellTrait> traits = currentlyCastingMap.get(entityID); if(traits != null && !traits.isEmpty()) return false; for(MagicSpellTrait trait : traits) if(trait.isKickable()) return true; return false; } /** * Kicks the Entity that is channeling. * @param entityID that is channeling. * @param timeInMs to kick. * @return true kicked something. */ public boolean kickChanneling(UUID entityID, long timeInMs){ Set<MagicSpellTrait> traits = currentlyCastingMap.get(entityID); if(traits == null || traits.isEmpty()) return false; int kicked = 0; Iterator<MagicSpellTrait> it = traits.iterator(); while(it.hasNext()){ MagicSpellTrait trait = it.next(); if(!trait.isKickable()) continue; trait.gotKicked(entityID); it.remove(); kicked++; } if(kicked > 0) silenceMap.put(entityID, System.currentTimeMillis() + timeInMs); return kicked > 0; } /** * Silences the Entity. * @param entityID that is channeling. * @param timeInMs to kick. * @return true kicked something. */ public boolean silence(UUID entityID, long timeInMs){ boolean interrupted = kickChanneling(entityID, timeInMs); if(!interrupted) silenceMap.put(entityID, System.currentTimeMillis() + timeInMs); return interrupted; } /** * If the Entity is silenced. * @param entityID to check * @return true if is silenced. */ public boolean isSilenced(UUID entityID){ if(entityID == null || !silenceMap.containsKey(entityID)) return false; return System.currentTimeMillis() < silenceMap.get(entityID); } /** * Returns the rest time the entity is silenced (in MiliSeconds). * @param entityID to get. */ public long getRestSilenceTime(UUID entityID){ if(entityID == null || !silenceMap.containsKey(entityID)) return 0; long rest = silenceMap.get(entityID) - System.currentTimeMillis(); return Math.max(0, rest); } }