/******************************************************************************* * Copyright 2014 Tob * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package de.tobiyas.racesandclasses.traitcontainer.traits.defaultraits.activate.HealOthersTrait; import java.util.LinkedList; import java.util.List; import org.bukkit.ChatColor; import org.bukkit.Effect; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.bukkit.event.block.Action; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; import org.bukkit.event.player.PlayerEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; import de.tobiyas.racesandclasses.APIs.LanguageAPI; import de.tobiyas.racesandclasses.configuration.traits.TraitConfig; import de.tobiyas.racesandclasses.eventprocessing.TraitEventManager; import de.tobiyas.racesandclasses.eventprocessing.eventresolvage.EventWrapper; import de.tobiyas.racesandclasses.eventprocessing.eventresolvage.PlayerAction; import de.tobiyas.racesandclasses.eventprocessing.events.entitydamage.EntityHealEvent; import de.tobiyas.racesandclasses.eventprocessing.events.entitydamage.EntityHealOtherEntityEvent; import de.tobiyas.racesandclasses.playermanagement.player.RaCPlayer; import de.tobiyas.racesandclasses.playermanagement.player.RaCPlayerManager; import de.tobiyas.racesandclasses.traitcontainer.interfaces.AbstractBasicTrait; import de.tobiyas.racesandclasses.traitcontainer.interfaces.TraitResults; import de.tobiyas.racesandclasses.traitcontainer.interfaces.annotations.configuration.TraitConfigurationField; import de.tobiyas.racesandclasses.traitcontainer.interfaces.annotations.configuration.TraitConfigurationNeeded; import de.tobiyas.racesandclasses.traitcontainer.interfaces.annotations.configuration.TraitEventsUsed; import de.tobiyas.racesandclasses.traitcontainer.interfaces.annotations.configuration.TraitInfos; import de.tobiyas.racesandclasses.traitcontainer.interfaces.markerinterfaces.Trait; import de.tobiyas.racesandclasses.translation.languages.Keys; import de.tobiyas.racesandclasses.util.bukkit.versioning.compatibility.CompatibilityModifier; import de.tobiyas.racesandclasses.util.traitutil.TraitConfiguration; import de.tobiyas.racesandclasses.util.traitutil.TraitConfigurationFailedException; public class HealOthersTrait extends AbstractBasicTrait { private double value; private static Material itemIDInHand = Material.STRING; private static boolean consume = true; @TraitInfos(category="activate", traitName="HealOthersTrait", visible=true) @Override public void importTrait() { } @SuppressWarnings("deprecation") @TraitEventsUsed(registerdClasses = {PlayerInteractEntityEvent.class, PlayerInteractEvent.class}) @Override public void generalInit() { TraitConfig config = plugin.getConfigManager().getTraitConfigManager().getConfigOfTrait(getName()); if(config != null){ itemIDInHand = Material.getMaterial((Integer) config.getValue("trait.iteminhand", Material.STRING.getId())); consume = (Boolean) config.getValue("trait.consume", true); } } @Override public String getName() { return "HealOthersTrait"; } @Override protected String getPrettyConfigIntern(){ return "heals: " + value; } @TraitConfigurationNeeded(fields = { @TraitConfigurationField(fieldName = "value", classToExpect = Double.class) }) @Override public void setConfiguration(TraitConfiguration configMap) throws TraitConfigurationFailedException { super.setConfiguration(configMap); value = (Double) configMap.get("value"); } @Override public TraitResults trigger(EventWrapper eventWrapper) { Event event = eventWrapper.getEvent(); if(event instanceof PlayerInteractEntityEvent || event instanceof PlayerInteractEvent){ boolean isSneaking = ((PlayerEvent) event).getPlayer().isSneaking(); if(!isSneaking){ return TraitResults.False(); } if(event instanceof PlayerInteractEntityEvent){ PlayerInteractEntityEvent Eevent = (PlayerInteractEntityEvent) event; Entity target = Eevent.getRightClicked(); if(target != null && target instanceof Player){ return new TraitResults(playerInteractsWithPlayer(Eevent.getPlayer(), (Player) target)); } return TraitResults.False(); } if(event instanceof PlayerInteractEvent){ PlayerInteractEvent Eevent = (PlayerInteractEvent) event; Action action = Eevent.getAction(); if(action == Action.RIGHT_CLICK_AIR){ Player player = Eevent.getPlayer(); return new TraitResults(playerInteractWithSelf(player)); } return TraitResults.False(); } } return TraitResults.False(); } private boolean playerInteractWithSelf(Player player) { double maxHealth = CompatibilityModifier.BukkitPlayer.safeGetMaxHealth(player); double currentHealth = CompatibilityModifier.BukkitPlayer.safeGetHealth(player); if(currentHealth >= maxHealth) { LanguageAPI.sendTranslatedMessage(player, Keys.trait_heal_target_full); return false; } double amount = modifyToPlayer(RaCPlayerManager.get().getPlayer(player), value, "value"); if(currentHealth + amount > maxHealth) amount = maxHealth - currentHealth; EntityHealEvent entityHealEvent = new EntityHealOtherEntityEvent(player, amount, RegainReason.MAGIC, player); TraitEventManager.fireEvent(entityHealEvent); if(entityHealEvent.isCancelled()) return false; amount = CompatibilityModifier.EntityHeal.safeGetAmount(entityHealEvent); //Never overheal! this gives an Exception! if(currentHealth + amount > maxHealth) amount = maxHealth - currentHealth; if(!entityHealEvent.isCancelled() && amount >= 0){ double newHealth = currentHealth + amount; CompatibilityModifier.BukkitPlayer.safeSetHealth(newHealth, player); Location loc = entityHealEvent.getEntity().getLocation(); loc.getWorld().playEffect(loc, Effect.POTION_BREAK, 1); LanguageAPI.sendTranslatedMessage(player, Keys.trait_healed_target_success, "target", player.getName()); if(consume){ int newAmount = player.getItemInHand().getAmount() - 1; if(newAmount == 0){ player.setItemInHand(new ItemStack(Material.AIR)); }else{ player.getItemInHand().setAmount(newAmount); } } return true; } return false; } private boolean playerInteractsWithPlayer(Player playerInteracting, Player target) { double maxHealth = CompatibilityModifier.BukkitPlayer.safeGetMaxHealth(target); double currentHealth = CompatibilityModifier.BukkitPlayer.safeGetHealth(target); if(currentHealth >= maxHealth){ LanguageAPI.sendTranslatedMessage(playerInteracting, Keys.trait_heal_target_full); return false; } double amount = modifyToPlayer(RaCPlayerManager.get().getPlayer(playerInteracting), value, "value"); if(currentHealth + amount > maxHealth) amount = maxHealth - currentHealth; Player targetPlayer = (Player) target; EntityHealEvent entityHealEvent = new EntityHealOtherEntityEvent(targetPlayer, value, RegainReason.MAGIC, playerInteracting); TraitEventManager.fireEvent(entityHealEvent); if(entityHealEvent.isCancelled()) return false; amount = CompatibilityModifier.EntityHeal.safeGetAmount(entityHealEvent); if(currentHealth + amount > maxHealth) amount = maxHealth - currentHealth; if(!entityHealEvent.isCancelled() && amount != 0){ double newHealth = currentHealth + amount; CompatibilityModifier.BukkitPlayer.safeSetHealth(newHealth, target); Location loc = entityHealEvent.getEntity().getLocation(); loc.getWorld().playEffect(loc, Effect.POTION_BREAK, 1); LanguageAPI.sendTranslatedMessage(playerInteracting, Keys.trait_healed_target_success, "target", target.getName()); LanguageAPI.sendTranslatedMessage(targetPlayer, Keys.trait_healed_other_success, "healer", playerInteracting.getName()); if(consume){ int newAmount = playerInteracting.getItemInHand().getAmount() - 1; if(newAmount == 0){ playerInteracting.setItemInHand(new ItemStack(Material.AIR)); }else{ playerInteracting.getItemInHand().setAmount(newAmount); } } return true; } return false; } @Override public boolean isBetterThan(Trait trait) { if(!(trait instanceof HealOthersTrait)) return false; HealOthersTrait otherTrait = (HealOthersTrait) trait; return value >= otherTrait.value; } public static List<String> getHelpForTrait(){ List<String> helpList = new LinkedList<String>(); helpList.add(ChatColor.YELLOW + "The trait lets you heal others or yourself for a certain value."); helpList.add(ChatColor.YELLOW + "It can be used by right-clicking another player with a " + ChatColor.LIGHT_PURPLE + itemIDInHand.name() + ChatColor.YELLOW + " in hands."); return helpList; } @Override public boolean triggerButHasUplink(EventWrapper wrapper){ RaCPlayer player = wrapper.getPlayer(); if(player.getPlayer().getItemInHand().getType() == itemIDInHand){ return false; } return true; } @Override public boolean canBeTriggered(EventWrapper wrapper) { PlayerAction action = wrapper.getPlayerAction(); RaCPlayer player = wrapper.getPlayer(); if(action == PlayerAction.INTERACT_ENTITY || action == PlayerAction.INTERACT_BLOCK || action == PlayerAction.INTERACT_AIR){ boolean isSneaking = player.getPlayer().isSneaking(); if(!isSneaking){ return false; } if(action == PlayerAction.INTERACT_ENTITY){ Entity target = wrapper.getEntityTarget(); if(target != null && target instanceof Player){ if(player.getPlayer().getItemInHand().getType() != itemIDInHand) return false; return true; } return false; } if(action == PlayerAction.INTERACT_AIR || action == PlayerAction.INTERACT_BLOCK){ if(player.getPlayer().getItemInHand().getType() != itemIDInHand) return false; return true; } } return false; } }