From 8c0a8a107572c39ed84a5d04ead02cb330fc0b48 Mon Sep 17 00:00:00 2001 From: UltraFaceguy Date: Tue, 16 Feb 2021 17:02:28 -0500 Subject: [PATCH] Large refactor of barrier, energy, spawner, minion, life, and combat status tasks --- pom.xml | 18 ++-- .../java/land/face/strife/StrifePlugin.java | 57 ++++------- .../face/strife/commands/StrifeCommand.java | 11 ++- .../java/land/face/strife/data/Spawner.java | 87 +++++++++++++++- .../java/land/face/strife/data/StrifeMob.java | 77 ++++++++++++--- .../land/face/strife/data/TargetResponse.java | 14 +++ .../land/face/strife/data/UniqueEntity.java | 9 ++ .../strife/data/champion/LifeSkillType.java | 1 + .../data/champion/PlayerEquipmentCache.java | 6 +- .../data/conditions/EnergyCondition.java | 2 +- .../data/conditions/InCombatCondition.java | 16 +-- .../face/strife/data/effects/AreaEffect.java | 18 ++-- .../strife/data/effects/ChangeEnergy.java | 31 +----- .../face/strife/data/effects/ChangeRage.java | 17 +++- .../land/face/strife/data/effects/Charm.java | 5 +- .../land/face/strife/data/effects/Damage.java | 8 +- .../strife/data/effects/EquipmentSwap.java | 2 +- .../strife/data/effects/EvokerFangEffect.java | 19 ++-- .../strife/data/effects/ShootProjectile.java | 7 +- .../land/face/strife/data/effects/Summon.java | 61 +++++++++++- .../data/effects/TriggerLoreAbility.java | 26 +++++ .../face/strife/listeners/CombatListener.java | 6 ++ .../face/strife/listeners/DataListener.java | 24 +++-- .../strife/listeners/DoubleJumpListener.java | 2 + .../listeners/EvokerFangEffectListener.java | 66 ------------- .../strife/listeners/ExperienceListener.java | 2 +- .../listeners/LaunchAndLandListener.java | 1 + .../strife/listeners/LoreAbilityListener.java | 9 +- .../face/strife/listeners/MinionListener.java | 7 +- .../face/strife/listeners/ShootListener.java | 51 +++------- .../face/strife/listeners/SpawnListener.java | 8 +- .../face/strife/managers/AbilityManager.java | 14 +-- .../face/strife/managers/BoostManager.java | 34 ++++--- .../face/strife/managers/BossBarManager.java | 9 +- .../face/strife/managers/ChampionManager.java | 2 +- .../strife/managers/CombatStatusManager.java | 77 --------------- .../face/strife/managers/EffectManager.java | 86 +++++++++------- .../face/strife/managers/MinionManager.java | 62 ------------ .../face/strife/managers/SpawnerManager.java | 99 ------------------- .../strife/managers/StrifeMobManager.java | 2 +- .../strife/managers/UniqueEntityManager.java | 10 +- .../strife/menus/stats/StatsMiscMenuItem.java | 2 +- .../land/face/strife/tasks/BarrierTask.java | 2 +- .../strife/tasks/CombatCountdownTask.java | 63 ++++++++++++ .../face/strife/tasks/CombatStatusTask.java | 36 ------- .../land/face/strife/tasks/EnergyTask.java | 36 ++++--- .../java/land/face/strife/tasks/LifeTask.java | 19 ++-- .../face/strife/tasks/MinionDecayTask.java | 36 ------- .../land/face/strife/tasks/MinionTask.java | 53 ++++++++++ .../face/strife/tasks/SpawnerSpawnTask.java | 37 ------- .../face/strife/tasks/ThrownItemTask.java | 13 ++- .../java/land/face/strife/util/ChunkUtil.java | 25 +++++ .../land/face/strife/util/DamageUtil.java | 29 +++--- .../java/land/face/strife/util/FangUtil.java | 53 ++++++++++ .../java/land/face/strife/util/ItemUtil.java | 18 ++++ .../java/land/face/strife/util/JumpUtil.java | 4 - .../land/face/strife/util/ProjectileUtil.java | 21 +++- .../java/land/face/strife/util/StatUtil.java | 14 ++- .../land/face/strife/util/TargetingUtil.java | 40 +++++--- 59 files changed, 812 insertions(+), 752 deletions(-) create mode 100644 src/main/java/land/face/strife/data/effects/TriggerLoreAbility.java delete mode 100644 src/main/java/land/face/strife/listeners/EvokerFangEffectListener.java delete mode 100644 src/main/java/land/face/strife/managers/CombatStatusManager.java delete mode 100644 src/main/java/land/face/strife/managers/MinionManager.java create mode 100644 src/main/java/land/face/strife/tasks/CombatCountdownTask.java delete mode 100644 src/main/java/land/face/strife/tasks/CombatStatusTask.java delete mode 100644 src/main/java/land/face/strife/tasks/MinionDecayTask.java create mode 100644 src/main/java/land/face/strife/tasks/MinionTask.java delete mode 100644 src/main/java/land/face/strife/tasks/SpawnerSpawnTask.java create mode 100644 src/main/java/land/face/strife/util/ChunkUtil.java create mode 100644 src/main/java/land/face/strife/util/FangUtil.java diff --git a/pom.xml b/pom.xml index a5030e14..dfc74d1e 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ strife - 3.3.2 + 3.4.0 jar strife @@ -85,13 +85,19 @@ io.pixeloutlaw facecore - 1.16.4.1 + master-SNAPSHOT provided io.pixeloutlaw bullion - 2.2.4 + master-SNAPSHOT + provided + + + com.github.UltraFaceguy + SnazzyParties + master-SNAPSHOT provided @@ -112,12 +118,6 @@ 1.18.1 provided - - com.github.UltraFaceguy - SnazzyParties - 1.1.0 - provided - me.glaremasters guilds diff --git a/src/main/java/land/face/strife/StrifePlugin.java b/src/main/java/land/face/strife/StrifePlugin.java index d635196e..9d43899e 100644 --- a/src/main/java/land/face/strife/StrifePlugin.java +++ b/src/main/java/land/face/strife/StrifePlugin.java @@ -28,6 +28,7 @@ The MIT License Copyright (c) 2015 Teal Cube Games import io.pixeloutlaw.minecraft.spigot.config.VersionedSmartYamlConfiguration; import io.pixeloutlaw.minecraft.spigot.garbage.StringExtensionsKt; import java.io.File; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -51,6 +52,7 @@ The MIT License Copyright (c) 2015 Teal Cube Games import land.face.strife.data.ability.Ability; import land.face.strife.data.champion.LifeSkillType; import land.face.strife.data.effects.ShootBlock; +import land.face.strife.data.effects.TriggerLoreAbility; import land.face.strife.hooks.SnazzyPartiesHook; import land.face.strife.listeners.BullionListener; import land.face.strife.listeners.ChatListener; @@ -65,7 +67,6 @@ The MIT License Copyright (c) 2015 Teal Cube Games import land.face.strife.listeners.EntityHider; import land.face.strife.listeners.EntityHider.Policy; import land.face.strife.listeners.EntityMagicListener; -import land.face.strife.listeners.EvokerFangEffectListener; import land.face.strife.listeners.ExperienceListener; import land.face.strife.listeners.FallListener; import land.face.strife.listeners.FishingListener; @@ -95,7 +96,6 @@ The MIT License Copyright (c) 2015 Teal Cube Games import land.face.strife.managers.BuffManager; import land.face.strife.managers.ChampionManager; import land.face.strife.managers.ChaserManager; -import land.face.strife.managers.CombatStatusManager; import land.face.strife.managers.CorruptionManager; import land.face.strife.managers.CounterManager; import land.face.strife.managers.DamageManager; @@ -104,7 +104,7 @@ The MIT License Copyright (c) 2015 Teal Cube Games import land.face.strife.managers.ExperienceManager; import land.face.strife.managers.IndicatorManager; import land.face.strife.managers.LoreAbilityManager; -import land.face.strife.managers.MinionManager; +import land.face.strife.managers.LoreAbilityManager.TriggerType; import land.face.strife.managers.MobModManager; import land.face.strife.managers.MonsterManager; import land.face.strife.managers.PathManager; @@ -132,18 +132,17 @@ The MIT License Copyright (c) 2015 Teal Cube Games import land.face.strife.tasks.AbilityTickTask; import land.face.strife.tasks.BoostTickTask; import land.face.strife.tasks.BossBarsTask; -import land.face.strife.tasks.CombatStatusTask; import land.face.strife.tasks.DamageOverTimeTask; +import land.face.strife.tasks.EnergyTask; import land.face.strife.tasks.EveryTickTask; import land.face.strife.tasks.ForceAttackSpeed; import land.face.strife.tasks.IndicatorTask; -import land.face.strife.tasks.MinionDecayTask; import land.face.strife.tasks.ParticleTask; import land.face.strife.tasks.SaveTask; -import land.face.strife.tasks.SpawnerSpawnTask; import land.face.strife.tasks.StealthParticleTask; import land.face.strife.tasks.StrifeMobTracker; import land.face.strife.tasks.VirtualEntityTask; +import land.face.strife.util.ChunkUtil; import land.face.strife.util.DamageUtil; import land.face.strife.util.LogUtil; import land.face.strife.util.LogUtil.LogLevel; @@ -197,7 +196,6 @@ public class StrifePlugin extends FacePlugin { private StealthManager stealthManager; private UniqueEntityManager uniqueEntityManager; private BossBarManager bossBarManager; - private MinionManager minionManager; private DamageManager damageManager; private ChaserManager chaserManager; private EntityEquipmentManager equipmentManager; @@ -207,7 +205,6 @@ public class StrifePlugin extends FacePlugin { private AbilityIconManager abilityIconManager; private BuffManager buffManager; private PathManager pathManager; - private CombatStatusManager combatStatusManager; private SpawnerManager spawnerManager; private MobModManager mobModManager; private BoostManager boostManager; @@ -241,6 +238,8 @@ public class StrifePlugin extends FacePlugin { public static float RUN_COST; public static float RUN_COST_PERCENT; + public static final DecimalFormat INT_FORMAT = new DecimalFormat("#,###,###,###,###"); + public static StrifePlugin getInstance() { return instance; } @@ -287,7 +286,6 @@ public void enable() { championManager = new ChampionManager(this); uniqueEntityManager = new UniqueEntityManager(this); bossBarManager = new BossBarManager(this); - minionManager = new MinionManager(); damageManager = new DamageManager(this); chaserManager = new ChaserManager(this); experienceManager = new ExperienceManager(this); @@ -317,7 +315,6 @@ public void enable() { abilityIconManager = new AbilityIconManager(this); buffManager = new BuffManager(); pathManager = new PathManager(); - combatStatusManager = new CombatStatusManager(this); MenuListener.getInstance().register(this); @@ -330,9 +327,9 @@ public void enable() { LogUtil.printError("DANGUS ALERT! Bad log level! Acceptable values: " + Arrays.toString(LogLevel.values())); } - WALK_COST = (float) settings.getDouble("config.mechanics.energy.walk-cost-flat", 3) / 20; + WALK_COST = (float) settings.getDouble("config.mechanics.energy.walk-cost-flat", 3) * EnergyTask.TICK_MULT; WALK_COST_PERCENT = (float) settings.getDouble("config.mechanics.energy.walk-regen-percent", 0.75); - RUN_COST = (float) settings.getDouble("config.mechanics.energy.run-cost-flat", 10) / 20; + RUN_COST = (float) settings.getDouble("config.mechanics.energy.run-cost-flat", 10) * EnergyTask.TICK_MULT; RUN_COST_PERCENT = (float) settings.getDouble("config.mechanics.energy.run-regen-percent", 0.25); buildBuffs(); @@ -357,12 +354,9 @@ public void enable() { StealthParticleTask stealthParticleTask = new StealthParticleTask(stealthManager); ForceAttackSpeed forceAttackSpeed = new ForceAttackSpeed(); BossBarsTask bossBarsTask = new BossBarsTask(bossBarManager); - MinionDecayTask minionDecayTask = new MinionDecayTask(minionManager); BoostTickTask boostTickTask = new BoostTickTask(boostManager); - SpawnerSpawnTask spawnerSpawnTask = new SpawnerSpawnTask(spawnerManager); AbilityTickTask iconDuraTask = new AbilityTickTask(abilityManager); VirtualEntityTask virtualEntityTask = new VirtualEntityTask(); - CombatStatusTask combatStatusTask = new CombatStatusTask(combatStatusManager); EveryTickTask everyTickTask = new EveryTickTask(); IndicatorTask indicatorTask = new IndicatorTask(this); damageOverTimeTask = new DamageOverTimeTask(this); @@ -427,10 +421,6 @@ public void enable() { 240L, // Start timer after 12s 2L // Run it every 1/10th of a second after )); - taskList.add(minionDecayTask.runTaskTimer(this, - 220L, // Start timer after 11s - 11L - )); taskList.add(boostTickTask.runTaskTimer(this, 20L, 20L @@ -439,10 +429,6 @@ public void enable() { 2L, 1L )); - taskList.add(spawnerSpawnTask.runTaskTimer(this, - 9 * 20L, // Start timer after 9s - 2 * 20L // Run it every 2 seconds - )); taskList.add(iconDuraTask.runTaskTimer(this, 3 * 20L, // Start timer after 3s AbilityTickTask.ABILITY_TICK_RATE @@ -459,10 +445,6 @@ public void enable() { 20L, 1L )); - taskList.add(combatStatusTask.runTaskTimer(this, - 3 * 20L + 2L, // Start timer after 3s - 20L - )); taskList.add(Bukkit.getScheduler().runTaskTimer(this, () -> boostManager.checkBoostSchedule(), 60L, @@ -477,7 +459,6 @@ public void enable() { Bukkit.getPluginManager().registerEvents(new CombatListener(this), this); Bukkit.getPluginManager().registerEvents(new CreeperExplodeListener(this), this); Bukkit.getPluginManager().registerEvents(new UniqueSplashListener(this), this); - Bukkit.getPluginManager().registerEvents(new EvokerFangEffectListener(strifeMobManager, effectManager), this); Bukkit.getPluginManager().registerEvents(new DOTListener(this), this); Bukkit.getPluginManager().registerEvents(new EndermanListener(), this); Bukkit.getPluginManager().registerEvents(new SwingListener(this), this); @@ -491,7 +472,7 @@ public void enable() { Bukkit.getPluginManager().registerEvents(new SpawnListener(this), this); Bukkit.getPluginManager().registerEvents(new MoneyDropListener(this), this); Bukkit.getPluginManager().registerEvents(new ShearsEquipListener(), this); - Bukkit.getPluginManager().registerEvents(new MinionListener(strifeMobManager, minionManager), this); + Bukkit.getPluginManager().registerEvents(new MinionListener(strifeMobManager), this); Bukkit.getPluginManager().registerEvents(new TargetingListener(this), this); Bukkit.getPluginManager().registerEvents(new FallListener(this), this); Bukkit.getPluginManager().registerEvents(new LaunchAndLandListener(this), this); @@ -550,7 +531,7 @@ public void enable() { for (World world : Bukkit.getWorlds()) { for (Chunk chunk : world.getLoadedChunks()) { - spawnerManager.stampChunk(chunk); + ChunkUtil.stampChunk(chunk); } } @@ -634,6 +615,14 @@ private void buildEffects() { assert cs != null; effectManager.loadEffect(key, cs); } + for (TriggerType type : TriggerType.values()) { + String id = "TRIGGER_" + type.name(); + TriggerLoreAbility triggerLoreAbility = new TriggerLoreAbility(type); + triggerLoreAbility.setId(id); + triggerLoreAbility.setFriendly(true); + triggerLoreAbility.setForceTargetCaster(true); + effectManager.getLoadedEffects().put(id, triggerLoreAbility); + } } private void buildConditions() { @@ -853,10 +842,6 @@ public BossBarManager getBossBarManager() { return bossBarManager; } - public MinionManager getMinionManager() { - return minionManager; - } - public EffectManager getEffectManager() { return effectManager; } @@ -913,10 +898,6 @@ public MobModManager getMobModManager() { return mobModManager; } - public CombatStatusManager getCombatStatusManager() { - return combatStatusManager; - } - public DataStorage getStorage() { return storage; } diff --git a/src/main/java/land/face/strife/commands/StrifeCommand.java b/src/main/java/land/face/strife/commands/StrifeCommand.java index 2105fa6a..9ba0216e 100644 --- a/src/main/java/land/face/strife/commands/StrifeCommand.java +++ b/src/main/java/land/face/strife/commands/StrifeCommand.java @@ -165,13 +165,13 @@ public void profileCommand(CommandSender sender, OnlinePlayer target) { @Subcommand("mobinfo|info") @CommandPermission("strife.info") public void infoCommand(Player sender) { - List targets = new ArrayList<>(TargetingUtil.getEntitiesInLine(sender.getEyeLocation(), 30)); + List targets = new ArrayList<>(TargetingUtil.getEntitiesInLine(sender.getEyeLocation(), 30, 2)); targets.remove(sender); if (targets.isEmpty()) { sendMessage(sender, "&eNo target found..."); return; } - TargetingUtil.DISTANCE_COMPARATOR.setLoc(((Player) sender).getLocation()); + TargetingUtil.DISTANCE_COMPARATOR.setLoc((sender).getLocation()); targets.sort(TargetingUtil.DISTANCE_COMPARATOR); StrifeMob targetMob = plugin.getStrifeMobManager().getStatMob(targets.get(0)); sendMessage(sender, "&aUniqueID: " + targetMob.getUniqueEntityId()); @@ -289,6 +289,13 @@ public void submenuAbilityCommand(CommandSender sender, OnlinePlayer target, Str plugin.getSubmenu(menu).open(target.getPlayer()); } + @Subcommand("ability refresh") + @CommandCompletion("@players") + @CommandPermission("strife.admin") + public void submenuAbilityCommand(CommandSender sender, OnlinePlayer target) { + plugin.getAbilityIconManager().setAllAbilityIcons(target.getPlayer()); + } + @Subcommand("bind") @CommandCompletion("@players @loreabilities") @CommandPermission("strife.admin") diff --git a/src/main/java/land/face/strife/data/Spawner.java b/src/main/java/land/face/strife/data/Spawner.java index f2087072..a308c72c 100644 --- a/src/main/java/land/face/strife/data/Spawner.java +++ b/src/main/java/land/face/strife/data/Spawner.java @@ -1,13 +1,21 @@ package land.face.strife.data; +import com.tealcube.minecraft.bukkit.facecore.utilities.MessageUtils; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import land.face.strife.StrifePlugin; +import land.face.strife.util.ChunkUtil; import land.face.strife.util.LogUtil; +import land.face.strife.util.SpecialStatusUtil; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Particle; +import org.bukkit.Sound; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; public class Spawner extends BukkitRunnable { @@ -15,6 +23,7 @@ public class Spawner extends BukkitRunnable { private final List entities = new CopyOnWriteArrayList<>(); private final List respawnTimes = new CopyOnWriteArrayList<>(); + private final String id; private final String uniqueId; private final UniqueEntity uniqueEntity; @@ -35,7 +44,7 @@ public Spawner(String id, UniqueEntity uniqueEntity, String uniqueId, int amount this.leashRange = leashRange; chunkKey = location.getChunk().getChunkKey(); - runTaskTimer(StrifePlugin.getInstance(), SPAWNER_OFFSET, 20L); + runTaskTimer(StrifePlugin.getInstance(), SPAWNER_OFFSET, 40L); SPAWNER_OFFSET++; LogUtil.printDebug("Created Spawner with taskId " + getTaskId()); } @@ -58,6 +67,82 @@ public void run() { LogUtil.printDebug("Cancelled SpawnerTimer with id " + getTaskId() + " due to leash range"); } } + spawnSpawner(this); + } + + public static void spawnSpawner(Spawner s) { + if (s.getUniqueEntity() == null || s.getLocation() == null) { + return; + } + + int maxMobs = s.getAmount(); + for (long stamp : s.getRespawnTimes()) { + if (System.currentTimeMillis() > stamp) { + s.getRespawnTimes().remove(stamp); + } + } + + int existingMobs = s.getRespawnTimes().size() + s.getEntities().size(); + if (existingMobs >= maxMobs) { + return; + } + + if (!isChuckLoaded(s)) { + return; + } + + int mobDiff = maxMobs - existingMobs; + while (mobDiff > 0) { + + StrifeMob mob = StrifePlugin.getInstance().getUniqueEntityManager() + .spawnUnique(s.getUniqueEntity(), s.getLocation()); + + if (mob == null || mob.getEntity() == null || !mob.getEntity().isValid()) { + Bukkit.getLogger().warning("Spawner failed to spawn unique! " + s.getId()); + continue; + } + + if (mob.getMods().size() >= 2) { + announceSpawnToNearbyPlayers(mob, s.getLocation()); + } + + if (StringUtils.isBlank(s.getUniqueEntity().getMount()) + && mob.getEntity().getVehicle() != null) { + mob.getEntity().getVehicle().remove(); + } + + SpecialStatusUtil.setDespawnOnUnload(mob.getEntity()); + s.addEntity(mob.getEntity()); + + // Random displacement to prevent clumping + if (s.getUniqueEntity().getDisplaceMultiplier() != 0) { + Vector vec = new Vector(-1 + Math.random() * 2, 0.1, -1 + Math.random() * 2).normalize(); + vec.multiply(s.getUniqueEntity().getDisplaceMultiplier()); + mob.getEntity().setVelocity(vec); + mob.getEntity().getLocation().setDirection(mob.getEntity().getVelocity().normalize()); + } + + mobDiff--; + } + } + + private static void announceSpawnToNearbyPlayers(StrifeMob mob, Location location) { + for (Player p : Bukkit.getOnlinePlayers()) { + if (location.getWorld() != p.getWorld()) { + continue; + } + Vector diff = location.toVector().subtract(p.getLocation().toVector()); + if (diff.lengthSquared() < 6400) { + p.playSound(location, Sound.BLOCK_BEACON_AMBIENT, 100, 0.8F); + MessageUtils.sendMessage(p, + "&7&o&lWoah!! &f" + mob.getEntity().getCustomName() + "&f has spawned nearby!"); + } + } + } + + private static boolean isChuckLoaded(Spawner spawner) { + String chunkId = spawner.getLocation().getWorld().getName() + spawner.getChunkKey(); + return ChunkUtil.isChuckLoaded(chunkId); } public void addRespawnTimeIfApplicable(LivingEntity livingEntity) { diff --git a/src/main/java/land/face/strife/data/StrifeMob.java b/src/main/java/land/face/strife/data/StrifeMob.java index 783377b3..dadf6e54 100644 --- a/src/main/java/land/face/strife/data/StrifeMob.java +++ b/src/main/java/land/face/strife/data/StrifeMob.java @@ -10,6 +10,7 @@ import java.util.UUID; import land.face.SnazzyPartiesPlugin; import land.face.data.Party; +import land.face.strife.StrifePlugin; import land.face.strife.data.ability.EntityAbilitySet; import land.face.strife.data.buff.Buff; import land.face.strife.data.champion.Champion; @@ -18,8 +19,10 @@ import land.face.strife.stats.StrifeStat; import land.face.strife.stats.StrifeTrait; import land.face.strife.tasks.BarrierTask; +import land.face.strife.tasks.CombatCountdownTask; import land.face.strife.tasks.EnergyTask; import land.face.strife.tasks.LifeTask; +import land.face.strife.tasks.MinionTask; import land.face.strife.util.SpecialStatusUtil; import land.face.strife.util.StatUtil; import org.bukkit.Bukkit; @@ -37,7 +40,6 @@ public class StrifeMob { private final WeakReference champion; private final WeakReference livingEntity; - private WeakReference master; private EntityAbilitySet abilitySet; private final Set mods = new HashSet<>(); @@ -45,17 +47,23 @@ public class StrifeMob { private UUID alliedGuild; private final Set tempEffects = new HashSet<>(); private boolean charmImmune = false; - private final Set minions = new HashSet<>(); private final Set runningBuffs = new HashSet<>(); private final Map takenDamage = new HashMap<>(); private float energy = 0; + private float maxEnergy = 0; private float barrier = 0; + private float maxBarrier = 0; private boolean shielded; + private CombatCountdownTask combatCountdownTask = null; + private final BarrierTask barrierTask = new BarrierTask(this); private final LifeTask lifeTask = new LifeTask(this); private final EnergyTask energyTask = new EnergyTask(this); + private MinionTask minionTask = null; + + private final Set minions = new HashSet<>(); private long cacheStamp = 1L; @@ -73,6 +81,14 @@ public float getBarrier() { return barrier; } + public float getMaxBarrier() { + return maxBarrier; + } + + public void setMaxBarrier(float maxBarrier) { + this.maxBarrier = maxBarrier; + } + public void restoreBarrier(float amount) { if (amount < 0) { Bukkit.getLogger().warning("Tried to restore a negative barrier amount!"); @@ -110,7 +126,6 @@ public float getEnergy() { } public void setEnergy(float energy) { - float maxEnergy = StatUtil.getMaximumEnergy(this); this.energy = Math.min(Math.max(0, energy), maxEnergy); if (getEntity() instanceof Player) { Player player = (Player) getEntity(); @@ -118,6 +133,14 @@ public void setEnergy(float energy) { } } + public float getMaxEnergy() { + return maxEnergy; + } + + public void setMaxEnergy(float maxEnergy) { + this.maxEnergy = maxEnergy; + } + public void trackDamage(StrifeMob attacker, float amount) { trackDamage(attacker.getEntity().getUniqueId(), amount); } @@ -312,7 +335,7 @@ public boolean isMinionOf(StrifeMob strifeMob) { } public boolean isMasterOf(StrifeMob strifeMob) { - return strifeMob.getMaster() == livingEntity; + return strifeMob.getMaster() == this; } public boolean isMasterOf(LivingEntity entity) { @@ -331,26 +354,30 @@ public boolean hasTrait(StrifeTrait trait) { return Objects.requireNonNull(champion.get()).hasTrait(trait); } + public void removeMinion(StrifeMob minion) { + minions.remove(minion); + } + public Set getMinions() { minions.removeIf(minion -> minion == null || minion.getEntity() == null || !minion.getEntity().isValid()); return new HashSet<>(minions); } - public void addMinion(StrifeMob strifeMob) { - minions.add(strifeMob); - strifeMob.forceSetStat(StrifeStat.MINION_MULT_INTERNAL, getStat(StrifeStat.MINION_DAMAGE)); - strifeMob.forceSetStat(StrifeStat.ACCURACY_MULT, 0f); - strifeMob.forceSetStat(StrifeStat.ACCURACY, StatUtil.getAccuracy(this)); - SpecialStatusUtil.setDespawnOnUnload(strifeMob.getEntity()); - strifeMob.setMaster(livingEntity.get()); + public void addMinion(StrifeMob minion, int lifespan) { + minions.add(minion); + minion.forceSetStat(StrifeStat.MINION_MULT_INTERNAL, getStat(StrifeStat.MINION_DAMAGE)); + minion.forceSetStat(StrifeStat.ACCURACY_MULT, 0f); + minion.forceSetStat(StrifeStat.ACCURACY, StatUtil.getAccuracy(this)); + SpecialStatusUtil.setDespawnOnUnload(minion.getEntity()); + minion.setMaster(this, lifespan); } - public LivingEntity getMaster() { - return master == null ? null : master.get(); + public StrifeMob getMaster() { + return minionTask == null ? null : minionTask.getMaster(); } - public void setMaster(LivingEntity master) { - this.master = new WeakReference<>(master); + public void setMaster(StrifeMob master, int lifespan) { + minionTask = new MinionTask(this, master, lifespan); } public void addHealingOverTime(float amount, int ticks) { @@ -373,6 +400,26 @@ public void setCharmImmune(boolean charmImmune) { this.charmImmune = charmImmune; } + public void bumpCombat() { + if (isInCombat()) { + combatCountdownTask.bump(); + return; + } + combatCountdownTask = new CombatCountdownTask(this); + combatCountdownTask.runTaskTimer(StrifePlugin.getInstance(), 0L, 10L); + } + + public void endCombat() { + if (!combatCountdownTask.isCancelled()) { + combatCountdownTask.cancel(); + } + combatCountdownTask = null; + } + + public boolean isInCombat() { + return combatCountdownTask != null; + } + public Map getBuffStats() { Map stats = new HashMap<>(); Iterator iterator = runningBuffs.iterator(); diff --git a/src/main/java/land/face/strife/data/TargetResponse.java b/src/main/java/land/face/strife/data/TargetResponse.java index e4f7558d..dc951eba 100644 --- a/src/main/java/land/face/strife/data/TargetResponse.java +++ b/src/main/java/land/face/strife/data/TargetResponse.java @@ -9,6 +9,7 @@ public class TargetResponse { private final Set entities = new HashSet<>(); private Location location = null; + private boolean cancelOnCasterDeath = false; public TargetResponse(Set entities, Location location) { this.entities.addAll(entities); @@ -19,6 +20,19 @@ public TargetResponse(Set entities) { this.entities.addAll(entities); } + public TargetResponse(Set entities, boolean cancelOnCasterDeath) { + this.entities.addAll(entities); + this.cancelOnCasterDeath = cancelOnCasterDeath; + } + + public boolean isCancelOnCasterDeath() { + return cancelOnCasterDeath; + } + + public void setCancelOnCasterDeath(boolean cancelOnCasterDeath) { + this.cancelOnCasterDeath = cancelOnCasterDeath; + } + public TargetResponse(Location location) { this.location = location; } diff --git a/src/main/java/land/face/strife/data/UniqueEntity.java b/src/main/java/land/face/strife/data/UniqueEntity.java index 25704046..32c123e7 100644 --- a/src/main/java/land/face/strife/data/UniqueEntity.java +++ b/src/main/java/land/face/strife/data/UniqueEntity.java @@ -28,6 +28,7 @@ public class UniqueEntity { private boolean angry; private boolean zombificationImmune; private boolean armsRaised; + private boolean gravity; private Profession profession; private int size; private int followRange = -1; @@ -153,6 +154,14 @@ public void setArmsRaised(boolean armsRaised) { this.armsRaised = armsRaised; } + public boolean isGravity() { + return gravity; + } + + public void setGravity(boolean gravity) { + this.gravity = gravity; + } + public Profession getProfession() { return profession; } diff --git a/src/main/java/land/face/strife/data/champion/LifeSkillType.java b/src/main/java/land/face/strife/data/champion/LifeSkillType.java index 073d317b..7943ad5c 100644 --- a/src/main/java/land/face/strife/data/champion/LifeSkillType.java +++ b/src/main/java/land/face/strife/data/champion/LifeSkillType.java @@ -16,6 +16,7 @@ public enum LifeSkillType { AGILITY("Agility", "agility", ChatColor.DARK_AQUA), TRADING("Trading", "trading", ChatColor.DARK_GREEN), SWORDSMANSHIP("Swordsmanship", "sword", ChatColor.RED), + DAGGER_MASTERY("Dagger Mastery", "dagger", ChatColor.YELLOW), AXE_MASTERY("Axe Mastery", "axe", ChatColor.RED), BLUNT_WEAPONS("Blunt Weapons", "blunt", ChatColor.RED), DUAL_WIELDING("Dual Wielding", "dual", ChatColor.GREEN), diff --git a/src/main/java/land/face/strife/data/champion/PlayerEquipmentCache.java b/src/main/java/land/face/strife/data/champion/PlayerEquipmentCache.java index c0998b6c..fc8c57c1 100644 --- a/src/main/java/land/face/strife/data/champion/PlayerEquipmentCache.java +++ b/src/main/java/land/face/strife/data/champion/PlayerEquipmentCache.java @@ -26,10 +26,10 @@ public class PlayerEquipmentCache { private final Map combinedStats = new HashMap<>(); private final Set combinedTraits = new HashSet<>(); - public final static EquipmentSlot[] itemSlots = EquipmentSlot.values(); + public final static EquipmentSlot[] ITEM_SLOTS = EquipmentSlot.values(); PlayerEquipmentCache() { - for (EquipmentSlot slot : itemSlots) { + for (EquipmentSlot slot : ITEM_SLOTS) { slotHashCodeMap.put(slot, -1); slotStatMap.put(slot, new HashMap<>()); slotAbilityMap.put(slot, new ArrayList<>()); @@ -110,7 +110,7 @@ public void recombineAbilities(Champion champion) { loreAbilities.get(triggerType).clear(); } Set newAbilities = new HashSet<>(champion.getSaveData().getBoundAbilities()); - for (EquipmentSlot slot : itemSlots) { + for (EquipmentSlot slot : ITEM_SLOTS) { newAbilities.addAll(slotAbilityMap.get(slot)); } for (LoreAbility la : newAbilities) { diff --git a/src/main/java/land/face/strife/data/conditions/EnergyCondition.java b/src/main/java/land/face/strife/data/conditions/EnergyCondition.java index b64cd391..cac5d2ad 100644 --- a/src/main/java/land/face/strife/data/conditions/EnergyCondition.java +++ b/src/main/java/land/face/strife/data/conditions/EnergyCondition.java @@ -19,7 +19,7 @@ public boolean isMet(StrifeMob attacker, StrifeMob target) { return false; } if (percentage) { - float energy = trueTarget.getEnergy() / StatUtil.getMaximumEnergy(trueTarget); + float energy = trueTarget.getEnergy() / StatUtil.updateMaxEnergy(trueTarget); return PlayerDataUtil.conditionCompare(getComparison(), energy, getValue()); } else { float energy = target.getEnergy(); diff --git a/src/main/java/land/face/strife/data/conditions/InCombatCondition.java b/src/main/java/land/face/strife/data/conditions/InCombatCondition.java index 5127e57d..f6946006 100644 --- a/src/main/java/land/face/strife/data/conditions/InCombatCondition.java +++ b/src/main/java/land/face/strife/data/conditions/InCombatCondition.java @@ -1,11 +1,6 @@ package land.face.strife.data.conditions; -import land.face.strife.StrifePlugin; import land.face.strife.data.StrifeMob; -import land.face.strife.util.TargetingUtil; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Mob; -import org.bukkit.entity.Player; public class InCombatCondition extends Condition { @@ -16,14 +11,7 @@ public InCombatCondition(boolean state) { } public boolean isMet(StrifeMob caster, StrifeMob target) { - LivingEntity entity = getCompareTarget() == CompareTarget.SELF ? caster.getEntity() : target.getEntity(); - if (entity instanceof Player) { - return state == StrifePlugin.getInstance().getCombatStatusManager() - .isInCombat((Player) entity); - } - if (entity instanceof Mob) { - return state == (TargetingUtil.getMobTarget(entity) != null); - } - throw new IllegalArgumentException("Combat condition can only work on players and mobs"); + StrifeMob mob = getCompareTarget() == CompareTarget.SELF ? caster : target; + return state == mob.isInCombat(); } } diff --git a/src/main/java/land/face/strife/data/effects/AreaEffect.java b/src/main/java/land/face/strife/data/effects/AreaEffect.java index 1150a203..c9abd522 100644 --- a/src/main/java/land/face/strife/data/effects/AreaEffect.java +++ b/src/main/java/land/face/strife/data/effects/AreaEffect.java @@ -36,7 +36,7 @@ public class AreaEffect extends LocationEffect { private TargetingPriority priority; private LineOfSight lineOfSight; private float range; - private float maxConeRadius; + private float radius; private int maxTargets; private boolean scaleTargetsWithMultishot; private boolean canBeEvaded; @@ -93,10 +93,11 @@ private Set getAreaEffectTargets(StrifeMob caster, Location locati areaTargets.addAll(TargetingUtil.getEntitiesInArea(location, range)); break; case LINE: - areaTargets.addAll(TargetingUtil.getEntitiesInLine(location, range)); + areaTargets.addAll(TargetingUtil.getEntitiesInLine(location, range, radius)); break; case CONE: - areaTargets.addAll(TargetingUtil.getEntitiesInCone(location, location.getDirection(), range, maxConeRadius)); + areaTargets.addAll(TargetingUtil.getEntitiesInCone(location, location.getDirection(), range, + radius)); break; case PARTY: if (caster.getEntity() instanceof Player) { @@ -218,15 +219,8 @@ public void setRange(double range) { this.range = (float) range; } - public float getMaxConeRadius() { - if (areaType != AreaType.CONE) { - throw new IllegalStateException("You cannot get cone radius on non-cone aoes dingus"); - } - return maxConeRadius; - } - - public void setMaxConeRadius(float maxConeRadius) { - this.maxConeRadius = maxConeRadius; + public void setRadius(float radius) { + this.radius = radius; } public int getMaxTargets() { diff --git a/src/main/java/land/face/strife/data/effects/ChangeEnergy.java b/src/main/java/land/face/strife/data/effects/ChangeEnergy.java index b0876b3f..237f033e 100644 --- a/src/main/java/land/face/strife/data/effects/ChangeEnergy.java +++ b/src/main/java/land/face/strife/data/effects/ChangeEnergy.java @@ -1,7 +1,9 @@ package land.face.strife.data.effects; +import land.face.strife.data.BonusDamage; import land.face.strife.data.StrifeMob; import land.face.strife.stats.StrifeStat; +import land.face.strife.util.DamageUtil; import land.face.strife.util.DamageUtil.DamageScale; import land.face.strife.util.StatUtil; @@ -19,28 +21,9 @@ public void apply(StrifeMob caster, StrifeMob target) { for (StrifeStat attr : getStatMults().keySet()) { restoreAmount += getStatMults().get(attr) * caster.getStat(attr); } - switch (damageScale) { - case FLAT: - StatUtil.changeEnergy(target, restoreAmount); - return; - case TARGET_CURRENT_ENERGY: - StatUtil.changeEnergy(target, restoreAmount * target.getEnergy()); - return; - case TARGET_MISSING_ENERGY: - StatUtil.changeEnergy(target, restoreAmount * getMissingEnergy(target)); - return; - case TARGET_MAX_ENERGY: - StatUtil.changeEnergy(target, restoreAmount * StatUtil.getMaximumEnergy(target)); - return; - case CASTER_CURRENT_ENERGY: - StatUtil.changeEnergy(target, restoreAmount * caster.getEnergy()); - return; - case CASTER_MISSING_ENERGY: - StatUtil.changeEnergy(target, restoreAmount * getMissingEnergy(caster)); - return; - case CASTER_MAX_ENERGY: - StatUtil.changeEnergy(target, restoreAmount * StatUtil.getMaximumEnergy(caster)); - } + BonusDamage bonusDamage = new BonusDamage(damageScale, null, null, restoreAmount); + restoreAmount = DamageUtil.applyDamageScale(caster, target, bonusDamage); + StatUtil.changeEnergy(target, restoreAmount); } public void setAmount(float amount) { @@ -50,8 +33,4 @@ public void setAmount(float amount) { public void setDamageScale(DamageScale damageScale) { this.damageScale = damageScale; } - - private float getMissingEnergy(StrifeMob mob) { - return 1 - mob.getEnergy() / StatUtil.getMaximumEnergy(mob); - } } \ No newline at end of file diff --git a/src/main/java/land/face/strife/data/effects/ChangeRage.java b/src/main/java/land/face/strife/data/effects/ChangeRage.java index fc50caa7..fc067cdd 100644 --- a/src/main/java/land/face/strife/data/effects/ChangeRage.java +++ b/src/main/java/land/face/strife/data/effects/ChangeRage.java @@ -1,26 +1,35 @@ package land.face.strife.data.effects; -import land.face.strife.StrifePlugin; +import land.face.strife.data.BonusDamage; import land.face.strife.data.StrifeMob; import land.face.strife.stats.StrifeStat; +import land.face.strife.util.DamageUtil; +import land.face.strife.util.DamageUtil.DamageScale; public class ChangeRage extends Effect { private float amount; + private DamageScale damageScale; @Override public void apply(StrifeMob caster, StrifeMob target) { if (target.getStat(StrifeStat.MAXIMUM_RAGE) == 0) { return; } - float rageAmount = amount; + float restoreAmount = amount; for (StrifeStat attr : getStatMults().keySet()) { - rageAmount += getStatMults().get(attr) * caster.getStat(attr); + restoreAmount += getStatMults().get(attr) * caster.getStat(attr); } - StrifePlugin.getInstance().getRageManager().changeRage(target, rageAmount); + BonusDamage bonusDamage = new BonusDamage(damageScale, null, null, restoreAmount); + restoreAmount = DamageUtil.applyDamageScale(caster, target, bonusDamage); + getPlugin().getRageManager().changeRage(target, restoreAmount); } public void setAmount(float amount) { this.amount = amount; } + + public void setDamageScale(DamageScale damageScale) { + this.damageScale = damageScale; + } } \ No newline at end of file diff --git a/src/main/java/land/face/strife/data/effects/Charm.java b/src/main/java/land/face/strife/data/effects/Charm.java index 92840658..66759114 100644 --- a/src/main/java/land/face/strife/data/effects/Charm.java +++ b/src/main/java/land/face/strife/data/effects/Charm.java @@ -40,10 +40,11 @@ public void apply(StrifeMob caster, StrifeMob target) { ((Mob) target.getEntity()).setTarget(null); - caster.addMinion(target); + float lifespan = lifespanSeconds * (1 + (caster.getStat(StrifeStat.EFFECT_DURATION) / 100)); + + caster.addMinion(target, (int) lifespan); target.getFactions().clear(); - getPlugin().getMinionManager().addMinion(target.getEntity(), (int) ((lifespanSeconds * 20D) / 11D)); getPlugin().getSpawnerManager().addRespawnTime(target.getEntity()); } diff --git a/src/main/java/land/face/strife/data/effects/Damage.java b/src/main/java/land/face/strife/data/effects/Damage.java index f7849d76..7e544b3d 100644 --- a/src/main/java/land/face/strife/data/effects/Damage.java +++ b/src/main/java/land/face/strife/data/effects/Damage.java @@ -36,12 +36,16 @@ public class Damage extends Effect { private boolean applyOnHitEffects; private boolean showPopoffs; private boolean bypassBarrier; - private List hitEffects = new ArrayList<>(); - private List killEffects = new ArrayList<>(); + private final List hitEffects = new ArrayList<>(); + private final List killEffects = new ArrayList<>(); @Override public void apply(StrifeMob caster, StrifeMob target) { + if (!target.getEntity().isValid()) { + return; + } + DamageModifiers mods = new DamageModifiers(); mods.setAttackType(attackType); mods.setAttackMultiplier(attackMultiplier); diff --git a/src/main/java/land/face/strife/data/effects/EquipmentSwap.java b/src/main/java/land/face/strife/data/effects/EquipmentSwap.java index 04da4fdc..5fd5e789 100644 --- a/src/main/java/land/face/strife/data/effects/EquipmentSwap.java +++ b/src/main/java/land/face/strife/data/effects/EquipmentSwap.java @@ -11,7 +11,7 @@ public class EquipmentSwap extends Effect { - private Map itemMap = new HashMap<>(); + private final Map itemMap = new HashMap<>(); @Override public void apply(StrifeMob caster, StrifeMob target) { diff --git a/src/main/java/land/face/strife/data/effects/EvokerFangEffect.java b/src/main/java/land/face/strife/data/effects/EvokerFangEffect.java index f29706af..9988abbf 100644 --- a/src/main/java/land/face/strife/data/effects/EvokerFangEffect.java +++ b/src/main/java/land/face/strife/data/effects/EvokerFangEffect.java @@ -1,23 +1,22 @@ package land.face.strife.data.effects; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; import java.util.Random; -import java.util.WeakHashMap; import land.face.strife.data.StrifeMob; +import land.face.strife.util.FangUtil; import org.bukkit.Location; -import org.bukkit.entity.EvokerFangs; public class EvokerFangEffect extends LocationEffect { private int quantity; private float spread; - private String hitEffects; + + private final List hitEffects = new ArrayList<>(); private static final int MAX_GROUND_CHECK = 9; private static final Random RANDOM = new Random(); - public static final Map FANG_EFFECT_MAP = new WeakHashMap<>(); - @Override public void apply(StrifeMob caster, StrifeMob target) { applyAtLocation(caster, target.getEntity().getLocation()); @@ -45,9 +44,7 @@ public void applyAtLocation(StrifeMob caster, Location location) { if (!groundFound) { continue; } - EvokerFangs fangs = fangLoc.getWorld().spawn(fangLoc, EvokerFangs.class); - fangs.setOwner(caster.getEntity()); - FANG_EFFECT_MAP.put(fangs, hitEffects); + FangUtil.createFang(caster, fangLoc, hitEffects, getId()); } } @@ -59,7 +56,7 @@ public void setSpread(float spread) { this.spread = spread; } - public void setHitEffects(String hitEffects) { - this.hitEffects = hitEffects; + public List getHitEffects() { + return hitEffects; } } \ No newline at end of file diff --git a/src/main/java/land/face/strife/data/effects/ShootProjectile.java b/src/main/java/land/face/strife/data/effects/ShootProjectile.java index f50648e4..154d7819 100644 --- a/src/main/java/land/face/strife/data/effects/ShootProjectile.java +++ b/src/main/java/land/face/strife/data/effects/ShootProjectile.java @@ -55,6 +55,7 @@ public class ShootProjectile extends Effect { private ItemStack thrownStack = null; private List hitEffects = new ArrayList<>(); private boolean throwItem; + private boolean throwSpin; @Override public void apply(StrifeMob caster, StrifeMob target) { @@ -156,7 +157,7 @@ public void apply(StrifeMob caster, StrifeMob target) { stack = new ItemStack(Material.IRON_SWORD); } } - new ThrownItemTask(projectile, stack, originLocation).runTaskTimer(getPlugin(), 0L, 1L); + new ThrownItemTask(projectile, stack, originLocation, throwSpin).runTaskTimer(getPlugin(), 0L, 1L); } } ProjectileUtil.bumpShotId(); @@ -246,6 +247,10 @@ public void setAttackMultiplier(double attackMultiplier) { this.attackMultiplier = attackMultiplier; } + public void setThrowSpin(boolean throwSpin) { + this.throwSpin = throwSpin; + } + private Vector getCastDirection(LivingEntity caster, LivingEntity target) { Vector direction; if (targeted) { diff --git a/src/main/java/land/face/strife/data/effects/Summon.java b/src/main/java/land/face/strife/data/effects/Summon.java index 5712b2fa..d2fd31e4 100644 --- a/src/main/java/land/face/strife/data/effects/Summon.java +++ b/src/main/java/land/face/strife/data/effects/Summon.java @@ -1,21 +1,36 @@ package land.face.strife.data.effects; +import static land.face.strife.data.champion.PlayerEquipmentCache.ITEM_SLOTS; + import land.face.strife.StrifePlugin; import land.face.strife.data.StrifeMob; +import land.face.strife.listeners.SpawnListener; import land.face.strife.stats.StrifeStat; +import land.face.strife.util.ItemUtil; +import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.disguisetypes.MobDisguise; +import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; +import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Mob; import org.bukkit.entity.Player; import org.bukkit.entity.Tameable; +import org.bukkit.inventory.EquipmentSlot; public class Summon extends LocationEffect { private String uniqueEntity; private String soundEffect; + private float lifeMult; private int amount; private double lifespanSeconds; private boolean mount; + private boolean clone; @Override public void apply(StrifeMob caster, StrifeMob target) { @@ -31,16 +46,44 @@ public void applyAtLocation(StrifeMob caster, Location location) { return; } - StrifeMob summonedEntity = StrifePlugin.getInstance().getUniqueEntityManager().spawnUnique(uniqueEntity, location); + StrifeMob summonedEntity = StrifePlugin.getInstance().getUniqueEntityManager() + .spawnUnique(uniqueEntity, location); if (summonedEntity == null || summonedEntity.getEntity() == null) { return; } LivingEntity summon = summonedEntity.getEntity(); - caster.addMinion(summonedEntity); + double lifespan = lifespanSeconds * (1 + (caster.getStat(StrifeStat.EFFECT_DURATION) / 100)); + caster.addMinion(summonedEntity, (int) lifespan); + + if (clone) { + Disguise disguise; + if (caster.getEntity().getType() == EntityType.PLAYER) { + disguise = new PlayerDisguise((Player) caster.getEntity()); + ((PlayerDisguise) disguise).setName(""); + } else { + disguise = new MobDisguise(DisguiseType.getType(caster.getEntity().getType())); + } + disguise.setReplaceSounds(true); + disguise.setDynamicName(true); + + DisguiseAPI.disguiseToAll(summonedEntity.getEntity(), disguise); + + Bukkit.getScheduler().runTaskLater(StrifePlugin.getInstance(), () -> { + for (EquipmentSlot slot : ITEM_SLOTS) { + if (slot == EquipmentSlot.HAND && ItemUtil + .isWandOrStaff(caster.getEntity().getEquipment().getItem(EquipmentSlot.HAND))) { + summonedEntity.getEntity().getEquipment().setItem(slot, SpawnListener.SKELETON_WAND); + } else { + summonedEntity.getEntity().getEquipment() + .setItem(slot, caster.getEntity().getEquipment().getItem(slot)); + } + } + }, 2L); + } - StrifePlugin.getInstance().getMinionManager().addMinion(summon, (int) ((lifespanSeconds * 20D) / 11D)); + summonedEntity.setStats(caster.getBaseStats()); if (caster.getEntity() instanceof Mob && summon instanceof Mob) { ((Mob) summon).setTarget(((Mob) caster.getEntity()).getTarget()); @@ -51,7 +94,8 @@ public void applyAtLocation(StrifeMob caster, Location location) { } if (soundEffect != null) { - PlaySound sound = (PlaySound) StrifePlugin.getInstance().getEffectManager().getEffect(soundEffect); + PlaySound sound = (PlaySound) StrifePlugin.getInstance().getEffectManager() + .getEffect(soundEffect); sound.applyAtLocation(caster, summon.getLocation()); } @@ -59,6 +103,7 @@ public void applyAtLocation(StrifeMob caster, Location location) { summon.addPassenger(caster.getEntity()); } double maxHealth = summon.getMaxHealth() * (1 + (caster.getStat(StrifeStat.MINION_LIFE) / 100)); + summon.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(maxHealth); summon.setHealth(maxHealth); } @@ -81,4 +126,12 @@ public void setMount(boolean mount) { public void setSoundEffect(String soundEffect) { this.soundEffect = soundEffect; } + + public void setLifeMult(float lifeMult) { + this.lifeMult = lifeMult; + } + + public void setClone(boolean clone) { + this.clone = clone; + } } diff --git a/src/main/java/land/face/strife/data/effects/TriggerLoreAbility.java b/src/main/java/land/face/strife/data/effects/TriggerLoreAbility.java new file mode 100644 index 00000000..f4d9d21f --- /dev/null +++ b/src/main/java/land/face/strife/data/effects/TriggerLoreAbility.java @@ -0,0 +1,26 @@ +package land.face.strife.data.effects; + +import land.face.strife.data.StrifeMob; +import land.face.strife.data.champion.Champion; +import land.face.strife.listeners.LoreAbilityListener; +import land.face.strife.managers.LoreAbilityManager.TriggerType; + +public class TriggerLoreAbility extends Effect { + + public TriggerLoreAbility(TriggerType triggerType) { + this.triggerType = triggerType; + } + + private final TriggerType triggerType; + + @Override + public void apply(StrifeMob caster, StrifeMob target) { + Champion champion = caster.getChampion(); + if (champion != null) { + LoreAbilityListener.executeBoundEffects(caster, target.getEntity(), champion.getLoreAbilities().get(triggerType)); + } + LoreAbilityListener.executeFiniteEffects(caster, target, triggerType); + } + + +} \ No newline at end of file diff --git a/src/main/java/land/face/strife/listeners/CombatListener.java b/src/main/java/land/face/strife/listeners/CombatListener.java index d2b62029..b6811aeb 100644 --- a/src/main/java/land/face/strife/listeners/CombatListener.java +++ b/src/main/java/land/face/strife/listeners/CombatListener.java @@ -36,6 +36,7 @@ import land.face.strife.util.DamageUtil; import land.face.strife.util.DamageUtil.AttackType; import land.face.strife.util.DamageUtil.DamageType; +import land.face.strife.util.FangUtil; import land.face.strife.util.ItemUtil; import land.face.strife.util.ProjectileUtil; import land.face.strife.util.StatUtil; @@ -43,6 +44,7 @@ import org.bukkit.Bukkit; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Bee; +import org.bukkit.entity.EvokerFangs; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; @@ -118,6 +120,10 @@ public void strifeDamageHandler(EntityDamageByEntityEvent event) { if (!(event.getEntity() instanceof LivingEntity) || event.getEntity() instanceof ArmorStand) { return; } + if (event.getDamager() instanceof EvokerFangs && FangUtil.isNoDamageFang((EvokerFangs) event.getDamager())) { + event.setCancelled(true); + return; + } LivingEntity defendEntity = (LivingEntity) event.getEntity(); LivingEntity attackEntity = DamageUtil.getAttacker(event.getDamager()); diff --git a/src/main/java/land/face/strife/listeners/DataListener.java b/src/main/java/land/face/strife/listeners/DataListener.java index 0cedea89..a6500652 100644 --- a/src/main/java/land/face/strife/listeners/DataListener.java +++ b/src/main/java/land/face/strife/listeners/DataListener.java @@ -21,12 +21,14 @@ import land.face.strife.data.StrifeMob; import land.face.strife.data.champion.Champion; import land.face.strife.stats.AbilitySlot; +import land.face.strife.util.ChunkUtil; import land.face.strife.util.DamageUtil; import land.face.strife.util.SpecialStatusUtil; import land.face.strife.util.StatUtil; import land.face.strife.util.TargetingUtil; import org.bukkit.Bukkit; import org.bukkit.Chunk; +import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.entity.Entity; import org.bukkit.entity.FallingBlock; @@ -114,13 +116,7 @@ public void onEntityAttack(final EntityDamageByEntityEvent event) { } LivingEntity attacker = DamageUtil.getAttacker(event.getDamager()); if (attacker instanceof Player) { - plugin.getCombatStatusManager().addPlayer((Player) attacker); - plugin.getBossBarManager().pushBar((Player) attacker, - plugin.getStrifeMobManager().getStatMob((LivingEntity) event.getEntity())); - return; - } - if (event.getEntity() instanceof Player) { - plugin.getCombatStatusManager().addPlayer((Player) event.getEntity()); + plugin.getBossBarManager().pushBar((Player) attacker, plugin.getStrifeMobManager().getStatMob((LivingEntity) event.getEntity())); } } @@ -129,8 +125,8 @@ public void onPlayerJoin(final PlayerJoinEvent event) { event.getPlayer().setHealthScaled(false); Champion champion = plugin.getChampionManager().getChampion(event.getPlayer()); plugin.getAbilityManager().loadPlayerCooldowns(event.getPlayer()); - plugin.getChampionManager().verifyStatValues(champion); plugin.getBoostManager().updateGlobalBoostStatus(event.getPlayer()); + plugin.getChampionManager().verifyStatValues(champion); if (champion.getUnusedStatPoints() > 0) { notifyUnusedPoints(event.getPlayer(), champion.getUnusedStatPoints()); @@ -144,8 +140,10 @@ public void onPlayerJoin(final PlayerJoinEvent event) { plugin.getChampionManager().update(event.getPlayer()); - Bukkit.getScheduler().runTaskLater(plugin, - () -> plugin.getAbilityIconManager().setAllAbilityIcons(event.getPlayer()), 2L); + if (event.getPlayer().getGameMode() != GameMode.CREATIVE) { + Bukkit.getScheduler().runTaskLater(plugin, + () -> plugin.getAbilityIconManager().setAllAbilityIcons(event.getPlayer()), 2L); + } } @EventHandler(priority = EventPriority.MONITOR) @@ -201,12 +199,12 @@ public void onInteract(final PlayerInteractEntityEvent event) { @EventHandler(priority = EventPriority.MONITOR) public void chunkLoadMonitor(ChunkLoadEvent e) { - plugin.getSpawnerManager().stampChunk(e.getChunk()); + ChunkUtil.stampChunk(e.getChunk()); } @EventHandler(priority = EventPriority.MONITOR) public void chunkUnloadMonitor(ChunkUnloadEvent e) { - plugin.getSpawnerManager().unstampChunk(e.getChunk()); + ChunkUtil.unstampChunk(e.getChunk()); } @EventHandler(priority = EventPriority.NORMAL) @@ -217,7 +215,7 @@ public void onChunkUnload(ChunkUnloadEvent e) { } plugin.getStrifeMobManager().doChunkDespawn(ent); } - plugin.getSpawnerManager().unstampChunk(e.getChunk()); + ChunkUtil.unstampChunk(e.getChunk()); } @EventHandler(priority = EventPriority.LOWEST) diff --git a/src/main/java/land/face/strife/listeners/DoubleJumpListener.java b/src/main/java/land/face/strife/listeners/DoubleJumpListener.java index 7ba915e1..beb6d22d 100644 --- a/src/main/java/land/face/strife/listeners/DoubleJumpListener.java +++ b/src/main/java/land/face/strife/listeners/DoubleJumpListener.java @@ -14,6 +14,7 @@ import land.face.strife.data.StrifeMob; import land.face.strife.data.champion.LifeSkillType; import land.face.strife.events.AirJumpEvent; +import land.face.strife.stats.StrifeStat; import land.face.strife.util.JumpUtil; import land.face.strife.util.PlayerDataUtil; import land.face.strife.util.StatUtil; @@ -110,6 +111,7 @@ public void airJump(PlayerToggleSneakEvent event) { double bonusY = Math.max(bonusVelocity.getY(), velocity.getY()); bonusVelocity.setY(bonusY); + bonusVelocity.multiply((120 - mob.getStat(StrifeStat.WEIGHT)) / 100); velocity.setY(0); event.getPlayer().setVelocity(velocity.add(bonusVelocity)); diff --git a/src/main/java/land/face/strife/listeners/EvokerFangEffectListener.java b/src/main/java/land/face/strife/listeners/EvokerFangEffectListener.java deleted file mode 100644 index ac2c9113..00000000 --- a/src/main/java/land/face/strife/listeners/EvokerFangEffectListener.java +++ /dev/null @@ -1,66 +0,0 @@ -package land.face.strife.listeners; - -import com.tealcube.minecraft.bukkit.shade.apache.commons.lang3.StringUtils; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import land.face.strife.data.StrifeMob; -import land.face.strife.data.TargetResponse; -import land.face.strife.data.effects.Effect; -import land.face.strife.data.effects.EvokerFangEffect; -import land.face.strife.managers.EffectManager; -import land.face.strife.managers.StrifeMobManager; -import org.bukkit.entity.EvokerFangs; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; - -public class EvokerFangEffectListener implements Listener { - - private final StrifeMobManager strifeMobManager; - private final EffectManager effectManager; - - public EvokerFangEffectListener(StrifeMobManager strifeMobManager, EffectManager effectManager) { - this.strifeMobManager = strifeMobManager; - this.effectManager = effectManager; - } - - @EventHandler(priority = EventPriority.NORMAL) - public void onEvokerFangHit(EntityDamageByEntityEvent event) { - if (!(event.getDamager() instanceof EvokerFangs)) { - return; - } - if (!(event.getEntity() instanceof LivingEntity)) { - return; - } - String effects = EvokerFangEffect.FANG_EFFECT_MAP.getOrDefault(event.getDamager(), null); - if (StringUtils.isBlank(effects)) { - return; - } - - String[] split = effects.split("~"); - if (split.length == 0) { - return; - } - EvokerFangs fangs = (EvokerFangs) event.getDamager(); - StrifeMob attacker = strifeMobManager.getStatMob(Objects.requireNonNull(fangs.getOwner())); - - Set targets = new HashSet<>(); - TargetResponse response = new TargetResponse(targets); - - List effectList = new ArrayList<>(); - for (String s : split) { - Effect effect = effectManager.getEffect(s); - if (effect != null) { - effectList.add(effect); - } - } - - effectManager.processEffectList(attacker, response, effectList); - event.setCancelled(true); - } -} diff --git a/src/main/java/land/face/strife/listeners/ExperienceListener.java b/src/main/java/land/face/strife/listeners/ExperienceListener.java index 4db4449c..1d521f85 100644 --- a/src/main/java/land/face/strife/listeners/ExperienceListener.java +++ b/src/main/java/land/face/strife/listeners/ExperienceListener.java @@ -133,7 +133,7 @@ public void onPlayerRespawn(PlayerRespawnEvent event) { } else { double xpToLevel = plugin.getLevelingRate().get(p.getLevel()); lostXP = Math.min(xpToLevel * 0.025, p.getExp() * xpToLevel); - sendMessage(p, "&cAlas! You lost &f" + (int) lostXP + " XP &cfrom dying!"); + sendMessage(p, "&cAlas! You lost &f" + StrifePlugin.INT_FORMAT.format(lostXP) + " XP &cfrom dying!"); p.setExp(Math.max(p.getExp() - 0.025f, 0.00001f)); } plugin.getSoulManager().setLostExp(p, lostXP); diff --git a/src/main/java/land/face/strife/listeners/LaunchAndLandListener.java b/src/main/java/land/face/strife/listeners/LaunchAndLandListener.java index 31fd9554..38f33074 100644 --- a/src/main/java/land/face/strife/listeners/LaunchAndLandListener.java +++ b/src/main/java/land/face/strife/listeners/LaunchAndLandListener.java @@ -59,6 +59,7 @@ public void onLaunch(LaunchEvent event) { bonusVelocity.normalize().multiply(0.28); bonusVelocity.setX(bonusVelocity.getX() * moveMult); bonusVelocity.setZ(bonusVelocity.getZ() * moveMult); + bonusVelocity.multiply((120 - mob.getStat(StrifeStat.WEIGHT)) / 100); Vector oldVelocity = event.getPlayer().getVelocity().clone() .setY(Math.max(0, event.getPlayer().getVelocity().getY())); diff --git a/src/main/java/land/face/strife/listeners/LoreAbilityListener.java b/src/main/java/land/face/strife/listeners/LoreAbilityListener.java index 637698d7..6563e970 100644 --- a/src/main/java/land/face/strife/listeners/LoreAbilityListener.java +++ b/src/main/java/land/face/strife/listeners/LoreAbilityListener.java @@ -15,6 +15,7 @@ import java.util.Iterator; import java.util.Set; +import land.face.strife.StrifePlugin; import land.face.strife.data.LoreAbility; import land.face.strife.data.StrifeMob; import land.face.strife.data.champion.Champion; @@ -175,23 +176,23 @@ public void onStrifeDamage(StrifeDamageEvent event) { executeFiniteEffects(defender, attacker, WHEN_HIT); } - private void executeBoundEffects(StrifeMob caster, LivingEntity target, Set effects) { + public static void executeBoundEffects(StrifeMob caster, LivingEntity target, Set effects) { if (effects == null || effects.isEmpty()) { return; } for (LoreAbility la : effects) { - loreAbilityManager.applyLoreAbility(la, caster, target); + StrifePlugin.getInstance().getLoreAbilityManager().applyLoreAbility(la, caster, target); } } - private void executeFiniteEffects(StrifeMob caster, StrifeMob target, TriggerType type) { + public static void executeFiniteEffects(StrifeMob caster, StrifeMob target, TriggerType type) { Iterator it = caster.getTempEffects().iterator(); while (it.hasNext()) { FiniteUsesEffect tempEffect = it.next(); if (tempEffect.getLoreAbility().getTriggerType() != type) { continue; } - loreAbilityManager.applyLoreAbility(tempEffect.getLoreAbility(), caster, target.getEntity()); + StrifePlugin.getInstance().getLoreAbilityManager().applyLoreAbility(tempEffect.getLoreAbility(), caster, target.getEntity()); if (tempEffect.getUses() > 1) { tempEffect.setUses(tempEffect.getUses() - 1); } else { diff --git a/src/main/java/land/face/strife/listeners/MinionListener.java b/src/main/java/land/face/strife/listeners/MinionListener.java index b84d5e54..c7282a01 100644 --- a/src/main/java/land/face/strife/listeners/MinionListener.java +++ b/src/main/java/land/face/strife/listeners/MinionListener.java @@ -19,7 +19,6 @@ package land.face.strife.listeners; import land.face.strife.data.StrifeMob; -import land.face.strife.managers.MinionManager; import land.face.strife.managers.StrifeMobManager; import land.face.strife.util.DamageUtil; import land.face.strife.util.LogUtil; @@ -38,11 +37,9 @@ public class MinionListener implements Listener { private final StrifeMobManager entityManager; - private final MinionManager minionManager; - public MinionListener(StrifeMobManager entityManager, MinionManager minionManager) { + public MinionListener(StrifeMobManager entityManager) { this.entityManager = entityManager; - this.minionManager = minionManager; } @EventHandler(priority = EventPriority.LOWEST) @@ -51,7 +48,7 @@ public void onMinionTargetAnything(final EntityTargetEvent event) { return; } if (event.getEntity() instanceof LivingEntity) { - if (minionManager.isMinion((LivingEntity) event.getEntity())) { + if (entityManager.getStatMob((LivingEntity) event.getEntity()).getMaster() != null) { event.setCancelled(true); } } diff --git a/src/main/java/land/face/strife/listeners/ShootListener.java b/src/main/java/land/face/strife/listeners/ShootListener.java index 1deb95b1..3d13ab44 100644 --- a/src/main/java/land/face/strife/listeners/ShootListener.java +++ b/src/main/java/land/face/strife/listeners/ShootListener.java @@ -36,7 +36,6 @@ import land.face.strife.data.effects.StrifeParticle; import land.face.strife.data.effects.StrifeParticle.ParticleStyle; import land.face.strife.stats.StrifeStat; -import land.face.strife.util.DamageUtil; import land.face.strife.util.DamageUtil.AttackType; import land.face.strife.util.DamageUtil.OriginLocation; import land.face.strife.util.ItemUtil; @@ -48,7 +47,6 @@ import org.bukkit.Particle; import org.bukkit.Sound; import org.bukkit.entity.Arrow; -import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Trident; @@ -200,46 +198,25 @@ public void onPlayerTridentThrow(ProjectileLaunchEvent event) { @EventHandler public void onDragonFireballHit(final EnderDragonFireballHitEvent event) { event.getAreaEffectCloud().remove(); - List hitEffects = ProjectileUtil.getHitEffects(event.getEntity()); - if (hitEffects.isEmpty()) { + event.setCancelled(true); + + if (!(event.getEntity().getShooter() instanceof LivingEntity)) { return; } - if (event.getTargets() == null || event.getTargets().isEmpty()) { + + List hitEffects = ProjectileUtil.getHitEffects(event.getEntity()); + if (hitEffects.isEmpty()) { return; } - LivingEntity attackEntity = (LivingEntity) event.getEntity().getShooter(); - StrifeMob attacker = plugin.getStrifeMobManager().getStatMob(attackEntity); - - for (Entity e : event.getTargets()) { - if (!(e instanceof LivingEntity)) { - continue; - } - LivingEntity defendEntity = (LivingEntity) e; - StrifeMob defender = plugin.getStrifeMobManager().getStatMob(defendEntity); - - double evasionMultiplier = StatUtil.getMinimumEvasionMult(StatUtil.getEvasion(defender), - StatUtil.getAccuracy(attacker)); - evasionMultiplier = evasionMultiplier + (DamageUtil.rollDouble() * (1 - evasionMultiplier)); - - if (evasionMultiplier <= 0.5) { - DamageUtil.doEvasion(attacker, defender); - event.setCancelled(true); - return; - } + StrifeMob caster = plugin.getStrifeMobManager().getStatMob((LivingEntity) event.getEntity().getShooter()); + Location loc = event.getEntity().getLocation().clone() + .add(event.getEntity().getLocation().getDirection().multiply(-0.25)); - if (plugin.getBlockManager().rollBlock(defender, false)) { - plugin.getBlockManager().blockFatigue(defendEntity, 1.0, false); - plugin.getBlockManager().bumpRunes(defender); - DamageUtil.doBlock(attacker, defender); - event.setCancelled(true); - return; + for (Effect effect : hitEffects) { + if (effect instanceof LocationEffect) { + ((LocationEffect) effect).applyAtLocation(caster, loc); } - - Set targets = new HashSet<>(); - TargetResponse response = new TargetResponse(targets); - - plugin.getEffectManager().processEffectList(attacker, response, hitEffects); } } @@ -281,10 +258,10 @@ private void doPistolShot(StrifeMob mob, float attackMultiplier) { double randomMultishot = Math.pow(Math.random(), 1.5); int projectiles = ProjectileUtil.getTotalProjectiles(1, mob.getStat(StrifeStat.MULTISHOT) * randomMultishot); flintlockHitscan.setMaxTargets(projectiles); - flintlockHitscan.setMaxConeRadius(0.35f * (projectiles - 1)); + flintlockHitscan.setRadius(0.35f * (projectiles - 1)); } else { flintlockHitscan.setMaxTargets(1); - flintlockHitscan.setMaxConeRadius(0f); + flintlockHitscan.setRadius(0f); } flintlockDamage.setAttackMultiplier(attackMultiplier); flintlockDamage.setApplyOnHitEffects(attackMultiplier > 0.5); diff --git a/src/main/java/land/face/strife/listeners/SpawnListener.java b/src/main/java/land/face/strife/listeners/SpawnListener.java index e2404fe1..f31ef868 100644 --- a/src/main/java/land/face/strife/listeners/SpawnListener.java +++ b/src/main/java/land/face/strife/listeners/SpawnListener.java @@ -46,7 +46,7 @@ public class SpawnListener implements Listener { private final ItemStack SKELETON_SWORD; private final ItemStack WITHER_SKELETON_SWORD; - private final ItemStack SKELETON_WAND; + public static ItemStack SKELETON_WAND; private final ItemStack WITCH_HAT; public SpawnListener(StrifePlugin plugin) { @@ -85,7 +85,8 @@ public void onJockeySpawn(CreatureSpawnEvent event) { return; } String world = event.getEntity().getLocation().getWorld().getName(); - if (plugin.getConfig().get("config.leveled-monsters.enabled-worlds." + world) == null) { + if (plugin.getSettings().getStringList("config.leveled-monsters.enabled-worlds") + .contains(world)) { event.setCancelled(true); } } @@ -93,7 +94,8 @@ public void onJockeySpawn(CreatureSpawnEvent event) { @EventHandler(priority = EventPriority.HIGHEST) public void onCreatureSpawnHighest(CreatureSpawnEvent event) { if (event.isCancelled() || event.getEntity().hasMetadata("NPC") || - event.getEntity().hasMetadata("pet") || event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.BREEDING) { + event.getEntity().hasMetadata("pet") + || event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.BREEDING) { return; } if (StringUtils.isNotBlank(SpecialStatusUtil.getUniqueId(event.getEntity()))) { diff --git a/src/main/java/land/face/strife/managers/AbilityManager.java b/src/main/java/land/face/strife/managers/AbilityManager.java index ff34d821..9fed60b1 100644 --- a/src/main/java/land/face/strife/managers/AbilityManager.java +++ b/src/main/java/land/face/strife/managers/AbilityManager.java @@ -454,7 +454,7 @@ private TargetResponse getTargets(StrifeMob caster, LivingEntity target, Ability case SELF: case TOGGLE: targets.add(caster.getEntity()); - return new TargetResponse(targets); + return new TargetResponse(targets, true); case PARTY: if (caster.getEntity() instanceof Player) { targets.addAll(plugin.getSnazzyPartiesHook().getNearbyPartyMembers((Player) caster.getEntity(), @@ -462,17 +462,17 @@ private TargetResponse getTargets(StrifeMob caster, LivingEntity target, Ability } else { targets.add(caster.getEntity()); } - return new TargetResponse(targets); + return new TargetResponse(targets, true); case MASTER: if (caster.getMaster() != null) { - targets.add(caster.getMaster()); + targets.add(caster.getMaster().getEntity()); } - return new TargetResponse(targets); + return new TargetResponse(targets, true); case MINIONS: for (StrifeMob mob : caster.getMinions()) { targets.add(mob.getEntity()); } - return new TargetResponse(targets); + return new TargetResponse(targets, true); case SINGLE_OTHER: if (target != null) { targets.add(target); @@ -483,7 +483,7 @@ private TargetResponse getTargets(StrifeMob caster, LivingEntity target, Ability if (newTarget != null) { targets.add(newTarget); } - return new TargetResponse(targets); + return new TargetResponse(targets, true); case TARGET_AREA: Location loc = TargetingUtil.getTargetLocation(caster.getEntity(), target, ability.getRange(), ability.isRaycastsTargetEntities()); @@ -502,7 +502,7 @@ private TargetResponse getTargets(StrifeMob caster, LivingEntity target, Ability targets.add(Bukkit.getPlayer(soul.getOwner())); } } - return new TargetResponse(targets); + return new TargetResponse(targets, true); } return new TargetResponse(new HashSet<>()); } diff --git a/src/main/java/land/face/strife/managers/BoostManager.java b/src/main/java/land/face/strife/managers/BoostManager.java index c3f4282d..86d2cb13 100644 --- a/src/main/java/land/face/strife/managers/BoostManager.java +++ b/src/main/java/land/face/strife/managers/BoostManager.java @@ -91,24 +91,28 @@ public void updateGlobalBoostStatus(Player player) { if (player.hasPermission("has.donated")) { contributors.add(player.getUniqueId()); } - String id = DiscordSRV.getPlugin().getAccountLinkManager().getDiscordId(player.getUniqueId()); - if (StringUtils.isBlank(id)) { - Bukkit.getLogger().info("No discord linked id found for user - no boost bonus"); - return; - } - Member member = DiscordUtil.getMemberById(id); - if (member == null) { - Bukkit.getLogger().info("No discord member found for id - no boost bonus"); - return; - } - for (Role role : member.getRoles()) { - Bukkit.getLogger().info(role.getName()); - if (role.getName().equals("Boosty Bois")) { - discordBoosters.add(player.getUniqueId()); + try { + String id = DiscordSRV.getPlugin().getAccountLinkManager().getDiscordId(player.getUniqueId()); + if (StringUtils.isBlank(id)) { + Bukkit.getLogger().info("No discord linked id found for user - no boost bonus"); return; } + Member member = DiscordUtil.getMemberById(id); + if (member == null) { + Bukkit.getLogger().info("No discord member found for id - no boost bonus"); + return; + } + for (Role role : member.getRoles()) { + Bukkit.getLogger().info(role.getName()); + if (role.getName().equals("Boosty Bois")) { + discordBoosters.add(player.getUniqueId()); + return; + } + } + Bukkit.getLogger().info("member not a booster - no boost bonus"); + } catch (Exception e) { + Bukkit.getLogger().warning("Error setting up boost data! " + e.getMessage()); } - Bukkit.getLogger().info("member not a booster - no boost bonus"); } public Map getStats() { diff --git a/src/main/java/land/face/strife/managers/BossBarManager.java b/src/main/java/land/face/strife/managers/BossBarManager.java index 42c22bac..2f2f2cee 100644 --- a/src/main/java/land/face/strife/managers/BossBarManager.java +++ b/src/main/java/land/face/strife/managers/BossBarManager.java @@ -20,7 +20,6 @@ import com.tealcube.minecraft.bukkit.TextUtils; import io.pixeloutlaw.minecraft.spigot.garbage.StringExtensionsKt; -import java.text.DecimalFormat; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -57,8 +56,6 @@ public class BossBarManager { private final int skillDuration; private final Random random = new Random(); - private static final DecimalFormat INT_FORMAT = new DecimalFormat("#,###,###"); - public BossBarManager(StrifePlugin plugin) { this.plugin = plugin; this.deathMessages = TextUtils.color(plugin.getSettings().getStringList("language.bar-title-entity-killed")); @@ -101,7 +98,7 @@ void pushSkillBar(Player player, LifeSkillType lifeSkillType) { String name = lifeSkillType.getName(); SkillBar bar = skillBars.get(player); int level = bar.getOwner().getSaveData().getSkillLevel(lifeSkillType); - String xp = INT_FORMAT.format(PlayerDataUtil.getLifeSkillExpToLevel(bar.getOwner(), lifeSkillType)); + String xp = StrifePlugin.INT_FORMAT.format(PlayerDataUtil.getLifeSkillExpToLevel(bar.getOwner(), lifeSkillType)); String barName = StringExtensionsKt .chatColorize("&f" + name + " Lv" + level + " &8- " + "&f(&a" + xp + "xp to " + (level + 1) + "&f)"); bar.getSkillBar().setTitle(barName); @@ -247,9 +244,9 @@ private String createBarTitle(StrifeMob barOwner) { } name += " "; if (!barOwner.hasTrait(StrifeTrait.NO_BARRIER_ALLOWED) && barOwner.getStat(StrifeStat.BARRIER) > 0) { - name = name + ChatColor.WHITE + INT_FORMAT.format(barOwner.getBarrier()) + "❤ "; + name = name + ChatColor.WHITE + StrifePlugin.INT_FORMAT.format(barOwner.getBarrier()) + "❤ "; } - name = name + ChatColor.RED + INT_FORMAT.format(barOwner.getEntity().getHealth()) + "❤"; + name = name + ChatColor.RED + StrifePlugin.INT_FORMAT.format(barOwner.getEntity().getHealth()) + "❤"; return name; } diff --git a/src/main/java/land/face/strife/managers/ChampionManager.java b/src/main/java/land/face/strife/managers/ChampionManager.java index 04c819df..8e8cd136 100644 --- a/src/main/java/land/face/strife/managers/ChampionManager.java +++ b/src/main/java/land/face/strife/managers/ChampionManager.java @@ -203,7 +203,7 @@ private void buildEquipmentAttributes(Champion champion) { PlayerEquipmentCache equipmentCache = champion.getEquipmentCache(); Set updatedSlots = new HashSet<>(); - for (EquipmentSlot slot : PlayerEquipmentCache.itemSlots) { + for (EquipmentSlot slot : PlayerEquipmentCache.ITEM_SLOTS) { ItemStack item = ItemUtil.getItem(equipment, slot); if (!ItemUtil.doesHashMatch(item, equipmentCache.getSlotHash(slot))) { updatedSlots.add(slot); diff --git a/src/main/java/land/face/strife/managers/CombatStatusManager.java b/src/main/java/land/face/strife/managers/CombatStatusManager.java deleted file mode 100644 index 2fadf618..00000000 --- a/src/main/java/land/face/strife/managers/CombatStatusManager.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * The MIT License Copyright (c) 2015 Teal Cube Games - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package land.face.strife.managers; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import land.face.strife.StrifePlugin; -import land.face.strife.data.champion.Champion; -import land.face.strife.data.champion.LifeSkillType; -import org.bukkit.entity.Player; - -public class CombatStatusManager { - - private final StrifePlugin plugin; - private final Map tickMap = new ConcurrentHashMap<>(); - - private static final int SECONDS_TILL_EXPIRY = 8; - - public CombatStatusManager(StrifePlugin plugin) { - this.plugin = plugin; - } - - public boolean isInCombat(Player player) { - return tickMap.containsKey(player); - } - - public void addPlayer(Player player) { - tickMap.put(player, SECONDS_TILL_EXPIRY); - } - - public void tickCombat() { - for (Player player : tickMap.keySet()) { - if (!player.isOnline() || !player.isValid()) { - tickMap.remove(player); - continue; - } - int ticksLeft = tickMap.get(player); - if (ticksLeft < 1) { - doExitCombat(player); - tickMap.remove(player); - continue; - } - tickMap.put(player, ticksLeft - 1); - } - } - - public void doExitCombat(Player player) { - if (!tickMap.containsKey(player)) { - return; - } - Champion champion = plugin.getChampionManager().getChampion(player); - if (champion.getDetailsContainer().getExpValues() == null) { - return; - } - for (LifeSkillType type : champion.getDetailsContainer().getExpValues().keySet()) { - plugin.getSkillExperienceManager().addExperience(player, type, - champion.getDetailsContainer().getExpValues().get(type), false, false); - } - champion.getDetailsContainer().clearAll(); - } -} diff --git a/src/main/java/land/face/strife/managers/EffectManager.java b/src/main/java/land/face/strife/managers/EffectManager.java index fb726bee..fd7c57df 100644 --- a/src/main/java/land/face/strife/managers/EffectManager.java +++ b/src/main/java/land/face/strife/managers/EffectManager.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -154,28 +155,33 @@ public EffectManager(StrifePlugin plugin) { } public void processEffectList(StrifeMob caster, TargetResponse response, List effectList) { - List taskEffects = new ArrayList<>(); - int waitTicks = 0; - for (Effect effect : effectList) { + if (!caster.getEntity().isValid() && response.isCancelOnCasterDeath()) { + return; + } + List taskEffects = new ArrayList<>(effectList); + List taskChunk = new ArrayList<>(); + Iterator runEffects = taskEffects.listIterator(); + while (runEffects.hasNext()) { + Effect effect = runEffects.next(); if (effect == null) { LogUtil.printWarning("Effect is null! Skipping..."); continue; } if (effect instanceof Wait) { - LogUtil.printDebug("Effects in this chunk: " + taskEffects.toString()); - List finalTaskEffects1 = taskEffects; + LogUtil.printDebug("Effects in this chunk: " + taskChunk.toString()); + executeEffectList(caster, response, taskChunk); + runEffects.remove(); + List newEffectList = new ArrayList<>(); + runEffects.forEachRemaining(newEffectList::add); Bukkit.getScheduler().runTaskLater(StrifePlugin.getInstance(), () -> - executeEffectList(caster, response, finalTaskEffects1), waitTicks); - waitTicks += ((Wait) effect).getTickDelay(); - taskEffects = new ArrayList<>(); - continue; + processEffectList(caster, response, newEffectList), ((Wait) effect).getTickDelay()); + return; } - taskEffects.add(effect); + taskChunk.add(effect); + runEffects.remove(); LogUtil.printDebug("Added effect " + effect.getId() + " to task list"); } - List finalTaskEffects = taskEffects; - Bukkit.getScheduler().runTaskLater(StrifePlugin.getInstance(), () -> - executeEffectList(caster, response, finalTaskEffects), waitTicks); + executeEffectList(caster, response, taskChunk); } public void executeEffectList(StrifeMob caster, TargetResponse response, List effectList) { @@ -192,29 +198,35 @@ public void executeEffectList(StrifeMob caster, TargetResponse response, List targets = new HashSet<>(response.getEntities()); - if (!targets.isEmpty()) { - for (LivingEntity le : targets) { - StrifeMob targetMob = plugin.getStrifeMobManager().getStatMob(le); - if (!PlayerDataUtil.areConditionsMet(caster, targetMob, effect.getConditions())) { - continue; - } - if (effect instanceof LocationEffect) { - effect.apply(caster, effect.isForceTargetCaster() ? caster : targetMob); - continue; - } - if (effect.isFriendly() != TargetingUtil.isFriendly(caster, targetMob)) { - continue; - } - applyEffectIfConditionsMet(effect, caster, effect.isForceTargetCaster() ? caster : targetMob); + if (response.getLocation() != null) { + if (!(effect instanceof LocationEffect) && !effect.isForceTargetCaster()) { + return; + } + if (!PlayerDataUtil.areConditionsMet(caster, null, effect.getConditions())) { + return; } + if (effect.isForceTargetCaster()) { + effect.apply(caster, caster); + return; + } + assert effect instanceof LocationEffect; + LocationEffect locEffect = (LocationEffect) effect; + locEffect.applyAtLocation(caster, response.getLocation()); return; } - if (effect instanceof LocationEffect && response.getLocation() != null) { - if (PlayerDataUtil.areConditionsMet(caster, null, effect.getConditions())) { - LocationEffect locEffect = (LocationEffect) effect; - locEffect.applyAtLocation(caster, response.getLocation()); + for (LivingEntity le : response.getEntities()) { + StrifeMob targetMob = plugin.getStrifeMobManager().getStatMob(le); + if (!PlayerDataUtil.areConditionsMet(caster, targetMob, effect.getConditions())) { + continue; } + if (effect instanceof LocationEffect) { + effect.apply(caster, effect.isForceTargetCaster() ? caster : targetMob); + continue; + } + if (effect.isFriendly() != TargetingUtil.isFriendly(caster, targetMob)) { + continue; + } + applyEffectIfConditionsMet(effect, caster, effect.isForceTargetCaster() ? caster : targetMob); } } @@ -273,6 +285,7 @@ public void loadEffect(String key, ConfigurationSection cs) { case INCREASE_RAGE: effect = new ChangeRage(); ((ChangeRage) effect).setAmount((float) cs.getDouble("amount", 1)); + ((ChangeRage) effect).setDamageScale(DamageScale.valueOf(cs.getString("scale", "FLAT"))); break; case DAMAGE: effect = new Damage(); @@ -386,9 +399,7 @@ public void loadEffect(String key, ConfigurationSection cs) { ((AreaEffect) effect).setCanBeCountered(cs.getBoolean("can-be-countered", canBeBlocked)); ((AreaEffect) effect).setCanBeEvaded(cs.getBoolean("can-be-evaded", false)); ((AreaEffect) effect).setTargetingCooldown(cs.getLong("target-cooldown", 0)); - if (((AreaEffect) effect).getAreaType() == AreaType.CONE) { - ((AreaEffect) effect).setMaxConeRadius((float) cs.getDouble("max-cone-radius", 3)); - } + ((AreaEffect) effect).setRadius((float) cs.getDouble("radius", 0.4)); if (((AreaEffect) effect).getMaxTargets() != -1) { ((AreaEffect) effect).setPriority( TargetingPriority.valueOf(cs.getString("priority", "RANDOM"))); @@ -459,6 +470,7 @@ public void loadEffect(String key, ConfigurationSection cs) { ((ShootProjectile) effect).setSilent(cs.getBoolean("silent", false)); ((ShootProjectile) effect).setGravity(cs.getBoolean("gravity", true)); ((ShootProjectile) effect).setThrowItem(cs.getBoolean("thrown-item", false)); + ((ShootProjectile) effect).setThrowSpin(cs.getBoolean("throw-spin", true)); ((ShootProjectile) effect).setBlockHitEffects(cs.getBoolean("effects-on-block-hit", false)); ((ShootProjectile) effect).setAttackMultiplier(cs.getDouble("attack-multiplier", 0D)); ((ShootProjectile) effect).setDisguise(PlayerDataUtil.parseDisguise(cs.getConfigurationSection("disguise"), @@ -502,7 +514,7 @@ public void loadEffect(String key, ConfigurationSection cs) { effect = new EvokerFangEffect(); ((EvokerFangEffect) effect).setQuantity(cs.getInt("quantity", 1)); ((EvokerFangEffect) effect).setSpread((float) cs.getDouble("spread", 0)); - ((EvokerFangEffect) effect).setHitEffects(String.join("~", cs.getStringList("hit-effects"))); + delayedSetEffects(((EvokerFangEffect) effect).getHitEffects(), cs.getStringList("hit-effects"), key, false); break; case FALLING_BLOCK: effect = new ShootBlock(); @@ -625,8 +637,10 @@ public void loadEffect(String key, ConfigurationSection cs) { ((Summon) effect).setAmount(cs.getInt("amount", 1)); ((Summon) effect).setUniqueEntity(cs.getString("unique-entity")); ((Summon) effect).setLifespanSeconds(cs.getInt("lifespan-seconds", 30)); + ((Summon) effect).setLifeMult((float) cs.getDouble("life-multiplier", 1.0)); ((Summon) effect).setSoundEffect(cs.getString("sound-effect-id", null)); ((Summon) effect).setMount(cs.getBoolean("mount", false)); + ((Summon) effect).setClone(cs.getBoolean("clone", false)); break; case CHARM: effect = new Charm(); diff --git a/src/main/java/land/face/strife/managers/MinionManager.java b/src/main/java/land/face/strife/managers/MinionManager.java deleted file mode 100644 index 2cc42c49..00000000 --- a/src/main/java/land/face/strife/managers/MinionManager.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * The MIT License Copyright (c) 2015 Teal Cube Games - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package land.face.strife.managers; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import org.bukkit.entity.LivingEntity; - -public class MinionManager { - - private final Map minionDecayMap = new ConcurrentHashMap<>(); - - public Map getMinionDecayMap() { - return minionDecayMap; - } - - public void addMinion(LivingEntity livingEntity, int ticks) { - minionDecayMap.put(livingEntity, ticks); - } - - public boolean isMinion(LivingEntity livingEntity) { - return minionDecayMap.containsKey(livingEntity); - } - - public void tickMinions() { - for (LivingEntity le : minionDecayMap.keySet()) { - if (le == null || !le.isValid()) { - minionDecayMap.remove(le); - continue; - } - if (!le.getPassengers().isEmpty()) { - continue; - } - int ticks = minionDecayMap.get(le); - minionDecayMap.put(le, ticks - 1); - if (ticks > 0) { - continue; - } - if (ticks <= -15) { - le.damage(le.getMaxHealth() * 10); - } else { - le.damage(le.getMaxHealth() / 10); - } - } - } -} diff --git a/src/main/java/land/face/strife/managers/SpawnerManager.java b/src/main/java/land/face/strife/managers/SpawnerManager.java index e68e68bf..fdbf1f26 100644 --- a/src/main/java/land/face/strife/managers/SpawnerManager.java +++ b/src/main/java/land/face/strife/managers/SpawnerManager.java @@ -1,26 +1,15 @@ package land.face.strife.managers; -import com.tealcube.minecraft.bukkit.facecore.utilities.MessageUtils; import java.util.HashMap; import java.util.Map; import land.face.strife.StrifePlugin; import land.face.strife.data.Spawner; -import land.face.strife.data.StrifeMob; -import land.face.strife.util.SpecialStatusUtil; -import org.apache.commons.lang.StringUtils; -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.Location; -import org.bukkit.Sound; import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; public class SpawnerManager { private final StrifePlugin plugin; private final Map spawnerMap = new HashMap<>(); - private final Map chunkActiveStamp = new HashMap<>(); public SpawnerManager(StrifePlugin plugin) { this.plugin = plugin; @@ -49,97 +38,9 @@ public void addRespawnTime(LivingEntity livingEntity) { } } - public void spawnSpawners() { - for (Spawner s : spawnerMap.values()) { - if (s.getUniqueEntity() == null || s.getLocation() == null) { - continue; - } - - int maxMobs = s.getAmount(); - for (long stamp : s.getRespawnTimes()) { - if (System.currentTimeMillis() > stamp) { - s.getRespawnTimes().remove(stamp); - } - } - - int existingMobs = s.getRespawnTimes().size() + s.getEntities().size(); - if (existingMobs >= maxMobs) { - continue; - } - - if (!isChuckLoaded(s)) { - continue; - } - - int mobDiff = maxMobs - existingMobs; - while (mobDiff > 0) { - - StrifeMob mob = plugin.getUniqueEntityManager() - .spawnUnique(s.getUniqueEntity(), s.getLocation()); - - if (mob == null || mob.getEntity() == null || !mob.getEntity().isValid()) { - Bukkit.getLogger().warning("Spawner failed to spawn unique! " + s.getId()); - continue; - } - - if (mob.getMods().size() >= 2) { - announceSpawnToNearbyPlayers(mob, s.getLocation()); - } - - if (StringUtils.isBlank(s.getUniqueEntity().getMount()) - && mob.getEntity().getVehicle() != null) { - mob.getEntity().getVehicle().remove(); - } - - SpecialStatusUtil.setDespawnOnUnload(mob.getEntity()); - s.addEntity(mob.getEntity()); - - // Random displacement to prevent clumping - if (s.getUniqueEntity().getDisplaceMultiplier() != 0) { - Vector vec = new Vector(-1 + Math.random() * 2, 0.1, -1 + Math.random() * 2).normalize(); - vec.multiply(s.getUniqueEntity().getDisplaceMultiplier()); - mob.getEntity().setVelocity(vec); - mob.getEntity().getLocation().setDirection(mob.getEntity().getVelocity().normalize()); - } - - mobDiff--; - } - } - } - - private void announceSpawnToNearbyPlayers(StrifeMob mob, Location location) { - for (Player p : Bukkit.getOnlinePlayers()) { - if (location.getWorld() != p.getWorld()) { - continue; - } - Vector diff = location.toVector().subtract(p.getLocation().toVector()); - if (diff.lengthSquared() < 6400) { - p.playSound(location, Sound.BLOCK_BEACON_AMBIENT, 100, 0.8F); - MessageUtils.sendMessage(p, - "&7&o&lWoah!! &f" + mob.getEntity().getCustomName() + "&f has spawned nearby!"); - } - } - } - public void cancelAll() { for (Spawner spawner : spawnerMap.values()) { spawner.cancel(); } } - - public void stampChunk(Chunk chunk) { - chunkActiveStamp.put(chunk.getWorld().getName() + chunk.getChunkKey(), System.currentTimeMillis() + 1200); - } - - public void unstampChunk(Chunk chunk) { - chunkActiveStamp.remove(chunk.getWorld().getName() + chunk.getChunkKey()); - } - - private boolean isChuckLoaded(Spawner spawner) { - String chunkId = spawner.getLocation().getWorld().getName() + spawner.getChunkKey(); - if (chunkActiveStamp.containsKey(chunkId)) { - return chunkActiveStamp.get(chunkId) < System.currentTimeMillis(); - } - return false; - } } diff --git a/src/main/java/land/face/strife/managers/StrifeMobManager.java b/src/main/java/land/face/strife/managers/StrifeMobManager.java index 84beb88f..3f8f49fb 100644 --- a/src/main/java/land/face/strife/managers/StrifeMobManager.java +++ b/src/main/java/land/face/strife/managers/StrifeMobManager.java @@ -40,7 +40,7 @@ public StrifeMob getStatMob(LivingEntity entity) { strifeMob.setStats(plugin.getMonsterManager().getBaseStats(entity)); strifeMob.restoreBarrier(200000); strifeMob.setEnergy(entity instanceof Player ? - StatUtil.getMaximumEnergy(strifeMob) * ((Player) entity).getFoodLevel() / 20 : 200000); + StatUtil.updateMaxEnergy(strifeMob) * ((Player) entity).getFoodLevel() / 20 : 200000); trackedEntities.put(entity, strifeMob); } return trackedEntities.get(entity); diff --git a/src/main/java/land/face/strife/managers/UniqueEntityManager.java b/src/main/java/land/face/strife/managers/UniqueEntityManager.java index 7ee7802e..aa9593d3 100644 --- a/src/main/java/land/face/strife/managers/UniqueEntityManager.java +++ b/src/main/java/land/face/strife/managers/UniqueEntityManager.java @@ -98,7 +98,7 @@ private void lambdaSetup(Entity e, UniqueEntity uniqueEntity) { } } - StrifeMob spawnUnique(UniqueEntity uniqueEntity, Location location) { + public StrifeMob spawnUnique(UniqueEntity uniqueEntity, Location location) { if (uniqueEntity.getType() == null) { LogUtil.printWarning("Null entity type: " + uniqueEntity.getName()); return null; @@ -118,6 +118,10 @@ StrifeMob spawnUnique(UniqueEntity uniqueEntity, Location location) { LivingEntity le = (LivingEntity) entity; le.setRemoveWhenFarAway(true); + if (!uniqueEntity.isGravity()) { + le.setGravity(false); + } + if (le instanceof Zombie) { ((Zombie) le).setBaby(uniqueEntity.isBaby()); ((Zombie) le).setArmsRaised(uniqueEntity.isArmsRaised()); @@ -255,8 +259,7 @@ StrifeMob spawnUnique(UniqueEntity uniqueEntity, Location location) { StrifeMob mountMob = spawnUnique(uniqueEntity.getMount(), location); if (mountMob != null) { mountMob.getEntity().addPassenger(mob.getEntity()); - mob.addMinion(mountMob); - StrifePlugin.getInstance().getMinionManager().addMinion(mountMob.getEntity(), 10); + mob.addMinion(mountMob, 0); } } @@ -329,6 +332,7 @@ public void loadUniques(VersionedSmartYamlConfiguration uniqueEnemiesYAML) { uniqueEntity.setAngry(cs.getBoolean("angry", false)); uniqueEntity.setZombificationImmune(cs.getBoolean("zombification-immune", true)); uniqueEntity.setArmsRaised(cs.getBoolean("arms-raised", true)); + uniqueEntity.setGravity(cs.getBoolean("gravity", true)); if (uniqueEntity.getType() == EntityType.VILLAGER || uniqueEntity.getType() == EntityType.ZOMBIE_VILLAGER) { String prof = cs.getString("profession"); if (prof != null) { diff --git a/src/main/java/land/face/strife/menus/stats/StatsMiscMenuItem.java b/src/main/java/land/face/strife/menus/stats/StatsMiscMenuItem.java index ef36f7a7..31288f31 100644 --- a/src/main/java/land/face/strife/menus/stats/StatsMiscMenuItem.java +++ b/src/main/java/land/face/strife/menus/stats/StatsMiscMenuItem.java @@ -59,7 +59,7 @@ public ItemStack getFinalIcon(Player commandSender) { List lore = new ArrayList<>(); lore.add(breakLine); lore.add(ChatColor.DARK_AQUA + "Maximum Energy: " + ChatColor.WHITE + INT_FORMAT - .format(StatUtil.getMaximumEnergy(pStats))); + .format(StatUtil.updateMaxEnergy(pStats))); if (!pStats.hasTrait(StrifeTrait.NO_ENERGY_REGEN)) { lore.add(ChatColor.DARK_AQUA + "Energy Regeneration: " + ChatColor.WHITE + ONE_DECIMAL .format(pStats.getStat(StrifeStat.ENERGY_REGEN)) + PER_TEN); diff --git a/src/main/java/land/face/strife/tasks/BarrierTask.java b/src/main/java/land/face/strife/tasks/BarrierTask.java index 77bdf2cb..48ad9108 100644 --- a/src/main/java/land/face/strife/tasks/BarrierTask.java +++ b/src/main/java/land/face/strife/tasks/BarrierTask.java @@ -18,7 +18,7 @@ public class BarrierTask extends BukkitRunnable { - private static final long TICK_RATE = 2L; + private static final long TICK_RATE = 3L; private static final int DELAY_TICKS = (int) ((float) 120 / TICK_RATE); private static final BlockData BLOCK_DATA = Bukkit.getServer().createBlockData(Material.WHITE_STAINED_GLASS); diff --git a/src/main/java/land/face/strife/tasks/CombatCountdownTask.java b/src/main/java/land/face/strife/tasks/CombatCountdownTask.java new file mode 100644 index 00000000..0d528f8d --- /dev/null +++ b/src/main/java/land/face/strife/tasks/CombatCountdownTask.java @@ -0,0 +1,63 @@ +package land.face.strife.tasks; + +import java.lang.ref.WeakReference; +import land.face.strife.StrifePlugin; +import land.face.strife.data.StrifeMob; +import land.face.strife.data.champion.Champion; +import land.face.strife.data.champion.LifeSkillType; +import land.face.strife.events.CombatChangeEvent; +import land.face.strife.events.CombatChangeEvent.NewCombatState; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +public class CombatCountdownTask extends BukkitRunnable { + + private static final int BUMP_TIME_HALF_SECONDS = 20; + private final WeakReference parentMob; + + private int halfSecondsRemaining; + + public CombatCountdownTask(StrifeMob parentMob) { + this.parentMob = new WeakReference<>(parentMob); + halfSecondsRemaining = BUMP_TIME_HALF_SECONDS; + CombatChangeEvent cce = new CombatChangeEvent(parentMob, NewCombatState.ENTER); + Bukkit.getPluginManager().callEvent(cce); + } + + @Override + public void run() { + StrifeMob mob = parentMob.get(); + if (mob == null || mob.getEntity() == null) { + cancel(); + return; + } + halfSecondsRemaining--; + if (halfSecondsRemaining == 0) { + CombatChangeEvent cce = new CombatChangeEvent(mob, NewCombatState.EXIT); + Bukkit.getPluginManager().callEvent(cce); + cancel(); + awardSkillExp(mob); + mob.endCombat(); + } + } + + public void bump() { + halfSecondsRemaining = BUMP_TIME_HALF_SECONDS; + } + + public static void awardSkillExp(StrifeMob mob) { + Champion champion = mob.getChampion(); + if (champion == null) { + return; + } + if (champion.getDetailsContainer().getExpValues() == null) { + return; + } + for (LifeSkillType type : champion.getDetailsContainer().getExpValues().keySet()) { + StrifePlugin.getInstance().getSkillExperienceManager().addExperience((Player) mob.getEntity(), type, + champion.getDetailsContainer().getExpValues().get(type), false, false); + } + champion.getDetailsContainer().clearAll(); + } +} diff --git a/src/main/java/land/face/strife/tasks/CombatStatusTask.java b/src/main/java/land/face/strife/tasks/CombatStatusTask.java deleted file mode 100644 index f10c994f..00000000 --- a/src/main/java/land/face/strife/tasks/CombatStatusTask.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * The MIT License Copyright (c) 2015 Teal Cube Games - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package land.face.strife.tasks; - -import land.face.strife.managers.CombatStatusManager; -import org.bukkit.scheduler.BukkitRunnable; - -public class CombatStatusTask extends BukkitRunnable { - - private CombatStatusManager combatStatusManager; - - public CombatStatusTask(CombatStatusManager combatStatusManager) { - this.combatStatusManager = combatStatusManager; - } - - @Override - public void run() { - combatStatusManager.tickCombat(); - } -} diff --git a/src/main/java/land/face/strife/tasks/EnergyTask.java b/src/main/java/land/face/strife/tasks/EnergyTask.java index 4c7d3e8a..1f16e2d5 100644 --- a/src/main/java/land/face/strife/tasks/EnergyTask.java +++ b/src/main/java/land/face/strife/tasks/EnergyTask.java @@ -12,7 +12,6 @@ import land.face.strife.stats.StrifeStat; import land.face.strife.stats.StrifeTrait; import land.face.strife.util.PlayerDataUtil; -import land.face.strife.util.StatUtil; import org.bukkit.GameMode; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; @@ -23,10 +22,12 @@ public class EnergyTask extends BukkitRunnable { private final WeakReference parentMob; private final List energyRestore = new ArrayList<>(); + public static final int TICKS_PER = 4; + public static final float TICK_MULT = 1f / (20f / TICKS_PER); public EnergyTask(StrifeMob parentMob) { this.parentMob = new WeakReference<>(parentMob); - this.runTaskTimer(StrifePlugin.getInstance(), 20L, 1L); + this.runTaskTimer(StrifePlugin.getInstance(), 20L, TICKS_PER); } @Override @@ -37,14 +38,25 @@ public void run() { return; } - if (mob.getStat(StrifeStat.ENERGY) == 0 || mob.getEnergy() >= StatUtil.getMaximumEnergy(mob)) { + if (mob.getStat(StrifeStat.ENERGY) < 0.1 || mob.hasTrait(StrifeTrait.NO_ENERGY_REGEN)) { + return; + } + + if (!mob.getEntity().isValid()) { + energyRestore.clear(); + return; + } + + if (mob.getEnergy() >= mob.getMaxEnergy()) { + mob.setEnergy(mob.getMaxEnergy()); + getBonusEnergy(); return; } float energy = 0; boolean noRegen = mob.hasTrait(StrifeTrait.NO_ENERGY_REGEN); if (!noRegen) { - energy += 0.005f * mob.getStat(StrifeStat.ENERGY_REGEN); + energy += TICK_MULT * 0.1f * mob.getStat(StrifeStat.ENERGY_REGEN); energy *= getHungerPotionMult(mob.getEntity()); } @@ -54,19 +66,16 @@ public void run() { return; } - double agility = PlayerDataUtil.getLifeSkillLevel(mob.getChampion(), LifeSkillType.AGILITY); - double agilityMult = 50.0 / (50 + agility); - if (player.getFoodLevel() > 6 && player.isSprinting()) { energy *= StrifePlugin.RUN_COST_PERCENT; - energy -= StrifePlugin.RUN_COST * agilityMult; + energy -= StrifePlugin.RUN_COST * getAgilityMult(mob); } else if (MoveUtil.hasMoved(player)) { if (player.isSprinting()) { player.setSprinting(false); } energy *= StrifePlugin.WALK_COST_PERCENT; if (!noRegen) { - energy -= StrifePlugin.WALK_COST * agilityMult; + energy -= StrifePlugin.WALK_COST * getAgilityMult(mob); } } else { if (player.isSprinting()) { @@ -79,11 +88,16 @@ public void run() { mob.setEnergy(mob.getEnergy() + energy); } + private static float getAgilityMult(StrifeMob mob) { + float agility = PlayerDataUtil.getLifeSkillLevel(mob.getChampion(), LifeSkillType.AGILITY); + return 50f / (50f + agility); + } + public void addEnergyOverTime(float amount, int ticks) { - amount = amount / ticks; + amount = (amount * TICKS_PER) / ticks; RestoreData restoreData = new RestoreData(); restoreData.setAmount(amount); - restoreData.setTicks(ticks); + restoreData.setTicks((int) ((float) ticks / TICKS_PER)); energyRestore.add(restoreData); } diff --git a/src/main/java/land/face/strife/tasks/LifeTask.java b/src/main/java/land/face/strife/tasks/LifeTask.java index c1ed7db4..8fb1f94a 100644 --- a/src/main/java/land/face/strife/tasks/LifeTask.java +++ b/src/main/java/land/face/strife/tasks/LifeTask.java @@ -18,7 +18,7 @@ public class LifeTask extends BukkitRunnable { - private static final long REGEN_TICK_RATE = 4L; + private static final long REGEN_TICK_RATE = 3L; private static final float REGEN_PERCENT_PER_SECOND = 0.1F; private static final float POTION_REGEN_FLAT_PER_LEVEL = 2f; private static final float POTION_REGEN_PERCENT_PER_LEVEL = 0.05f; @@ -39,23 +39,26 @@ public void run() { return; } if (!mob.getEntity().isValid() || mob.getEntity().getHealth() <= 0) { + lifeRestore.clear(); return; } - double playerMaxHealth = mob.getEntity().getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue(); - float tickMultiplier = (1 / (20f / REGEN_TICK_RATE)) * REGEN_PERCENT_PER_SECOND; - - PlayerDataUtil.restoreHealth(mob.getEntity(), getBonusHealth()); + double maxLife = mob.getEntity().getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue(); - if (mob.getEntity().getHealth() >= playerMaxHealth) { + if (mob.getEntity().getHealth() >= maxLife) { + getBonusHealth(); return; } + float tickMultiplier = (1 / (20f / REGEN_TICK_RATE)) * REGEN_PERCENT_PER_SECOND; + + PlayerDataUtil.restoreHealth(mob.getEntity(), getBonusHealth()); + float lifeAmount = StatUtil.getRegen(mob); if (mob.getEntity().hasPotionEffect(REGENERATION)) { int potionIntensity = mob.getEntity().getPotionEffect(REGENERATION).getAmplifier() + 1; lifeAmount += potionIntensity * POTION_REGEN_FLAT_PER_LEVEL; - lifeAmount += potionIntensity * playerMaxHealth * POTION_REGEN_PERCENT_PER_LEVEL; + lifeAmount += potionIntensity * maxLife * POTION_REGEN_PERCENT_PER_LEVEL; } if (mob.getEntity().hasPotionEffect(WITHER)) { lifeAmount *= 0.33f; @@ -68,7 +71,7 @@ public void run() { } lifeAmount *= tickMultiplier; - mob.getEntity().setHealth(Math.min(mob.getEntity().getHealth() + lifeAmount, playerMaxHealth)); + mob.getEntity().setHealth(Math.min(mob.getEntity().getHealth() + lifeAmount, maxLife)); } public void addHealingOverTime(float amount, int ticks) { diff --git a/src/main/java/land/face/strife/tasks/MinionDecayTask.java b/src/main/java/land/face/strife/tasks/MinionDecayTask.java deleted file mode 100644 index 79d7b0a2..00000000 --- a/src/main/java/land/face/strife/tasks/MinionDecayTask.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * The MIT License Copyright (c) 2015 Teal Cube Games - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package land.face.strife.tasks; - -import land.face.strife.managers.MinionManager; -import org.bukkit.scheduler.BukkitRunnable; - -public class MinionDecayTask extends BukkitRunnable { - - private MinionManager minionManager; - - public MinionDecayTask(MinionManager minionManager) { - this.minionManager = minionManager; - } - - @Override - public void run() { - minionManager.tickMinions(); - } -} diff --git a/src/main/java/land/face/strife/tasks/MinionTask.java b/src/main/java/land/face/strife/tasks/MinionTask.java new file mode 100644 index 00000000..eb9b727f --- /dev/null +++ b/src/main/java/land/face/strife/tasks/MinionTask.java @@ -0,0 +1,53 @@ +package land.face.strife.tasks; + +import java.lang.ref.WeakReference; +import java.util.Objects; +import land.face.strife.StrifePlugin; +import land.face.strife.data.StrifeMob; +import org.bukkit.scheduler.BukkitRunnable; + +public class MinionTask extends BukkitRunnable { + + private final WeakReference minion; + private final WeakReference master; + private int lifespan; + + public MinionTask(StrifeMob minion, StrifeMob master, int lifespanSeconds) { + this.minion = new WeakReference<>(minion); + this.master = new WeakReference<>(master); + this.lifespan = lifespanSeconds; + this.runTaskTimer(StrifePlugin.getInstance(), 20L, 20L); + } + + @Override + public void run() { + StrifeMob mob = master.get(); + if (mob == null || mob.getEntity() == null) { + cancel(); + return; + } + StrifeMob minionMob = minion.get(); + if (minionMob == null || minionMob.getEntity() == null || !minionMob.getEntity().isValid()) { + Objects.requireNonNull(master.get()).removeMinion(minionMob); + cancel(); + return; + } + if (!mob.getEntity().getPassengers().isEmpty()) { + return; + } + if (lifespan > 0) { + lifespan--; + return; + } + if (lifespan <= -15) { + minionMob.getEntity().damage(minionMob.getEntity().getMaxHealth() * 10); + } else { + minionMob.getEntity().damage(minionMob.getEntity().getMaxHealth() / 10); + } + } + + public StrifeMob getMaster() { + return master.get(); + } + +} diff --git a/src/main/java/land/face/strife/tasks/SpawnerSpawnTask.java b/src/main/java/land/face/strife/tasks/SpawnerSpawnTask.java deleted file mode 100644 index c2fc787b..00000000 --- a/src/main/java/land/face/strife/tasks/SpawnerSpawnTask.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * The MIT License Copyright (c) 2015 Teal Cube Games - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT - * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package land.face.strife.tasks; - -import land.face.strife.managers.SpawnerManager; -import org.bukkit.scheduler.BukkitRunnable; - -public class SpawnerSpawnTask extends BukkitRunnable { - - private final SpawnerManager spawnerManager; - - public SpawnerSpawnTask(SpawnerManager spawnerManager) { - this.spawnerManager = spawnerManager; - } - - @Override - public void run() { - spawnerManager.spawnSpawners(); - } - -} diff --git a/src/main/java/land/face/strife/tasks/ThrownItemTask.java b/src/main/java/land/face/strife/tasks/ThrownItemTask.java index 217210cf..6d59c7a6 100644 --- a/src/main/java/land/face/strife/tasks/ThrownItemTask.java +++ b/src/main/java/land/face/strife/tasks/ThrownItemTask.java @@ -14,12 +14,15 @@ public class ThrownItemTask extends BukkitRunnable { private final Projectile projectile; private final ArmorStand stand; - private static final EulerAngle startAngle = new EulerAngle(0, 0, 0); + private final boolean spin; + private static final EulerAngle spin_angle = new EulerAngle(0, 0, 0); + private static final EulerAngle point_angle = new EulerAngle(0, 5, 272); - public ThrownItemTask(Projectile projectile, ItemStack stack, Location location) { + public ThrownItemTask(Projectile projectile, ItemStack stack, Location location, boolean spin) { this.projectile = projectile; + this.spin = spin; stand = location.getWorld().spawn(location, ArmorStand.class); - stand.setRightArmPose(startAngle); + stand.setRightArmPose(spin ? spin_angle : point_angle); stand.setVisible(false); stand.setGravity(false); stand.setMarker(true); @@ -43,9 +46,11 @@ public void run() { Location loc = projectile.getLocation().clone(); loc.add(0, -0.9, 0); loc.setDirection(projectile.getVelocity()); + if (spin) { + stand.setRightArmPose(stand.getRightArmPose().add(0.82, 0.0, 0.0)); + } loc.add(projectile.getVelocity()); stand.teleport(loc); - stand.setRightArmPose(stand.getRightArmPose().add(0.82, 0.0, 0.0)); } } diff --git a/src/main/java/land/face/strife/util/ChunkUtil.java b/src/main/java/land/face/strife/util/ChunkUtil.java new file mode 100644 index 00000000..f74da782 --- /dev/null +++ b/src/main/java/land/face/strife/util/ChunkUtil.java @@ -0,0 +1,25 @@ +package land.face.strife.util; + +import java.util.HashMap; +import java.util.Map; +import org.bukkit.Chunk; + +public class ChunkUtil { + + private static final Map chunkActiveStamp = new HashMap<>(); + + public static void stampChunk(Chunk chunk) { + chunkActiveStamp.put(chunk.getWorld().getName() + chunk.getChunkKey(), System.currentTimeMillis() + 1200); + } + + public static void unstampChunk(Chunk chunk) { + chunkActiveStamp.remove(chunk.getWorld().getName() + chunk.getChunkKey()); + } + + public static boolean isChuckLoaded(String chunkId) { + if (chunkActiveStamp.containsKey(chunkId)) { + return chunkActiveStamp.get(chunkId) < System.currentTimeMillis(); + } + return false; + } +} diff --git a/src/main/java/land/face/strife/util/DamageUtil.java b/src/main/java/land/face/strife/util/DamageUtil.java index b784cb4c..d2aae4e1 100644 --- a/src/main/java/land/face/strife/util/DamageUtil.java +++ b/src/main/java/land/face/strife/util/DamageUtil.java @@ -127,6 +127,11 @@ public static boolean preDamage(StrifeMob attacker, StrifeMob defender, DamageMo plugin.getChampionManager().getChampion((Player) defender.getEntity())); } + if (attacker != defender){ + attacker.bumpCombat(); + defender.bumpCombat(); + } + if (plugin.getCounterManager().executeCounters(attacker.getEntity(), defender.getEntity())) { return false; } @@ -136,9 +141,6 @@ public static boolean preDamage(StrifeMob attacker, StrifeMob defender, DamageMo if (mods.isCanBeEvaded()) { float evasionMultiplier = DamageUtil.getFullEvasionMult(attacker, defender, mods.getAbilityMods()); if (evasionMultiplier < DamageUtil.EVASION_THRESHOLD) { - if (defender.getEntity() instanceof Player) { - plugin.getCombatStatusManager().addPlayer((Player) defender.getEntity()); - } DamageUtil.doEvasion(attacker, defender); TargetingUtil.expandMobRange(attacker.getEntity(), defender.getEntity()); return false; @@ -149,9 +151,6 @@ public static boolean preDamage(StrifeMob attacker, StrifeMob defender, DamageMo if (mods.isCanBeBlocked()) { if (plugin.getBlockManager().isAttackBlocked(attacker, defender, attackMult, mods.getAttackType(), mods.isBlocking())) { - if (defender.getEntity() instanceof Player) { - plugin.getCombatStatusManager().addPlayer((Player) defender.getEntity()); - } TargetingUtil.expandMobRange(attacker.getEntity(), defender.getEntity()); DamageUtil.doReflectedDamage(defender, attacker, mods.getAttackType()); return false; @@ -244,7 +243,7 @@ public static float calculateFinalDamage(StrifeMob attacker, StrifeMob defender, defender.getEntity(), IndicatorStyle.RANDOM_POPOFF, 9, ChatColor.BOLD + damageString); } if (mods.isShowPopoffs() && attacker.getMaster() != null && attacker.getMaster() instanceof Player) { - plugin.getIndicatorManager().addIndicator(attacker.getMaster(), + plugin.getIndicatorManager().addIndicator(attacker.getMaster().getEntity(), defender.getEntity(), IndicatorStyle.RANDOM_POPOFF, 9, "&7" + damageString); } @@ -395,17 +394,21 @@ public static float applyDamageScale(StrifeMob caster, StrifeMob target, BonusDa case CASTER_CURRENT_ENERGY: return amount * StatUtil.getEnergy(caster); case TARGET_MISSING_ENERGY: - return amount * (StatUtil.getMaximumEnergy(target) - StatUtil.getEnergy(target)); + return amount * (StatUtil.updateMaxEnergy(target) - StatUtil.getEnergy(target)); case CASTER_MISSING_ENERGY: - return amount * (StatUtil.getMaximumEnergy(caster) - StatUtil.getEnergy(caster)); + return amount * (StatUtil.updateMaxEnergy(caster) - StatUtil.getEnergy(caster)); case TARGET_MAX_ENERGY: - return amount * StatUtil.getMaximumEnergy(target); + return amount * StatUtil.updateMaxEnergy(target); case CASTER_MAX_ENERGY: - return amount * StatUtil.getMaximumEnergy(caster); + return amount * StatUtil.updateMaxEnergy(caster); case TARGET_CURRENT_RAGE: return amount * StrifePlugin.getInstance().getRageManager().getRage(target.getEntity()); case CASTER_CURRENT_RAGE: return amount * StrifePlugin.getInstance().getRageManager().getRage(caster.getEntity()); + case TARGET_MAX_RAGE: + return amount * StatUtil.getMaximumRage(target); + case CASTER_MAX_RAGE: + return amount * StatUtil.getMaximumRage(caster); } return amount; } @@ -884,7 +887,7 @@ public static void restoreHealth(LivingEntity livingEntity, double amount) { } public static AttackType getAttackType(EntityDamageByEntityEvent event) { - if (event.getCause() == DamageCause.ENTITY_EXPLOSION) { + if (event.getCause() == DamageCause.ENTITY_EXPLOSION || event.getDamager() instanceof EvokerFangs) { return AttackType.AREA; } else if (event.getDamager() instanceof Projectile) { return AttackType.PROJECTILE; @@ -950,6 +953,8 @@ public enum DamageScale { CASTER_MAX_ENERGY, TARGET_CURRENT_RAGE, CASTER_CURRENT_RAGE, + TARGET_MAX_RAGE, + CASTER_MAX_RAGE } public enum OriginLocation { diff --git a/src/main/java/land/face/strife/util/FangUtil.java b/src/main/java/land/face/strife/util/FangUtil.java new file mode 100644 index 00000000..9c3faf60 --- /dev/null +++ b/src/main/java/land/face/strife/util/FangUtil.java @@ -0,0 +1,53 @@ +package land.face.strife.util; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; +import land.face.strife.StrifePlugin; +import land.face.strife.data.StrifeMob; +import land.face.strife.data.TargetResponse; +import land.face.strife.data.effects.Effect; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.EvokerFangs; +import org.bukkit.entity.LivingEntity; + +public class FangUtil { + + private static final Map NO_DAMAGE_FANGS = new WeakHashMap<>(); + private static final Set HIT_DELAY_IDS = new HashSet<>(); + + public static void createFang(StrifeMob owner, Location location, List effects, String id) { + location.setYaw(location.getYaw() + 90); + EvokerFangs fangs = location.getWorld().spawn(location, EvokerFangs.class); + fangs.setOwner(owner.getEntity()); + NO_DAMAGE_FANGS.put(fangs, true); + Bukkit.getScheduler().runTaskLater(StrifePlugin.getInstance(), + () -> playFangEffects(fangs, owner, effects, id), 9L); + } + + public static boolean isNoDamageFang(EvokerFangs fangs) { + return NO_DAMAGE_FANGS.containsKey(fangs); + } + + private static void playFangEffects(EvokerFangs fangs, StrifeMob owner, List effects, String effectId) { + Set targets = TargetingUtil.getEntitiesInArea(fangs.getLocation().add(0, 0.3, 0), 0.6); + targets.removeIf(t -> HIT_DELAY_IDS.contains(t.getUniqueId() + effectId)); + + if (targets.isEmpty()) { + return; + } + + TargetResponse response = new TargetResponse(targets); + StrifePlugin.getInstance().getEffectManager().executeEffectList(owner, response, effects); + + for (LivingEntity livingEntity : targets) { + String delayKey = livingEntity.getUniqueId() + effectId; + HIT_DELAY_IDS.add(delayKey); + Bukkit.getScheduler().runTaskLater(StrifePlugin.getInstance(), () -> HIT_DELAY_IDS.remove(delayKey), 10L); + } + } + +} diff --git a/src/main/java/land/face/strife/util/ItemUtil.java b/src/main/java/land/face/strife/util/ItemUtil.java index 3e3bc992..7e96f3ce 100644 --- a/src/main/java/land/face/strife/util/ItemUtil.java +++ b/src/main/java/land/face/strife/util/ItemUtil.java @@ -6,12 +6,14 @@ import io.pixeloutlaw.minecraft.spigot.hilt.ItemStackExtensionsKt; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import land.face.strife.StrifePlugin; +import land.face.strife.stats.StrifeStat; import land.face.strife.stats.StrifeTrait; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -28,6 +30,22 @@ public class ItemUtil { + // This is for integrations with Loot. It assumes default + // settings for enchantments, and is kinda shitty + public static Map getEnchantmentStats(Player player) { + Map total = new HashMap<>(); + return total; + } + + private static Map getStats(ItemStack stack) { + Map total = new HashMap<>(); + List lore = ItemStackExtensionsKt.getLore(stack); + for (String s : lore) { + + } + return null; + } + public static ItemStack withBase64(ItemStack item, String base64) { UUID hashAsId = new UUID(base64.hashCode(), base64.hashCode()); return Bukkit.getUnsafe().modifyItemStack(item, diff --git a/src/main/java/land/face/strife/util/JumpUtil.java b/src/main/java/land/face/strife/util/JumpUtil.java index 664df9ac..e68c958e 100644 --- a/src/main/java/land/face/strife/util/JumpUtil.java +++ b/src/main/java/land/face/strife/util/JumpUtil.java @@ -8,7 +8,6 @@ import land.face.strife.data.StrifeMob; import land.face.strife.data.champion.LifeSkillType; import land.face.strife.stats.StrifeStat; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -57,12 +56,10 @@ public static double determineHoverPower(Player player) { HoverData data = new HoverData((int) player.getLocation().getX(), (int) player.getLocation().getZ(), checkerLocation.getY()); HOVER_MAP.put(player, data); - Bukkit.getLogger().info("New hover entry created"); return 20 - Math.min(distanceFromHoverGround(player, data), 20); } HoverData data = HOVER_MAP.get(player); if ((int) checkerLocation.getX() == data.getBlockX() && (int) checkerLocation.getZ() == data.getBlockZ()) { - Bukkit.getLogger().info("Using previous hover entry"); return 20 - Math.min(distanceFromHoverGround(player, data), 20); } data.setBlockX(player.getLocation().getBlockX()); @@ -71,7 +68,6 @@ public static double determineHoverPower(Player player) { checkerLocation.setY(checkerLocation.getY() - 0.5); } data.setGroundBlockY(checkerLocation.getY()); - Bukkit.getLogger().info("Updated hover entry"); return 20 - Math.min(distanceFromHoverGround(player, data), 20); } diff --git a/src/main/java/land/face/strife/util/ProjectileUtil.java b/src/main/java/land/face/strife/util/ProjectileUtil.java index 63b7dd26..83a08b1c 100644 --- a/src/main/java/land/face/strife/util/ProjectileUtil.java +++ b/src/main/java/land/face/strife/util/ProjectileUtil.java @@ -1,5 +1,6 @@ package land.face.strife.util; +import io.pixeloutlaw.minecraft.spigot.hilt.ItemStackExtensionsKt; import java.util.List; import java.util.Map; import java.util.Random; @@ -7,6 +8,7 @@ import land.face.strife.data.StrifeMob; import land.face.strife.data.effects.Effect; import land.face.strife.stats.StrifeStat; +import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.AbstractArrow.PickupStatus; import org.bukkit.entity.Arrow; @@ -14,8 +16,9 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; -import org.bukkit.entity.ShulkerBullet; +import org.bukkit.entity.Snowball; import org.bukkit.entity.Trident; +import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; public class ProjectileUtil { @@ -27,6 +30,8 @@ public class ProjectileUtil { private static final Map> HIT_EFFECTS = new WeakHashMap<>(); private static final Map SHOT_ID = new WeakHashMap<>(); + private static final ItemStack wandProjectile = buildWandProjectile(); + private static final Random RANDOM = new Random(System.currentTimeMillis()); public static void setGroundTrigger(Projectile projectile) { @@ -148,9 +153,11 @@ public static void createArrow(LivingEntity shooter, double attackMult, float po public static void createMagicMissile(LivingEntity shooter, double attackMult, float power, double spread, double vertBonus, boolean gravity) { Vector velocity = getProjectileVelocity(shooter, power, spread, vertBonus); - ShulkerBullet bullet = shooter.getWorld() - .spawn(shooter.getEyeLocation().clone().add(0, -0.35, 0), - ShulkerBullet.class, e -> e.setVelocity(velocity)); + Snowball bullet = shooter.getWorld() + .spawn(shooter.getEyeLocation().clone().add(0, -0.35, 0), Snowball.class, e -> { + e.setVelocity(velocity); + e.setItem(wandProjectile); + }); bullet.setShooter(shooter); bullet.setGravity(gravity); @@ -219,4 +226,10 @@ private static double randomOffset(double magnitude) { private static double randomWandOffset(double magnitude) { return 0.12 + magnitude * 0.005; } + + private static ItemStack buildWandProjectile() { + ItemStack stack = new ItemStack(Material.NETHER_STAR); + ItemStackExtensionsKt.setCustomModelData(stack, 100); + return stack; + } } diff --git a/src/main/java/land/face/strife/util/StatUtil.java b/src/main/java/land/face/strife/util/StatUtil.java index 675d76a9..0fcb5011 100644 --- a/src/main/java/land/face/strife/util/StatUtil.java +++ b/src/main/java/land/face/strife/util/StatUtil.java @@ -40,10 +40,18 @@ public static float getHealth(StrifeMob ae) { return event.getAppliedValue(); } - public static float getMaximumEnergy(StrifeMob ae) { + public static float updateMaxEnergy(StrifeMob ae) { float amount = ae.getStat(StrifeStat.ENERGY) * (1 + ae.getStat(StrifeStat.ENERGY_MULT) / 100); PropertyUpdateEvent event = new PropertyUpdateEvent(ae, "energy", amount); Bukkit.getPluginManager().callEvent(event); + ae.setMaxEnergy(event.getAppliedValue()); + return event.getAppliedValue(); + } + + public static float getMaximumRage(StrifeMob ae) { + float amount = ae.getStat(StrifeStat.MAXIMUM_RAGE); + PropertyUpdateEvent event = new PropertyUpdateEvent(ae, "rage", amount); + Bukkit.getPluginManager().callEvent(event); return event.getAppliedValue(); } @@ -59,7 +67,9 @@ public static float getMaximumBarrier(StrifeMob ae) { if (ae.hasTrait(StrifeTrait.NO_BARRIER_ALLOWED)) { return 0; } - return ae.getStat(StrifeStat.BARRIER) * (1 + ae.getStat(StrifeStat.BARRIER_MULT) / 100); + float amount = ae.getStat(StrifeStat.BARRIER) * (1 + ae.getStat(StrifeStat.BARRIER_MULT) / 100); + ae.setMaxBarrier(amount); + return amount; } public static float getBarrierPerSecond(StrifeMob ae) { diff --git a/src/main/java/land/face/strife/util/TargetingUtil.java b/src/main/java/land/face/strife/util/TargetingUtil.java index 1d03f65a..d9de820f 100644 --- a/src/main/java/land/face/strife/util/TargetingUtil.java +++ b/src/main/java/land/face/strife/util/TargetingUtil.java @@ -5,8 +5,11 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -30,6 +33,7 @@ import org.bukkit.entity.Mob; import org.bukkit.entity.Player; import org.bukkit.entity.Tameable; +import org.bukkit.util.BoundingBox; import org.bukkit.util.RayTraceResult; import org.bukkit.util.Vector; @@ -171,7 +175,7 @@ public static Set getEntitiesInCone(Location origin, Vector direct .getNearbyEntities(origin, length, length, length); targetList.removeIf(TargetingUtil::isInvalidTarget); Set validTargets = new HashSet<>(); - for (float incRange = 0; incRange <= length + 0.01; incRange += 0.8) { + for (float incRange = 0; incRange < length; incRange += 0.6) { Location loc = origin.clone().add(direction.clone().multiply(incRange)); for (Entity entity : targetList) { if (entityWithinRadius(entity, loc, maxConeRadius * (incRange / length))) { @@ -182,16 +186,29 @@ public static Set getEntitiesInCone(Location origin, Vector direct return validTargets; } - public static Set getEntitiesInLine(Location location, float range) { + public static Set getEntitiesInLine(Location location, float range, float radius) { Collection targetList = Objects.requireNonNull(location.getWorld()) .getNearbyEntities(location, range, range, range); targetList.removeIf(TargetingUtil::isInvalidTarget); + + Map boundingBoxes = new HashMap<>(); + for (Entity entity : targetList) { + boundingBoxes.put(entity.getBoundingBox().clone().expand(radius), entity); + } + + float increment = radius * 1.9f; + Location checkLocation = location.clone(); + Vector incrementVector = location.getDirection().clone().multiply(increment); + Set validTargets = new HashSet<>(); - for (float incRange = 0; incRange <= range + 0.01; incRange += 0.8) { - Location loc = location.clone().add(location.getDirection().multiply(incRange)); - for (Entity entity : targetList) { - if (entityWithinRadius(entity, loc, 0.2f)) { - validTargets.add((LivingEntity) entity); + for (float incRange = 0; incRange <= range + 0.01; incRange += increment) { + checkLocation.add(incrementVector); + Iterator iterator = boundingBoxes.keySet().iterator(); + while (iterator.hasNext()) { + BoundingBox box = iterator.next(); + if (box.contains(checkLocation.toVector())) { + validTargets.add((LivingEntity) boundingBoxes.get(box)); + iterator.remove(); } } } @@ -276,13 +293,8 @@ private static boolean isValidRaycastTarget(LivingEntity caster, Entity entity) } private static boolean entityWithinRadius(Entity e, Location loc, float radius) { - Vector centerPoint = e.getLocation().toVector(); - centerPoint.setY(centerPoint.getY() + e.getHeight() / 2); - double width = e.getWidth() * 0.55 + 0.2; - double height = e.getHeight() * 0.55 + 0.2; - return Math.abs(loc.getX() - centerPoint.getX()) < width + radius - && Math.abs(loc.getZ() - centerPoint.getZ()) < width + radius - && Math.abs(loc.getY() - centerPoint.getY()) < height + radius; + BoundingBox box = e.getBoundingBox().clone().expand(radius); + return box.contains(loc.toVector()); } public static LivingEntity selectFirstEntityInSight(LivingEntity caster, double range, boolean friendly) {