mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-30 00:56:47 +01:00
Archery events & bugfixes
- Added custom events for Skill Shot and Daze. - Archery metadata is now stored directly as a location, rather than a string. - Fixed bug where arrows weren't properly tracked. - Use HashMap instead of ArrayList for entity tracking.
This commit is contained in:
parent
a99293aa48
commit
965035fa72
@ -51,6 +51,7 @@ Version 1.4.07
|
||||
+ Added new /mccooldowns command to show all ability cooldowns
|
||||
+ Commands may now both print text and display a scoreboard
|
||||
+ Killing a custom entity will automatically add it to the custom entity config file with default values.
|
||||
= Fixed bug where arrow retrieval was not properly detecting entities that already existed in the tracker
|
||||
= Fixed bug which allowed players to bypass fishing's exploit prevention
|
||||
= Fixed bug where FakeEntityDamageByEntityEvent wasn't being fired
|
||||
= Fixed bug with "Skull Splitter" not finding the locale string
|
||||
|
@ -0,0 +1,33 @@
|
||||
package com.gmail.nossr50.events.skills;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||
import com.gmail.nossr50.events.fake.FakeEntityDamageByEntityEvent;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
|
||||
public abstract class McMMOPlayerCombatEvent extends FakeEntityDamageByEntityEvent {
|
||||
private Player player;
|
||||
private SkillType skill;
|
||||
private int skillLevel;
|
||||
|
||||
public McMMOPlayerCombatEvent(Player player, Entity damager, Entity damagee, DamageCause cause, double damage, SkillType skill) {
|
||||
super(damager, damagee, cause, damage);
|
||||
this.player = player;
|
||||
this.skill = skill;
|
||||
skillLevel = UserManager.getPlayer(player).getProfile().getSkillLevel(skill);
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public SkillType getSkill() {
|
||||
return skill;
|
||||
}
|
||||
|
||||
public int getSkillLevel() {
|
||||
return skillLevel;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.gmail.nossr50.events.skills.archery;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||
import com.gmail.nossr50.events.skills.McMMOPlayerCombatEvent;
|
||||
|
||||
public class McMMOPlayerArcheryCombatEvent extends McMMOPlayerCombatEvent {
|
||||
public McMMOPlayerArcheryCombatEvent(Player player, Entity damager, Entity damagee, DamageCause cause, double damage) {
|
||||
super(player, damager, damagee, cause, damage, SkillType.ARCHERY);
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.gmail.nossr50.events.skills.archery;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
|
||||
import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||
import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
|
||||
|
||||
public abstract class McMMOPlayerArcheryEvent extends McMMOPlayerSkillEvent implements Cancellable {
|
||||
private boolean cancelled;
|
||||
|
||||
protected McMMOPlayerArcheryEvent(Player player) {
|
||||
super(player, SkillType.ARCHERY);
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.gmail.nossr50.events.skills.archery;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.gmail.nossr50.skills.archery.Archery;
|
||||
|
||||
public class McMMOPlayerDazeEvent extends McMMOPlayerArcheryCombatEvent {
|
||||
public McMMOPlayerDazeEvent(Player player, Entity damager, Entity damagee) {
|
||||
super(player, damager, damagee, DamageCause.PROJECTILE, Archery.dazeModifier);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.gmail.nossr50.events.skills.archery;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class McMMOPlayerSkillShotEvent extends McMMOPlayerArcheryCombatEvent {
|
||||
public McMMOPlayerSkillShotEvent(Player player, Entity damager, Entity damagee, double damage) {
|
||||
super(player, damager, damagee, DamageCause.PROJECTILE, damage);
|
||||
}
|
||||
}
|
@ -74,7 +74,7 @@ public class EntityListener implements Listener {
|
||||
}
|
||||
|
||||
projectile.setMetadata(mcMMO.bowForceKey, new FixedMetadataValue(plugin, Math.min(event.getForce() * AdvancedConfig.getInstance().getForceMultiplier(), 1.0)));
|
||||
projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(plugin, Archery.locationToString(projectile.getLocation())));
|
||||
projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(plugin, projectile.getLocation()));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
@ -86,7 +86,7 @@ public class EntityListener implements Listener {
|
||||
}
|
||||
|
||||
projectile.setMetadata(mcMMO.bowForceKey, new FixedMetadataValue(plugin, 1.0));
|
||||
projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(plugin, Archery.locationToString(projectile.getLocation())));
|
||||
projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(plugin, projectile.getLocation()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,20 +1,18 @@
|
||||
package com.gmail.nossr50.skills.archery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
|
||||
public class Archery {
|
||||
private static List<TrackedEntity> trackedEntities = new ArrayList<TrackedEntity>();
|
||||
private static Map<UUID, TrackedEntity> trackedEntities = new HashMap<UUID, TrackedEntity>();
|
||||
|
||||
public static int retrieveMaxBonusLevel = AdvancedConfig.getInstance().getRetrieveMaxBonusLevel();
|
||||
public static double retrieveMaxChance = AdvancedConfig.getInstance().getRetrieveChanceMax();
|
||||
@ -31,12 +29,12 @@ public class Archery {
|
||||
public static final double DISTANCE_XP_MULTIPLIER = 0.025;
|
||||
|
||||
protected static void incrementTrackerValue(LivingEntity livingEntity) {
|
||||
for (TrackedEntity trackedEntity : trackedEntities) {
|
||||
if (trackedEntity.getLivingEntity().getEntityId() == livingEntity.getEntityId()) {
|
||||
TrackedEntity trackedEntity = trackedEntities.get(livingEntity.getUniqueId());
|
||||
|
||||
if (trackedEntity != null) {
|
||||
trackedEntity.incrementArrowCount();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
addToTracker(livingEntity); // If the entity isn't tracked yet
|
||||
}
|
||||
@ -45,11 +43,11 @@ public class Archery {
|
||||
TrackedEntity trackedEntity = new TrackedEntity(livingEntity);
|
||||
|
||||
trackedEntity.incrementArrowCount();
|
||||
trackedEntities.add(trackedEntity);
|
||||
trackedEntities.put(livingEntity.getUniqueId(), trackedEntity);
|
||||
}
|
||||
|
||||
protected static void removeFromTracker(TrackedEntity trackedEntity) {
|
||||
trackedEntities.remove(trackedEntity);
|
||||
protected static void removeFromTracker(UUID id) {
|
||||
trackedEntities.remove(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,24 +56,14 @@ public class Archery {
|
||||
* @param livingEntity The entity hit by the arrows
|
||||
*/
|
||||
public static void arrowRetrievalCheck(LivingEntity livingEntity) {
|
||||
for (Iterator<TrackedEntity> entityIterator = trackedEntities.iterator(); entityIterator.hasNext();) {
|
||||
TrackedEntity trackedEntity = entityIterator.next();
|
||||
UUID id = livingEntity.getUniqueId();
|
||||
TrackedEntity trackedEntity = trackedEntities.get(id);
|
||||
|
||||
if (trackedEntity.getID() == livingEntity.getUniqueId()) {
|
||||
Misc.dropItems(livingEntity.getLocation(), new ItemStack(Material.ARROW), trackedEntity.getArrowCount());
|
||||
entityIterator.remove();
|
||||
if (trackedEntity == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Location stringToLocation(String location) {
|
||||
String[] values = location.split(",");
|
||||
|
||||
return new Location(mcMMO.p.getServer().getWorld(values[0]), Double.parseDouble(values[1]), Double.parseDouble(values[2]), Double.parseDouble(values[3]), Float.parseFloat(values[4]), Float.parseFloat(values[5]));
|
||||
}
|
||||
|
||||
public static String locationToString(Location location) {
|
||||
return location.getWorld().getName() + "," + location.getX() + "," + location.getY() + "," + location.getZ() + "," + location.getYaw() + "," + location.getPitch();
|
||||
Misc.dropItems(livingEntity.getLocation(), new ItemStack(Material.ARROW), trackedEntity.getArrowCount());
|
||||
removeFromTracker(id);
|
||||
}
|
||||
}
|
||||
|
@ -5,19 +5,19 @@ import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||
import com.gmail.nossr50.events.skills.archery.McMMOPlayerDazeEvent;
|
||||
import com.gmail.nossr50.events.skills.archery.McMMOPlayerSkillShotEvent;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
|
||||
public class ArcheryManager extends SkillManager {
|
||||
@ -26,15 +26,15 @@ public class ArcheryManager extends SkillManager {
|
||||
}
|
||||
|
||||
public boolean canDaze(LivingEntity target) {
|
||||
return target instanceof Player && Permissions.daze(getPlayer());
|
||||
return target instanceof Player && Permissions.daze(getPlayer()) && SkillUtils.activationSuccessful(getSkillLevel(), getActivationChance(), Archery.dazeMaxBonus, Archery.dazeMaxBonusLevel);
|
||||
}
|
||||
|
||||
public boolean canSkillShot() {
|
||||
public boolean canUseSkillShot() {
|
||||
return getSkillLevel() >= Archery.skillShotIncreaseLevel && Permissions.bonusDamage(getPlayer(), skill);
|
||||
}
|
||||
|
||||
public boolean canTrackArrows() {
|
||||
return Permissions.arrowRetrieval(getPlayer());
|
||||
public boolean canTrack(Arrow arrow) {
|
||||
return Permissions.arrowRetrieval(getPlayer()) && !arrow.hasMetadata(mcMMO.infiniteArrowKey) && SkillUtils.activationSuccessful(getSkillLevel(), getActivationChance(), Archery.retrieveMaxChance, Archery.retrieveMaxBonusLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,7 +44,7 @@ public class ArcheryManager extends SkillManager {
|
||||
* @param damager The {@link Entity} who shot the arrow
|
||||
*/
|
||||
public void distanceXpBonus(LivingEntity target, Entity damager) {
|
||||
Location firedLocation = Archery.stringToLocation(damager.getMetadata(mcMMO.arrowDistanceKey).get(0).asString());
|
||||
Location firedLocation = (Location) damager.getMetadata(mcMMO.arrowDistanceKey).get(0).value();
|
||||
Location targetLocation = target.getLocation();
|
||||
|
||||
if (firedLocation.getWorld() != targetLocation.getWorld()) {
|
||||
@ -58,39 +58,52 @@ public class ArcheryManager extends SkillManager {
|
||||
* Track arrows fired for later retrieval.
|
||||
*
|
||||
* @param target The {@link LivingEntity} damaged by the arrow
|
||||
* @param arrow The {@link Arrow} that damaged the target
|
||||
*/
|
||||
public void trackArrows(LivingEntity target) {
|
||||
if (SkillUtils.activationSuccessful(getSkillLevel(), getActivationChance(), Archery.retrieveMaxChance, Archery.retrieveMaxBonusLevel)) {
|
||||
Archery.incrementTrackerValue(target);
|
||||
public void trackArrow(LivingEntity target, Arrow arrow) {
|
||||
if (!canTrack(arrow)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Archery.incrementTrackerValue(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the effects of the Daze ability
|
||||
*
|
||||
* @param defender The {@link Player} being affected by the ability
|
||||
* @param target The {@link LivingEntity} being affected by the ability
|
||||
* @param arrow The {@link Arrow} that was fired
|
||||
*/
|
||||
public double daze(Player defender, Arrow arrow) {
|
||||
if (!SkillUtils.activationSuccessful(getSkillLevel(), getActivationChance(), Archery.dazeMaxBonus, Archery.dazeMaxBonusLevel)) {
|
||||
public double daze(LivingEntity target, Arrow arrow) {
|
||||
if (!canDaze(target)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Player attacker = getPlayer();
|
||||
|
||||
McMMOPlayerDazeEvent event = new McMMOPlayerDazeEvent(attacker, arrow, target);
|
||||
mcMMO.p.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Player defender = (Player) target;
|
||||
Location dazedLocation = defender.getLocation();
|
||||
dazedLocation.setPitch(90 - Misc.getRandom().nextInt(181));
|
||||
|
||||
defender.teleport(dazedLocation);
|
||||
defender.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 20 * 10, 10));
|
||||
defender.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, Misc.TICK_CONVERSION_FACTOR * 10, 10));
|
||||
|
||||
if (UserManager.getPlayer(defender).useChatNotifications()) {
|
||||
defender.sendMessage(LocaleLoader.getString("Combat.TouchedFuzzy"));
|
||||
}
|
||||
|
||||
if (mcMMOPlayer.useChatNotifications()) {
|
||||
getPlayer().sendMessage(LocaleLoader.getString("Combat.TargetDazed"));
|
||||
attacker.sendMessage(LocaleLoader.getString("Combat.TargetDazed"));
|
||||
}
|
||||
|
||||
return CombatUtils.callFakeDamageEvent(arrow, defender, DamageCause.PROJECTILE, Archery.dazeModifier);
|
||||
return event.getDamage();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,9 +114,24 @@ public class ArcheryManager extends SkillManager {
|
||||
* @param arrow The {@link Arrow} that was fired
|
||||
*/
|
||||
public double skillShot(LivingEntity target, double damage, Arrow arrow) {
|
||||
if (!canUseSkillShot()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
McMMOPlayerSkillShotEvent event = new McMMOPlayerSkillShotEvent(getPlayer(), arrow, target, calculateSkillShotBonus(damage));
|
||||
mcMMO.p.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return event.getDamage();
|
||||
}
|
||||
|
||||
private double calculateSkillShotBonus(double damage) {
|
||||
double damageBonusPercent = Math.min(((getSkillLevel() / Archery.skillShotIncreaseLevel) * Archery.skillShotIncreasePercentage), Archery.skillShotMaxBonusPercentage);
|
||||
double archeryBonus = Math.min(damage * damageBonusPercent, Archery.skillShotMaxBonusDamage);
|
||||
|
||||
return CombatUtils.callFakeDamageEvent(arrow, target, DamageCause.PROJECTILE, archeryBonus);
|
||||
return archeryBonus;
|
||||
}
|
||||
}
|
||||
|
@ -22,15 +22,11 @@ public class TrackedEntity extends BukkitRunnable {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!livingEntity.isValid()) {
|
||||
Archery.removeFromTracker(this);
|
||||
Archery.removeFromTracker(id);
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
protected LivingEntity getLivingEntity() {
|
||||
return livingEntity;
|
||||
}
|
||||
|
||||
protected UUID getID() {
|
||||
return id;
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.config.experience.ExperienceConfig;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||
@ -167,18 +166,10 @@ public final class CombatUtils {
|
||||
}
|
||||
}
|
||||
|
||||
if (archeryManager.canSkillShot()) {
|
||||
finalDamage += archeryManager.skillShot(target, initialDamage, arrow);
|
||||
}
|
||||
|
||||
if (archeryManager.canDaze(target)) {
|
||||
finalDamage += archeryManager.daze((Player) target, arrow);
|
||||
}
|
||||
|
||||
if (!arrow.hasMetadata(mcMMO.infiniteArrowKey) && archeryManager.canTrackArrows()) {
|
||||
archeryManager.trackArrows(target);
|
||||
}
|
||||
finalDamage += archeryManager.daze(target, arrow);
|
||||
|
||||
archeryManager.trackArrow(target, arrow);
|
||||
archeryManager.distanceXpBonus(target, arrow);
|
||||
|
||||
event.setDamage(finalDamage);
|
||||
|
Loading…
Reference in New Issue
Block a user