1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00
This commit is contained in:
TheBusyBiscuit 2020-08-26 12:47:08 +02:00
parent cced66725a
commit 6e6a953009
4 changed files with 141 additions and 70 deletions

View File

@ -81,6 +81,7 @@
* Fixed Electric Press not working
* Fixed #2240
* Fixed #2243
* Fixed #2249
## Release Candidate 15 (01 Aug 2020)

View File

@ -0,0 +1,93 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.armor;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* The Boots of the Stomper are boots which damage nearby enemies whenever the {@link Player}
* takes fall damage.
*
* @author TheBusyBiscuit
*
*/
public class StomperBoots extends SlimefunItem {
public StomperBoots(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
/**
* This will apply the "stomp" effect to the given {@link EntityDamageEvent}.
*
* @param fallDamageEvent
* The {@link EntityDamageEvent} in which the {@link Player} has taken fall damage
*/
public void stomp(EntityDamageEvent fallDamageEvent) {
Player p = (Player) fallDamageEvent.getEntity();
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ZOMBIE_BREAK_WOODEN_DOOR, 1F, 2F);
p.setVelocity(new Vector(0, 0.7, 0));
for (Entity n : p.getNearbyEntities(4, 4, 4)) {
if (n instanceof LivingEntity && n.isValid() && !n.getUniqueId().equals(p.getUniqueId())) {
Vector velocity = getShockwave(p.getLocation(), n.getLocation());
n.setVelocity(velocity);
// Check if it's not a Player or if PvP is enabled
if (!(n instanceof Player) || (p.getWorld().getPVP() && SlimefunPlugin.getProtectionManager().hasPermission(p, n.getLocation(), ProtectableAction.PVP))) {
EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(p, n, DamageCause.ENTITY_ATTACK, fallDamageEvent.getDamage() / 2);
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
((LivingEntity) n).damage(event.getDamage());
}
}
}
}
for (BlockFace face : BlockFace.values()) {
Block b = p.getLocation().getBlock().getRelative(BlockFace.DOWN).getRelative(face);
p.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType());
}
}
/**
* This gives us the "shockwave" {@link Vector} for a given target.
*
* @param origin
* The {@link Location} of our {@link Player}
* @param target
* The {@link Location} of the {@link Entity} we are pushing away
*
* @return A {@link Vector} to determine the velocity for our {@link Entity}
*/
private Vector getShockwave(Location origin, Location target) {
// As the distance approached zero we might slip into a "division by zero" when normalizing
if (origin.distanceSquared(target) < 0.05) {
return new Vector(0, 1, 0);
}
else {
Vector direction = target.toVector().subtract(origin.toVector());
return direction.normalize().multiply(1.4);
}
}
}

View File

@ -1,20 +1,9 @@
package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.EnderPearl;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@ -24,20 +13,19 @@ import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.StomperBoots;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* This {@link Listener} is responsible for handling all boots provided by
* Slimefun, such as the Boots of the Stomper or any {@link SlimefunArmorPiece} that
* is a pair of boots and needs to listen to an {@link Event}.
* Slimefun, such as the {@link StomperBoots} or any {@link SlimefunArmorPiece} that
* is a pair of boots and needs to listen to an {@link EntityDamageEvent}.
*
* @author TheBusyBiscuit
* @author Walshy
@ -45,71 +33,55 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/
public class SlimefunBootsListener implements Listener {
private final Map<String, Predicate<EntityDamageEvent>> cancelledEvents = new HashMap<>();
public SlimefunBootsListener(SlimefunPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
cancelledEvents.put("ENDER_BOOTS", e -> e instanceof EntityDamageByEntityEvent && ((EntityDamageByEntityEvent) e).getDamager() instanceof EnderPearl);
cancelledEvents.put("BOOTS_OF_THE_STOMPER", e -> {
if (e.getCause() == DamageCause.FALL) {
stomp(e);
return true;
}
return false;
});
cancelledEvents.put("SLIME_BOOTS", e -> e.getCause() == DamageCause.FALL);
cancelledEvents.put("SLIME_STEEL_BOOTS", e -> e.getCause() == DamageCause.FALL);
}
private void stomp(EntityDamageEvent e) {
Player p = (Player) e.getEntity();
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ZOMBIE_BREAK_WOODEN_DOOR, 1F, 2F);
p.setVelocity(new Vector(0.0, 0.7, 0.0));
for (Entity n : p.getNearbyEntities(4, 4, 4)) {
if (n instanceof LivingEntity && !n.getUniqueId().equals(p.getUniqueId())) {
Vector velocity = n.getLocation().toVector().subtract(p.getLocation().toVector()).normalize().multiply(1.4);
n.setVelocity(velocity);
if (!(n instanceof Player) || (p.getWorld().getPVP() && SlimefunPlugin.getProtectionManager().hasPermission(p, n.getLocation(), ProtectableAction.PVP))) {
EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(p, n, DamageCause.ENTITY_ATTACK, e.getDamage() / 2);
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) ((LivingEntity) n).damage(e.getDamage() / 2);
}
}
}
for (BlockFace face : BlockFace.values()) {
Block b = p.getLocation().getBlock().getRelative(BlockFace.DOWN).getRelative(face);
p.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType());
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onDamage(EntityDamageEvent e) {
if (e.getEntity() instanceof Player) {
Player p = (Player) e.getEntity();
SlimefunItem boots = SlimefunItem.getByItem(p.getInventory().getBoots());
if (e.getCause() == DamageCause.FALL) {
onFallDamage(e);
}
else if (e instanceof EntityDamageByEntityEvent) {
EntityDamageByEntityEvent event = (EntityDamageByEntityEvent) e;
if (boots != null) {
for (Map.Entry<String, Predicate<EntityDamageEvent>> event : cancelledEvents.entrySet()) {
if (boots.getID().equals(event.getKey())) {
if (Slimefun.hasUnlocked(p, boots, true) && event.getValue().test(e)) {
e.setCancelled(true);
}
break;
}
if (event.getDamager() instanceof EnderPearl) {
onEnderPearlDamage(e);
}
}
}
}
private void onFallDamage(EntityDamageEvent e) {
Player p = (Player) e.getEntity();
SlimefunItem boots = SlimefunItem.getByItem(p.getInventory().getBoots());
if (boots != null) {
// Check if the boots were researched
if (!Slimefun.hasUnlocked(p, boots, true)) {
return;
}
if (boots instanceof StomperBoots) {
e.setCancelled(true);
((StomperBoots) boots).stomp(e);
}
else if (boots.getID().equals("SLIME_BOOTS") || boots.getID().equals("SLIME_STEEL_BOOTS")) {
e.setCancelled(true);
}
}
}
private void onEnderPearlDamage(EntityDamageEvent e) {
Player p = (Player) e.getEntity();
SlimefunItem boots = SlimefunItem.getByItem(p.getInventory().getBoots());
if (boots != null && boots.getID().equals("ENDER_BOOTS") && Slimefun.hasUnlocked(p, boots, true)) {
e.setCancelled(true);
}
}
@EventHandler
public void onTrample(PlayerInteractEvent e) {
if (e.getAction() == Action.PHYSICAL) {
@ -118,8 +90,12 @@ public class SlimefunBootsListener implements Listener {
if (b != null && b.getType() == Material.FARMLAND) {
ItemStack boots = e.getPlayer().getInventory().getBoots();
if (SlimefunUtils.isItemSimilar(boots, SlimefunItems.FARMER_SHOES, true) && Slimefun.hasUnlocked(e.getPlayer(), boots, true)) {
e.setCancelled(true);
if (SlimefunUtils.isItemSimilar(boots, SlimefunItems.FARMER_SHOES, true)) {
SlimefunItem item = SlimefunItems.FARMER_SHOES.getItem();
if (Slimefun.hasUnlocked(e.getPlayer(), item, true)) {
e.setCancelled(true);
}
}
}
}

View File

@ -34,6 +34,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.androids.Woodcutt
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.HazmatArmorPiece;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.Parachute;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.StomperBoots;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.EnderBackpack;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.RestoredBackpack;
@ -1063,7 +1064,7 @@ public final class SlimefunItemSetup {
new IndustrialMiner(categories.basicMachines, SlimefunItems.INDUSTRIAL_MINER, Material.IRON_BLOCK, false, 3).register(plugin);
new AdvancedIndustrialMiner(categories.basicMachines, SlimefunItems.ADVANCED_INDUSTRIAL_MINER).register(plugin);
new SlimefunItem(categories.magicalArmor, SlimefunItems.BOOTS_OF_THE_STOMPER, RecipeType.ARMOR_FORGE,
new StomperBoots(categories.magicalArmor, SlimefunItems.BOOTS_OF_THE_STOMPER, RecipeType.ARMOR_FORGE,
new ItemStack[] {null, null, null, new ItemStack(Material.YELLOW_WOOL), null, new ItemStack(Material.YELLOW_WOOL), new ItemStack(Material.PISTON), null, new ItemStack(Material.PISTON)})
.register(plugin);